From 32db3dc1c7c5bb9dad1bd838716e126c792b93ea Mon Sep 17 00:00:00 2001 From: Robert Femmer Date: Tue, 12 Mar 2024 14:09:53 +0000 Subject: [PATCH 001/207] fuzz: building fuzz_handshake with libprotobuf-mutator works --- fuzz/CMakeLists.txt | 1 + fuzz/fuzz_handshake/fuzz_handshake.cc | 6 ++++++ fuzz/fuzz_handshake/fuzz_handshake.proto | 5 +++++ fuzz/oss-fuzz-build.sh | 2 ++ 4 files changed, 14 insertions(+) create mode 100644 fuzz/fuzz_handshake/fuzz_handshake.cc create mode 100644 fuzz/fuzz_handshake/fuzz_handshake.proto diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt index 771dc5cd5e..9ad001ae50 100644 --- a/fuzz/CMakeLists.txt +++ b/fuzz/CMakeLists.txt @@ -17,4 +17,5 @@ include("${CMAKE_SOURCE_DIR}/cmake/Modules/Generate.cmake") add_subdirectory(fuzz_config_init) add_subdirectory(fuzz_handle_rtps_message) add_subdirectory(fuzz_type_object) +add_subdirectory(fuzz_handshake) # add_subdirectory(fuzz_idlc) diff --git a/fuzz/fuzz_handshake/fuzz_handshake.cc b/fuzz/fuzz_handshake/fuzz_handshake.cc new file mode 100644 index 0000000000..08b40a9200 --- /dev/null +++ b/fuzz/fuzz_handshake/fuzz_handshake.cc @@ -0,0 +1,6 @@ +#include "fuzz_handshake.pb.h" + +#include + +DEFINE_PROTO_FUZZER(const fuzz_handshake::FuzzMsg& message) { +} diff --git a/fuzz/fuzz_handshake/fuzz_handshake.proto b/fuzz/fuzz_handshake/fuzz_handshake.proto new file mode 100644 index 0000000000..657bbf3613 --- /dev/null +++ b/fuzz/fuzz_handshake/fuzz_handshake.proto @@ -0,0 +1,5 @@ +syntax = "proto2"; +package fuzz_handshake; +message FuzzMsg { + required string msg = 1; +} diff --git a/fuzz/oss-fuzz-build.sh b/fuzz/oss-fuzz-build.sh index 02dde69421..fabb697556 100644 --- a/fuzz/oss-fuzz-build.sh +++ b/fuzz/oss-fuzz-build.sh @@ -12,6 +12,8 @@ # SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause # +source fuzz/fuzz_handshake/prepare.sh + ( mkdir build cd build From c2f159244aad5c3a0772f3c6998f0ddb5e045adf Mon Sep 17 00:00:00 2001 From: TheFixer Date: Wed, 4 Dec 2019 14:03:10 +0100 Subject: [PATCH 002/207] expose-seqnum-via-sampleinfo Signed-off-by: TheFixer --- src/core/ddsc/include/dds/dds.h | 2 ++ src/core/ddsc/src/dds_rhc_default.c | 2 ++ src/core/ddsi/include/dds/ddsi/ddsi_serdata.h | 1 + src/core/ddsi/src/ddsi_receive.c | 9 +++++---- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/ddsc/include/dds/dds.h b/src/core/ddsc/include/dds/dds.h index 60b73aa017..2783426515 100644 --- a/src/core/ddsc/include/dds/dds.h +++ b/src/core/ddsc/include/dds/dds.h @@ -321,6 +321,8 @@ typedef struct dds_sample_info uint32_t generation_rank; /** difference in generations between the sample and most recent sample of the same instance when read/take was called */ uint32_t absolute_generation_rank; + /** sequence number of the data (relative to the publisher); always 0 for invalid samples */ + int64_t seq_no; } dds_sample_info_t; diff --git a/src/core/ddsc/src/dds_rhc_default.c b/src/core/ddsc/src/dds_rhc_default.c index c397b3c0a0..7186fbb5db 100644 --- a/src/core/ddsc/src/dds_rhc_default.c +++ b/src/core/ddsc/src/dds_rhc_default.c @@ -1942,6 +1942,7 @@ static void make_sample_info (dds_sample_info_t *si, const struct rhc_instance * si->absolute_generation_rank = get_absolute_generation_rank (inst, sample); si->valid_data = true; si->source_timestamp = sample->sample->timestamp.v; + si->seq_no = sample->sample->seq_no; } static void make_sample_info_invsample (dds_sample_info_t *si, const struct rhc_instance *inst) @@ -1958,6 +1959,7 @@ static void make_sample_info_invsample (dds_sample_info_t *si, const struct rhc_ si->absolute_generation_rank = 0; si->valid_data = false; si->source_timestamp = inst->tstamp.v; + si->seq_no = 0; /* sequence number for invalid sample is meaningless; use 0 in this case */ } static bool read_sample_update_conditions (struct dds_rhc_default *rhc, struct trigger_info_pre *pre, struct trigger_info_post *post, struct trigger_info_qcond *trig_qc, struct rhc_instance *inst, dds_querycond_mask_t conds, bool sample_wasread) diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h index 6c3eca6d1e..18a55b9db8 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h @@ -41,6 +41,7 @@ struct ddsi_serdata { /* these get set by generic code after creating the serdata */ ddsrt_wctime_t timestamp; uint32_t statusinfo; + ddsi_seqno_t seq_no; /* FIXME: can I get rid of this one? */ ddsrt_mtime_t twrite; /* write time, not source timestamp, set post-throttling */ diff --git a/src/core/ddsi/src/ddsi_receive.c b/src/core/ddsi/src/ddsi_receive.c index 9429ce0730..692b4753d4 100644 --- a/src/core/ddsi/src/ddsi_receive.c +++ b/src/core/ddsi/src/ddsi_receive.c @@ -1969,13 +1969,14 @@ static int handle_Gap (struct ddsi_receiver_state *rst, ddsrt_etime_t tnow, stru return 1; } -static struct ddsi_serdata *get_serdata (struct ddsi_sertype const * const type, const struct ddsi_rdata *fragchain, uint32_t sz, int justkey, unsigned statusinfo, ddsrt_wctime_t tstamp) +static struct ddsi_serdata *get_serdata (struct ddsi_sertype const * const type, const struct ddsi_rdata *fragchain, uint32_t sz, int justkey, unsigned statusinfo, ddsrt_wctime_t tstamp, ddsi_seqno_t seq_no) { struct ddsi_serdata *sd = ddsi_serdata_from_ser (type, justkey ? SDK_KEY : SDK_DATA, fragchain, sz); if (sd) { sd->statusinfo = statusinfo; sd->timestamp = tstamp; + sd->seq_no = seq_no; } return sd; } @@ -2020,7 +2021,7 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, si->data_smhdr_flags, sampleinfo->size); return NULL; } - sample = get_serdata (type, fragchain, sampleinfo->size, 0, statusinfo, tstamp); + sample = get_serdata (type, fragchain, sampleinfo->size, 0, statusinfo, tstamp, sampleinfo->seq); } else if (sampleinfo->size) { @@ -2029,12 +2030,12 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, as one would expect to receive */ if (data_smhdr_flags & DDSI_DATA_FLAG_KEYFLAG) { - sample = get_serdata (type, fragchain, sampleinfo->size, 1, statusinfo, tstamp); + sample = get_serdata (type, fragchain, sampleinfo->size, 1, statusinfo, tstamp, sampleinfo->seq); } else { assert (data_smhdr_flags & DDSI_DATA_FLAG_DATAFLAG); - sample = get_serdata (type, fragchain, sampleinfo->size, 0, statusinfo, tstamp); + sample = get_serdata (type, fragchain, sampleinfo->size, 0, statusinfo, tstamp, sampleinfo->seq); } } else if (data_smhdr_flags & DDSI_DATA_FLAG_INLINE_QOS) From 8507ad3063f665c6cc062935b162419d1e875589 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 18 Nov 2022 13:51:59 +0100 Subject: [PATCH 003/207] Use seqno_t as type for sequence numbers (which is defined as uint64_t) Signed-off-by: TheFixer --- src/core/ddsc/include/dds/dds.h | 2 +- src/core/ddsi/include/dds/ddsi/ddsi_serdata.h | 2 +- src/core/ddsi/src/ddsi_receive.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ddsc/include/dds/dds.h b/src/core/ddsc/include/dds/dds.h index 2783426515..4f07dbf0d5 100644 --- a/src/core/ddsc/include/dds/dds.h +++ b/src/core/ddsc/include/dds/dds.h @@ -322,7 +322,7 @@ typedef struct dds_sample_info /** difference in generations between the sample and most recent sample of the same instance when read/take was called */ uint32_t absolute_generation_rank; /** sequence number of the data (relative to the publisher); always 0 for invalid samples */ - int64_t seq_no; + uint64_t seq_no; } dds_sample_info_t; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h index 18a55b9db8..4649014971 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h @@ -41,7 +41,7 @@ struct ddsi_serdata { /* these get set by generic code after creating the serdata */ ddsrt_wctime_t timestamp; uint32_t statusinfo; - ddsi_seqno_t seq_no; + ddsi_seqno_t sequence_number; /* FIXME: can I get rid of this one? */ ddsrt_mtime_t twrite; /* write time, not source timestamp, set post-throttling */ diff --git a/src/core/ddsi/src/ddsi_receive.c b/src/core/ddsi/src/ddsi_receive.c index 692b4753d4..b27fa0cd27 100644 --- a/src/core/ddsi/src/ddsi_receive.c +++ b/src/core/ddsi/src/ddsi_receive.c @@ -1976,7 +1976,7 @@ static struct ddsi_serdata *get_serdata (struct ddsi_sertype const * const type, { sd->statusinfo = statusinfo; sd->timestamp = tstamp; - sd->seq_no = seq_no; + sd->sequence_number = seq_no; } return sd; } From 571f0804117a5ca843830f535a22645961286d15 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Wed, 21 Dec 2022 15:08:28 +0100 Subject: [PATCH 004/207] Removed seq_no from dds_sampleinfo_t and add sequence_number to ddsi_serdata Signed-off-by: TheFixer --- src/core/ddsc/include/dds/dds.h | 2 -- src/core/ddsc/src/dds_rhc_default.c | 2 -- src/core/ddsi/src/ddsi_discovery.c | 1 + src/core/ddsi/src/ddsi_receive.c | 1 + src/core/ddsi/src/ddsi_serdata.c | 2 ++ 5 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/ddsc/include/dds/dds.h b/src/core/ddsc/include/dds/dds.h index 4f07dbf0d5..60b73aa017 100644 --- a/src/core/ddsc/include/dds/dds.h +++ b/src/core/ddsc/include/dds/dds.h @@ -321,8 +321,6 @@ typedef struct dds_sample_info uint32_t generation_rank; /** difference in generations between the sample and most recent sample of the same instance when read/take was called */ uint32_t absolute_generation_rank; - /** sequence number of the data (relative to the publisher); always 0 for invalid samples */ - uint64_t seq_no; } dds_sample_info_t; diff --git a/src/core/ddsc/src/dds_rhc_default.c b/src/core/ddsc/src/dds_rhc_default.c index 7186fbb5db..c397b3c0a0 100644 --- a/src/core/ddsc/src/dds_rhc_default.c +++ b/src/core/ddsc/src/dds_rhc_default.c @@ -1942,7 +1942,6 @@ static void make_sample_info (dds_sample_info_t *si, const struct rhc_instance * si->absolute_generation_rank = get_absolute_generation_rank (inst, sample); si->valid_data = true; si->source_timestamp = sample->sample->timestamp.v; - si->seq_no = sample->sample->seq_no; } static void make_sample_info_invsample (dds_sample_info_t *si, const struct rhc_instance *inst) @@ -1959,7 +1958,6 @@ static void make_sample_info_invsample (dds_sample_info_t *si, const struct rhc_ si->absolute_generation_rank = 0; si->valid_data = false; si->source_timestamp = inst->tstamp.v; - si->seq_no = 0; /* sequence number for invalid sample is meaningless; use 0 in this case */ } static bool read_sample_update_conditions (struct dds_rhc_default *rhc, struct trigger_info_pre *pre, struct trigger_info_post *post, struct trigger_info_qcond *trig_qc, struct rhc_instance *inst, dds_querycond_mask_t conds, bool sample_wasread) diff --git a/src/core/ddsi/src/ddsi_discovery.c b/src/core/ddsi/src/ddsi_discovery.c index c402728eaf..0fe13a36ae 100644 --- a/src/core/ddsi/src/ddsi_discovery.c +++ b/src/core/ddsi/src/ddsi_discovery.c @@ -425,6 +425,7 @@ int ddsi_builtins_dqueue_handler (const struct ddsi_rsample_info *sampleinfo, co d->timestamp = (sampleinfo->timestamp.v != DDSRT_WCTIME_INVALID.v) ? sampleinfo->timestamp : ddsrt_time_wallclock (); d->statusinfo = statusinfo; + d->sequence_number = sampleinfo->seq; // set protocol version & vendor id for plist types // FIXME: find a better way then fixing these up afterward if (d->ops == &ddsi_serdata_ops_plist) diff --git a/src/core/ddsi/src/ddsi_receive.c b/src/core/ddsi/src/ddsi_receive.c index b27fa0cd27..a3e43424ba 100644 --- a/src/core/ddsi/src/ddsi_receive.c +++ b/src/core/ddsi/src/ddsi_receive.c @@ -2058,6 +2058,7 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, { sample->statusinfo = statusinfo; sample->timestamp = tstamp; + sample->sequence_number = sampleinfo->seq; } } else diff --git a/src/core/ddsi/src/ddsi_serdata.c b/src/core/ddsi/src/ddsi_serdata.c index 6b015e380c..36f8a16b2b 100644 --- a/src/core/ddsi/src/ddsi_serdata.c +++ b/src/core/ddsi/src/ddsi_serdata.c @@ -27,6 +27,7 @@ void ddsi_serdata_init (struct ddsi_serdata *d, const struct ddsi_sertype *tp, e d->hash = 0; d->statusinfo = 0; d->timestamp.v = INT64_MIN; + d->sequence_number = 0; d->twrite.v = INT64_MIN; d->loan = NULL; ddsrt_atomic_st32 (&d->refc, 1); @@ -42,6 +43,7 @@ struct ddsi_serdata *ddsi_serdata_copy_as_type (const struct ddsi_sertype *type, { converted->statusinfo = serdata->statusinfo; converted->timestamp = serdata->timestamp; + converted->sequence_number = serdata->sequence_number; } ddsi_serdata_to_ser_unref (tmpref, &iov); return converted; From 467b500656191d9b23dcbdf9ea2a3f8fc6375ba1 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Mon, 23 Jan 2023 09:13:02 +0100 Subject: [PATCH 005/207] Add .get_sequencenumber function to ddsi_serdata_ops interface, so that the sequence number can be retrieved from serdata Signed-off-by: TheFixer --- src/core/ddsc/src/dds_serdata_builtintopic.c | 2 ++ src/core/ddsc/src/dds_serdata_default.c | 10 ++++++++++ src/core/ddsc/tests/cdr.c | 3 ++- src/core/ddsi/include/dds/ddsi/ddsi_serdata.h | 9 ++++++++- src/core/ddsi/src/ddsi_serdata_cdr.c | 1 + src/core/ddsi/src/ddsi_serdata_plist.c | 3 ++- src/core/ddsi/src/ddsi_serdata_pserop.c | 3 ++- 7 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/core/ddsc/src/dds_serdata_builtintopic.c b/src/core/ddsc/src/dds_serdata_builtintopic.c index 303183f49d..c3d7038efc 100644 --- a/src/core/ddsc/src/dds_serdata_builtintopic.c +++ b/src/core/ddsc/src/dds_serdata_builtintopic.c @@ -444,6 +444,7 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_builtintopic = { .untyped_to_sample = serdata_builtin_untyped_to_sample, .print = serdata_builtin_type_print, .get_keyhash = NULL, + .get_sequencenumber = NULL, .from_loaned_sample = NULL, .from_psmx = NULL }; @@ -501,6 +502,7 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_builtintopic_topic = { .untyped_to_sample = serdata_builtin_untyped_to_sample, .print = serdata_builtin_type_print, .get_keyhash = NULL, + .get_sequencenumber = NULL, .from_loaned_sample = NULL, .from_psmx = NULL }; diff --git a/src/core/ddsc/src/dds_serdata_default.c b/src/core/ddsc/src/dds_serdata_default.c index a812721158..983ef562ec 100644 --- a/src/core/ddsc/src/dds_serdata_default.c +++ b/src/core/ddsc/src/dds_serdata_default.c @@ -159,6 +159,12 @@ static uint32_t serdata_default_get_size(const struct ddsi_serdata *dcmn) return d->pos + (uint32_t)sizeof (struct dds_cdr_header); } +static uint64_t serdata_default_get_sequencenumber(const struct ddsi_serdata *dcmn) +{ + const struct dds_serdata_default *d = (const struct dds_serdata_default *) dcmn; + return d->c.sequence_number; +} + static bool serdata_default_eqkey(const struct ddsi_serdata *acmn, const struct ddsi_serdata *bcmn) { const struct dds_serdata_default *a = (const struct dds_serdata_default *)acmn; @@ -980,6 +986,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_cdr = { .untyped_to_sample = serdata_default_untyped_to_sample_cdr, .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, + .get_sequencenumber = serdata_default_get_sequencenumber, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; @@ -1000,6 +1007,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_xcdr2 = { .untyped_to_sample = serdata_default_untyped_to_sample_cdr, .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, + .get_sequencenumber = serdata_default_get_sequencenumber, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; @@ -1020,6 +1028,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_cdr_nokey = { .untyped_to_sample = serdata_default_untyped_to_sample_cdr_nokey, .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, + .get_sequencenumber = serdata_default_get_sequencenumber, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; @@ -1040,6 +1049,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_xcdr2_nokey = { .untyped_to_sample = serdata_default_untyped_to_sample_cdr_nokey, .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, + .get_sequencenumber = serdata_default_get_sequencenumber, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; diff --git a/src/core/ddsc/tests/cdr.c b/src/core/ddsc/tests/cdr.c index ae0b2f625c..c73b7124ad 100644 --- a/src/core/ddsc/tests/cdr.c +++ b/src/core/ddsc/tests/cdr.c @@ -461,7 +461,8 @@ static const struct ddsi_serdata_ops sd_ops = { .to_untyped = sd_to_untyped, .untyped_to_sample = sd_untyped_to_sample, .print = sd_print, - .get_keyhash = sd_get_keyhash + .get_keyhash = sd_get_keyhash, + .get_sequencenumber = 0 }; /*---------------------------------------------------------------- diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h index 4649014971..7e43505bfd 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h @@ -145,6 +145,9 @@ typedef size_t (*ddsi_serdata_print_t) (const struct ddsi_sertype *type, const s - buf needs to be at least 16 bytes large */ typedef void (*ddsi_serdata_get_keyhash_t) (const struct ddsi_serdata *d, struct ddsi_keyhash *buf, bool force_md5); +/* Sequence number of the sample as advertised by the publisher */ +typedef uint64_t (*ddsi_serdata_get_sequencenumber_t) (const struct ddsi_serdata *d); + // Used for taking a loaned sample and constructing a serdata around this // takes over ownership of loan on success (leaves it unchanged on failure) typedef struct ddsi_serdata* (*ddsi_serdata_from_loan_t) (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const char *sample, struct dds_loaned_sample *loaned_sample, bool will_require_cdr); @@ -152,7 +155,6 @@ typedef struct ddsi_serdata* (*ddsi_serdata_from_loan_t) (const struct ddsi_sert // Used for constructing a serdata from data received on a PSMX typedef struct ddsi_serdata* (*ddsi_serdata_from_psmx_t) (const struct ddsi_sertype *type, struct dds_loaned_sample *loaned_sample); - struct ddsi_serdata_ops { ddsi_serdata_eqkey_t eqkey; ddsi_serdata_size_t get_size; @@ -169,6 +171,7 @@ struct ddsi_serdata_ops { ddsi_serdata_free_t free; ddsi_serdata_print_t print; ddsi_serdata_get_keyhash_t get_keyhash; + ddsi_serdata_get_sequencenumber_t get_sequencenumber; ddsi_serdata_from_loan_t from_loaned_sample; ddsi_serdata_from_psmx_t from_psmx; }; @@ -251,6 +254,10 @@ DDS_INLINE_EXPORT inline uint32_t ddsi_serdata_size (const struct ddsi_serdata * } /** @component typesupport_if */ +DDS_INLINE_EXPORT inline uint64_t ddsi_serdata_sequencenumber(const struct ddsi_serdata *d) { + return d->ops->get_sequencenumber (d); +} + DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_ser (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size) { return type->serdata_ops->from_ser (type, kind, fragchain, size); } diff --git a/src/core/ddsi/src/ddsi_serdata_cdr.c b/src/core/ddsi/src/ddsi_serdata_cdr.c index e809130057..ecdb0892e6 100644 --- a/src/core/ddsi/src/ddsi_serdata_cdr.c +++ b/src/core/ddsi/src/ddsi_serdata_cdr.c @@ -353,5 +353,6 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_cdr = { .to_untyped = serdata_cdr_to_untyped, .untyped_to_sample = serdata_cdr_untyped_to_sample_cdr, .print = serdata_cdr_print_cdr, + .get_sequencenumber = 0, .get_keyhash = 0 }; diff --git a/src/core/ddsi/src/ddsi_serdata_plist.c b/src/core/ddsi/src/ddsi_serdata_plist.c index 911618b5f5..24fa77b45f 100644 --- a/src/core/ddsi/src/ddsi_serdata_plist.c +++ b/src/core/ddsi/src/ddsi_serdata_plist.c @@ -324,5 +324,6 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_plist = { .to_untyped = serdata_plist_to_untyped, .untyped_to_sample = serdata_plist_untyped_to_sample, .print = serdata_plist_print_plist, - .get_keyhash = serdata_plist_get_keyhash + .get_keyhash = serdata_plist_get_keyhash, + .get_sequencenumber = 0 }; diff --git a/src/core/ddsi/src/ddsi_serdata_pserop.c b/src/core/ddsi/src/ddsi_serdata_pserop.c index 1241e66feb..1cc075cb25 100644 --- a/src/core/ddsi/src/ddsi_serdata_pserop.c +++ b/src/core/ddsi/src/ddsi_serdata_pserop.c @@ -307,5 +307,6 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_pserop = { .to_untyped = serdata_pserop_to_untyped, .untyped_to_sample = serdata_pserop_untyped_to_sample, .print = serdata_pserop_print_pserop, - .get_keyhash = serdata_pserop_get_keyhash + .get_keyhash = serdata_pserop_get_keyhash, + .get_sequencenumber = 0 }; From 80854d1b8e126438a32819b1aed647bfe5e67f01 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Mon, 1 May 2023 09:23:32 +0200 Subject: [PATCH 006/207] First attempt to add writer guid to serdata interface Signed-off-by: TheFixer --- src/core/ddsc/src/dds_serdata_builtintopic.c | 2 + src/core/ddsc/src/dds_serdata_default.c | 10 +++++ src/core/ddsc/tests/cdr.c | 3 +- src/core/ddsi/include/dds/ddsi/ddsi_serdata.h | 10 +++++ src/core/ddsi/src/ddsi_receive.c | 40 ++++++------------- src/core/ddsi/src/ddsi_serdata_cdr.c | 3 +- src/core/ddsi/src/ddsi_serdata_plist.c | 3 +- src/core/ddsi/src/ddsi_serdata_pserop.c | 3 +- 8 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/core/ddsc/src/dds_serdata_builtintopic.c b/src/core/ddsc/src/dds_serdata_builtintopic.c index c3d7038efc..a4b7fd3c78 100644 --- a/src/core/ddsc/src/dds_serdata_builtintopic.c +++ b/src/core/ddsc/src/dds_serdata_builtintopic.c @@ -445,6 +445,7 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_builtintopic = { .print = serdata_builtin_type_print, .get_keyhash = NULL, .get_sequencenumber = NULL, + .get_writer_guid = NULL, .from_loaned_sample = NULL, .from_psmx = NULL }; @@ -503,6 +504,7 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_builtintopic_topic = { .print = serdata_builtin_type_print, .get_keyhash = NULL, .get_sequencenumber = NULL, + .get_writer_guid = NULL, .from_loaned_sample = NULL, .from_psmx = NULL }; diff --git a/src/core/ddsc/src/dds_serdata_default.c b/src/core/ddsc/src/dds_serdata_default.c index 983ef562ec..4016b1201a 100644 --- a/src/core/ddsc/src/dds_serdata_default.c +++ b/src/core/ddsc/src/dds_serdata_default.c @@ -165,6 +165,12 @@ static uint64_t serdata_default_get_sequencenumber(const struct ddsi_serdata *dc return d->c.sequence_number; } +static ddsi_guid_t *serdata_default_get_writer_guid(const struct ddsi_serdata *dcmn) +{ + struct dds_serdata_default *d = (struct dds_serdata_default *) dcmn; + return &d->c.writer_guid; +} + static bool serdata_default_eqkey(const struct ddsi_serdata *acmn, const struct ddsi_serdata *bcmn) { const struct dds_serdata_default *a = (const struct dds_serdata_default *)acmn; @@ -987,6 +993,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_cdr = { .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, .get_sequencenumber = serdata_default_get_sequencenumber, + .get_writer_guid = serdata_default_get_writer_guid, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; @@ -1008,6 +1015,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_xcdr2 = { .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, .get_sequencenumber = serdata_default_get_sequencenumber, + .get_writer_guid = serdata_default_get_writer_guid, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; @@ -1029,6 +1037,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_cdr_nokey = { .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, .get_sequencenumber = serdata_default_get_sequencenumber, + .get_writer_guid = serdata_default_get_writer_guid, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; @@ -1050,6 +1059,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_xcdr2_nokey = { .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, .get_sequencenumber = serdata_default_get_sequencenumber, + .get_writer_guid = serdata_default_get_writer_guid, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; diff --git a/src/core/ddsc/tests/cdr.c b/src/core/ddsc/tests/cdr.c index c73b7124ad..28c5429b6a 100644 --- a/src/core/ddsc/tests/cdr.c +++ b/src/core/ddsc/tests/cdr.c @@ -462,7 +462,8 @@ static const struct ddsi_serdata_ops sd_ops = { .untyped_to_sample = sd_untyped_to_sample, .print = sd_print, .get_keyhash = sd_get_keyhash, - .get_sequencenumber = 0 + .get_sequencenumber = 0, + .get_writer_guid = 0 }; /*---------------------------------------------------------------- diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h index 7e43505bfd..d34c347b41 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h @@ -42,6 +42,7 @@ struct ddsi_serdata { ddsrt_wctime_t timestamp; uint32_t statusinfo; ddsi_seqno_t sequence_number; + ddsi_guid_t writer_guid; /* FIXME: can I get rid of this one? */ ddsrt_mtime_t twrite; /* write time, not source timestamp, set post-throttling */ @@ -148,6 +149,9 @@ typedef void (*ddsi_serdata_get_keyhash_t) (const struct ddsi_serdata *d, struct /* Sequence number of the sample as advertised by the publisher */ typedef uint64_t (*ddsi_serdata_get_sequencenumber_t) (const struct ddsi_serdata *d); +/* Get the reference to the guid of the writer that published the serdata */ +typedef ddsi_guid_t * (*ddsi_serdata_get_writer_guid_t) (const struct ddsi_serdata *d); + // Used for taking a loaned sample and constructing a serdata around this // takes over ownership of loan on success (leaves it unchanged on failure) typedef struct ddsi_serdata* (*ddsi_serdata_from_loan_t) (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const char *sample, struct dds_loaned_sample *loaned_sample, bool will_require_cdr); @@ -172,6 +176,7 @@ struct ddsi_serdata_ops { ddsi_serdata_print_t print; ddsi_serdata_get_keyhash_t get_keyhash; ddsi_serdata_get_sequencenumber_t get_sequencenumber; + ddsi_serdata_get_writer_guid_t get_writer_guid; ddsi_serdata_from_loan_t from_loaned_sample; ddsi_serdata_from_psmx_t from_psmx; }; @@ -258,6 +263,11 @@ DDS_INLINE_EXPORT inline uint64_t ddsi_serdata_sequencenumber(const struct ddsi_ return d->ops->get_sequencenumber (d); } +/** @component typesupport_if */ +DDS_INLINE_EXPORT inline ddsi_guid_t *ddsi_serdata_writer_guid(const struct ddsi_serdata *d) { + return d->ops->get_writer_guid (d); +} + DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_ser (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size) { return type->serdata_ops->from_ser (type, kind, fragchain, size); } diff --git a/src/core/ddsi/src/ddsi_receive.c b/src/core/ddsi/src/ddsi_receive.c index a3e43424ba..0653bf1f29 100644 --- a/src/core/ddsi/src/ddsi_receive.c +++ b/src/core/ddsi/src/ddsi_receive.c @@ -1969,15 +1969,9 @@ static int handle_Gap (struct ddsi_receiver_state *rst, ddsrt_etime_t tnow, stru return 1; } -static struct ddsi_serdata *get_serdata (struct ddsi_sertype const * const type, const struct ddsi_rdata *fragchain, uint32_t sz, int justkey, unsigned statusinfo, ddsrt_wctime_t tstamp, ddsi_seqno_t seq_no) +static struct ddsi_serdata *get_serdata (struct ddsi_sertype const * const type, const struct ddsi_rdata *fragchain, uint32_t sz, int justkey) { struct ddsi_serdata *sd = ddsi_serdata_from_ser (type, justkey ? SDK_KEY : SDK_DATA, fragchain, sz); - if (sd) - { - sd->statusinfo = statusinfo; - sd->timestamp = tstamp; - sd->sequence_number = seq_no; - } return sd; } @@ -2003,17 +1997,16 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, const ddsi_plist_t * __restrict qos = si->qos; const char *failmsg = NULL; struct ddsi_serdata *sample = NULL; + const struct ddsi_proxy_writer *pwr = sampleinfo->pwr; + ddsi_seqno_t seq = sampleinfo->seq; + ddsi_guid_t guid; + if (pwr) guid = pwr->e.guid; else memset (&guid, 0, sizeof (guid)); if (si->statusinfo == 0) { /* normal write */ if (!(data_smhdr_flags & DDSI_DATA_FLAG_DATAFLAG) || sampleinfo->size == 0) { - const struct ddsi_proxy_writer *pwr = sampleinfo->pwr; - ddsi_guid_t guid; - /* pwr can't currently be null, but that might change some day, and this being - an error path, it doesn't hurt to survive that */ - if (pwr) guid = pwr->e.guid; else memset (&guid, 0, sizeof (guid)); DDS_CTRACE (&gv->logconfig, "data(application, vendor %u.%u): "PGUIDFMT" #%"PRIu64": write without proper payload (data_smhdr_flags 0x%x size %"PRIu32")\n", sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], @@ -2021,7 +2014,7 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, si->data_smhdr_flags, sampleinfo->size); return NULL; } - sample = get_serdata (type, fragchain, sampleinfo->size, 0, statusinfo, tstamp, sampleinfo->seq); + sample = get_serdata (type, fragchain, sampleinfo->size, 0); } else if (sampleinfo->size) { @@ -2030,12 +2023,12 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, as one would expect to receive */ if (data_smhdr_flags & DDSI_DATA_FLAG_KEYFLAG) { - sample = get_serdata (type, fragchain, sampleinfo->size, 1, statusinfo, tstamp, sampleinfo->seq); + sample = get_serdata (type, fragchain, sampleinfo->size, 1); } else { assert (data_smhdr_flags & DDSI_DATA_FLAG_DATAFLAG); - sample = get_serdata (type, fragchain, sampleinfo->size, 0, statusinfo, tstamp, sampleinfo->seq); + sample = get_serdata (type, fragchain, sampleinfo->size, 0); } } else if (data_smhdr_flags & DDSI_DATA_FLAG_INLINE_QOS) @@ -2054,12 +2047,6 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, } else if ((sample = ddsi_serdata_from_keyhash (type, &qos->keyhash)) == NULL) failmsg = "keyhash is MD5 and can't be converted to key value"; - else - { - sample->statusinfo = statusinfo; - sample->timestamp = tstamp; - sample->sequence_number = sampleinfo->seq; - } } else { @@ -2068,9 +2055,6 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, if (sample == NULL) { /* No message => error out */ - const struct ddsi_proxy_writer *pwr = sampleinfo->pwr; - ddsi_guid_t guid; - if (pwr) guid = pwr->e.guid; else memset (&guid, 0, sizeof (guid)); DDS_CWARNING (&gv->logconfig, "data(application, vendor %u.%u): "PGUIDFMT" #%"PRIu64": deserialization %s/%s failed (%s)\n", sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], @@ -2080,6 +2064,11 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, } else { + sample->statusinfo = statusinfo; + sample->timestamp = tstamp; + sample->sequence_number = seq; + memcpy(&sample->writer_guid, &guid, sizeof(sample->writer_guid)); + if ((*tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, sample)) == NULL) { ddsi_serdata_unref (sample); @@ -2087,14 +2076,11 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, } else if (gv->logconfig.c.mask & DDS_LC_TRACE) { - const struct ddsi_proxy_writer *pwr = sampleinfo->pwr; - ddsi_guid_t guid; char tmp[1024]; size_t res = 0; tmp[0] = 0; if (gv->logconfig.c.mask & DDS_LC_CONTENT) res = ddsi_serdata_print (sample, tmp, sizeof (tmp)); - if (pwr) guid = pwr->e.guid; else memset (&guid, 0, sizeof (guid)); GVTRACE ("data(application, vendor %u.%u): "PGUIDFMT" #%"PRIu64": ST%"PRIx32" %s/%s:%s%s", sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], PGUID (guid), sampleinfo->seq, statusinfo, diff --git a/src/core/ddsi/src/ddsi_serdata_cdr.c b/src/core/ddsi/src/ddsi_serdata_cdr.c index ecdb0892e6..5b3121beb2 100644 --- a/src/core/ddsi/src/ddsi_serdata_cdr.c +++ b/src/core/ddsi/src/ddsi_serdata_cdr.c @@ -353,6 +353,7 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_cdr = { .to_untyped = serdata_cdr_to_untyped, .untyped_to_sample = serdata_cdr_untyped_to_sample_cdr, .print = serdata_cdr_print_cdr, + .get_keyhash = 0, .get_sequencenumber = 0, - .get_keyhash = 0 + .get_writer_guid = 0 }; diff --git a/src/core/ddsi/src/ddsi_serdata_plist.c b/src/core/ddsi/src/ddsi_serdata_plist.c index 24fa77b45f..b7acceff41 100644 --- a/src/core/ddsi/src/ddsi_serdata_plist.c +++ b/src/core/ddsi/src/ddsi_serdata_plist.c @@ -325,5 +325,6 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_plist = { .untyped_to_sample = serdata_plist_untyped_to_sample, .print = serdata_plist_print_plist, .get_keyhash = serdata_plist_get_keyhash, - .get_sequencenumber = 0 + .get_sequencenumber = 0, + .get_writer_guid = 0 }; diff --git a/src/core/ddsi/src/ddsi_serdata_pserop.c b/src/core/ddsi/src/ddsi_serdata_pserop.c index 1cc075cb25..a62564b4e7 100644 --- a/src/core/ddsi/src/ddsi_serdata_pserop.c +++ b/src/core/ddsi/src/ddsi_serdata_pserop.c @@ -308,5 +308,6 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_pserop = { .untyped_to_sample = serdata_pserop_untyped_to_sample, .print = serdata_pserop_print_pserop, .get_keyhash = serdata_pserop_get_keyhash, - .get_sequencenumber = 0 + .get_sequencenumber = 0, + .get_writer_guid = 0 }; From a14732e137866532ce0fc57ff3bd7294ab99905a Mon Sep 17 00:00:00 2001 From: TheFixer Date: Thu, 1 Jun 2023 11:08:56 +0200 Subject: [PATCH 007/207] Implement function dds_reader_store_historical_data() to deliver serdata to reader rhc Signed-off-by: TheFixer --- src/core/ddsc/include/dds/dds.h | 3 ++ src/core/ddsc/src/dds_reader.c | 79 +++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/src/core/ddsc/include/dds/dds.h b/src/core/ddsc/include/dds/dds.h index 60b73aa017..20d13b1777 100644 --- a/src/core/ddsc/include/dds/dds.h +++ b/src/core/ddsc/include/dds/dds.h @@ -1888,6 +1888,9 @@ dds_wait_for_acks(dds_entity_t publisher_or_writer, dds_duration_t timeout); * DOC_TODO The reader is a DDS Entity */ +DDS_EXPORT dds_return_t +dds_reader_store_historical_serdata (dds_entity_t reader, dds_guid_t guid, bool autodispose, struct ddsi_serdata *serdata); + /** * @brief Creates a new instance of a DDS reader. * @ingroup reader diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index ed38aba178..3c4804beb4 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -39,6 +39,17 @@ #include "dds__builtin.h" #include "dds__statistics.h" #include "dds__psmx.h" +/* LH: likely some of the following includes can go */ +#if 0 +#include "dds__data_allocator.h" +#include "dds/ddsi/ddsi_sertype.h" +#include "dds/ddsi/ddsi_entity_index.h" +#include "dds/ddsi/ddsi_security_omg.h" +#include "dds/ddsi/ddsi_statistics.h" +#include "dds/ddsi/ddsi_endpoint_match.h" +#include "dds/ddsi/ddsi_serdata.h" +#include "dds/ddsi/ddsi_tkmap.h" +#endif DECL_ENTITY_LOCK_UNLOCK (dds_reader) @@ -483,6 +494,74 @@ const struct dds_entity_deriver dds_entity_deriver_reader = { .invoke_cbs_for_pending_events = dds_reader_invoke_cbs_for_pending_events }; + +dds_return_t dds_reader_store_historical_serdata (dds_entity_t reader, dds_guid_t guid, bool autodispose, struct ddsi_serdata *serdata) +{ + dds_return_t ret; + dds_entity * e; + if ((ret = dds_entity_pin (reader, &e)) < 0) + return ret; + else if (dds_entity_kind (e) != DDS_KIND_READER) + { + dds_entity_unpin (e); + return DDS_RETCODE_ILLEGAL_OPERATION; + } + + dds_reader *dds_rd = (dds_reader *) e; + struct ddsi_reader *rd = dds_rd->m_rd; + struct ddsi_domaingv *gv = rd->e.gv; + + /* The serdata->writer_info contains the ddsi guid in BE format. + * To compare this with the guid we'll transfer the guid + * to the right format and compare both. + * LH: It feels a bit weird having to do this transformation, + * but it seems to work. However, I do have a difficulty in explaining + * why this is necessary. */ + struct ddsi_guid ddsiguid, tmp; + memcpy(&tmp, &guid, 16); + ddsiguid = ddsi_ntoh_guid(tmp); + + ddsi_thread_state_awake (ddsi_lookup_thread_state (), gv); + ddsrt_mutex_lock (&rd->e.lock); + + /* retrieve the topic key map used to get the instance id of the serdata */ + struct ddsi_tkmap_instance * tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata); + if (tk == NULL) { + ret = DDS_RETCODE_BAD_PARAMETER; + goto fail_get_writer_info; + } + + /* historical data is always unregistered */ + serdata->statusinfo |= DDSI_STATUSINFO_UNREGISTER; + /* set the writer guid of the serdata */ + serdata->writer_guid = ddsiguid; + /* timestamp and seqnum have already been set in the serdata by the caller */ + + /* We'll use the lowest possible strength when inserting historical data + * to ensure that live writers which are stronger always take precedence. + * We'll still need to figure out how to ensure that a live writer takes + * precedence in case the live writer also has the lowest possible strength. + */ + struct ddsi_writer_info wi; + wi.guid = ddsiguid; + wi.ownership_strength = INT32_MIN; /* use the lowest possible strength to ensure that live writers with a */ + wi.auto_dispose = autodispose; + wi.iid = tk->m_iid; + if (!dds_rhc_store (dds_rd->m_rhc, &wi, serdata, tk)) + { + ret = DDS_RETCODE_ERROR; + goto fail_rhc_store; + } + +fail_rhc_store: + ddsi_tkmap_instance_unref (gv->m_tkmap, tk); +fail_get_writer_info: + ddsrt_mutex_unlock (&rd->e.lock); + ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); + dds_entity_unpin (e); + return ret; +} + static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscriber, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener, struct dds_rhc *rhc) { dds_subscriber *sub = NULL; From 1bfa3b81ac9023d9967d9aaf0dc4c108e8d9ebc6 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 7 Jul 2023 09:12:08 +0200 Subject: [PATCH 008/207] Use lifespan set to DDSRT_MTIME_NEVER when adding historical serdata to the rhc of a durable reader Signed-off-by: TheFixer --- src/core/ddsc/src/dds_reader.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index 3c4804beb4..390c941a80 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -510,7 +510,6 @@ dds_return_t dds_reader_store_historical_serdata (dds_entity_t reader, dds_guid_ dds_reader *dds_rd = (dds_reader *) e; struct ddsi_reader *rd = dds_rd->m_rd; struct ddsi_domaingv *gv = rd->e.gv; - /* The serdata->writer_info contains the ddsi guid in BE format. * To compare this with the guid we'll transfer the guid * to the right format and compare both. @@ -520,19 +519,24 @@ dds_return_t dds_reader_store_historical_serdata (dds_entity_t reader, dds_guid_ struct ddsi_guid ddsiguid, tmp; memcpy(&tmp, &guid, 16); ddsiguid = ddsi_ntoh_guid(tmp); - ddsi_thread_state_awake (ddsi_lookup_thread_state (), gv); ddsrt_mutex_lock (&rd->e.lock); - /* retrieve the topic key map used to get the instance id of the serdata */ - struct ddsi_tkmap_instance * tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata); + struct ddsi_tkmap_instance *tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata); if (tk == NULL) { ret = DDS_RETCODE_BAD_PARAMETER; - goto fail_get_writer_info; + goto fail_tkmap_lookup; + } + /* retrieve the builtin key map to get the iid for the writer */ + struct ddsi_tkmap_instance *tk_builtin = ddsi_builtintopic_get_tkmap_entry(gv->builtin_topic_interface, &ddsiguid); + if (tk_builtin == NULL) { + ret = DDS_RETCODE_BAD_PARAMETER; + goto fail_tk_builtin; } - /* historical data is always unregistered */ - serdata->statusinfo |= DDSI_STATUSINFO_UNREGISTER; + if (!ddsi_builtintopic_is_visible(gv->builtin_topic_interface, &ddsiguid, ddsi_get_entity_vendorid(&rd->e))) { + serdata->statusinfo |= DDSI_STATUSINFO_UNREGISTER; + } /* set the writer guid of the serdata */ serdata->writer_guid = ddsiguid; /* timestamp and seqnum have already been set in the serdata by the caller */ @@ -544,9 +548,12 @@ dds_return_t dds_reader_store_historical_serdata (dds_entity_t reader, dds_guid_ */ struct ddsi_writer_info wi; wi.guid = ddsiguid; - wi.ownership_strength = INT32_MIN; /* use the lowest possible strength to ensure that live writers with a */ + wi.ownership_strength = INT32_MIN; /* use the lowest possible strength to ensure that live writers always take precedence */ wi.auto_dispose = autodispose; - wi.iid = tk->m_iid; + wi.iid = tk_builtin->m_iid; +#ifdef DDS_HAS_LIFESPAN + wi.lifespan_exp = DDSRT_MTIME_NEVER; +#endif if (!dds_rhc_store (dds_rd->m_rhc, &wi, serdata, tk)) { ret = DDS_RETCODE_ERROR; @@ -554,8 +561,10 @@ dds_return_t dds_reader_store_historical_serdata (dds_entity_t reader, dds_guid_ } fail_rhc_store: + ddsi_tkmap_instance_unref (gv->m_tkmap, tk_builtin); +fail_tk_builtin: ddsi_tkmap_instance_unref (gv->m_tkmap, tk); -fail_get_writer_info: +fail_tkmap_lookup: ddsrt_mutex_unlock (&rd->e.lock); ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); dds_entity_unpin (e); From 1b0dbac14d6b45cd2ab118cc73d4c579d3968675 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Thu, 14 Sep 2023 16:27:21 +0200 Subject: [PATCH 009/207] create cmake infrastructure for durability Signed-off-by: TheFixer --- src/CMakeLists.txt | 13 ++++++ src/core/CMakeLists.txt | 4 ++ src/core/ddsc/src/dds_domain.c | 9 ++++ src/ddsrt/CMakeLists.txt | 2 +- src/ddsrt/include/dds/features.h.in | 3 ++ src/durability/CMakeLists.txt | 36 +++++++++++++++ .../include/dds/durability/dds_durability.h | 37 ++++++++++++++++ src/durability/src/dds_durability.c | 44 +++++++++++++++++++ 8 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 src/durability/CMakeLists.txt create mode 100644 src/durability/include/dds/durability/dds_durability.h create mode 100644 src/durability/src/dds_durability.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ae00de44c6..cdbe359712 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,6 +22,12 @@ function(PREPEND var prefix) set(${var} "${listVar}" PARENT_SCOPE) endfunction() +# Durable support is currently under development (beta). +# Therefore it is disabled by default. To enable durable support +# in CycloneDDS use the build option '-DENABLE_DURABILITY' +# when building CycloneDDS + +option(ENABLE_DURABILITY "Enable Durable support" OFF) option(ENABLE_SECURITY "Enable OMG DDS Security support" ON) option(ENABLE_LIFESPAN "Enable Lifespan QoS support" ON) option(ENABLE_DEADLINE_MISSED "Enable Deadline Missed QoS support" ON) @@ -104,6 +110,10 @@ if(ENABLE_ICEORYX) endif() endif() +if(ENABLE_DURABILITY) + message(STATUS "Building with Durable support") +endif() + if(BUILD_TESTING) add_subdirectory(ucunit) endif() @@ -116,4 +126,7 @@ add_subdirectory(security) if(ENABLE_ICEORYX) add_subdirectory(psmx_iox) endif() +if(ENABLE_DURABILITY) + add_subdirectory(durability) +endif() add_subdirectory(core) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 0db30e1fe8..6fb6ea19e9 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -58,6 +58,10 @@ if(ENABLE_SECURITY) $>) endif() +if(ENABLE_DURABILITY) + target_link_libraries(ddsc PRIVATE "$") +endif() + include(cdr/CMakeLists.txt) include(ddsi/CMakeLists.txt) include(ddsc/CMakeLists.txt) diff --git a/src/core/ddsc/src/dds_domain.c b/src/core/ddsc/src/dds_domain.c index 68a332553b..6a5c356998 100644 --- a/src/core/ddsc/src/dds_domain.c +++ b/src/core/ddsc/src/dds_domain.c @@ -32,6 +32,10 @@ #include "dds__serdata_default.h" #include "dds__psmx.h" +#ifdef DDS_HAS_DURABILITY +#include "dds/durability/dds_durability.h" +#endif + static dds_return_t dds_domain_free (dds_entity *vdomain); const struct dds_entity_deriver dds_entity_deriver_domain = { @@ -302,6 +306,11 @@ dds_entity_t dds_create_domain (const dds_domainid_t domain, const char *config) const struct config_source config_src = { .kind = CFGKIND_XML, .u = { .xml = config } }; ret = dds_domain_create_internal_xml_or_raw (&dom, domain, false, &config_src); dds_entity_unpin_and_drop_ref (&dds_global.m_entity); + +#ifdef DDS_HAS_DURABILITY + dds_durability_init2(&dom->gv); +#endif + return ret; } diff --git a/src/ddsrt/CMakeLists.txt b/src/ddsrt/CMakeLists.txt index b3d38e67e0..811062c277 100644 --- a/src/ddsrt/CMakeLists.txt +++ b/src/ddsrt/CMakeLists.txt @@ -311,7 +311,7 @@ set(DDSRT_WITH_LWIP ${WITH_LWIP}) set(DDSRT_WITH_FREERTOS ${WITH_FREERTOS}) foreach(feature SSL SECURITY LIFESPAN DEADLINE_MISSED NETWORK_PARTITIONS - SSM TYPELIB TYPE_DISCOVERY TOPIC_DISCOVERY) + SSM TYPELIB TYPE_DISCOVERY TOPIC_DISCOVERY DURABILITY) set(DDS_HAS_${feature} ${ENABLE_${feature}}) endforeach() diff --git a/src/ddsrt/include/dds/features.h.in b/src/ddsrt/include/dds/features.h.in index 28ac452333..5795a9b0d8 100644 --- a/src/ddsrt/include/dds/features.h.in +++ b/src/ddsrt/include/dds/features.h.in @@ -41,6 +41,9 @@ /* Not for general use, specificly for testing psmx Cyclone DDS plugin */ #cmakedefine DDS_ALLOW_NESTED_DOMAIN 1 +/* Whether or not durable support is included */ +#cmakedefine DDS_HAS_DURABILITY 1 + /* Not intended for general use, whether building a static library, specifically testing psmx and security */ #cmakedefine DDS_IS_STATIC_LIBRARY 1 diff --git a/src/durability/CMakeLists.txt b/src/durability/CMakeLists.txt new file mode 100644 index 0000000000..30cba56886 --- /dev/null +++ b/src/durability/CMakeLists.txt @@ -0,0 +1,36 @@ +# Copyright(c) 2006 to 2021 ZettaScale Technology and others +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Public License v. 2.0 which is available at +# http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +# v. 1.0 which is available at +# http://www.eclipse.org/org/documents/edl-v10.php. +# +# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause +# +set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}") +set(binary_dir "${CMAKE_CURRENT_BINARY_DIR}") + +add_library(durability INTERFACE) + +target_include_directories( + durability INTERFACE + "$" + "$" + "$") + +set(headers + "${source_dir}/include/dds/durability/dds_durability.h") + +set(sources + "${source_dir}/src/dds_durability.c") + +target_sources(durability INTERFACE ${headers} ${sources}) + +install( + DIRECTORY + "${source_dir}/include/" + "${binary_dir}/include/" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + COMPONENT dev + FILES_MATCHING PATTERN "*.h") \ No newline at end of file diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h new file mode 100644 index 0000000000..65cf52600e --- /dev/null +++ b/src/durability/include/dds/durability/dds_durability.h @@ -0,0 +1,37 @@ +// Copyright(c) 2006 to 2020 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#ifndef DDS_DURABILITY_H +#define DDS_DURABILITY_H + +#include "dds/ddsi/ddsi_domaingv.h" +#include "dds/ddsrt/retcode.h" +#include "ddsc/dds.h" +#include "dds__types.h" +#include "dds/ddsc/dds_rhc.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/* Integration functions for durability plugins */ +typedef int (*plugin_init)(const char *argument, void **context, struct ddsi_domaingv *gv); +typedef int (*plugin_finalize)(void *context); + +dds_return_t dds_durability_init2 (struct ddsi_domaingv* gv); +dds_return_t dds_durability_fini2 (void); +void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc); +void dds_durability_wait_for_ds (uint32_t quorum, dds_time_t timeout); + +#if defined (__cplusplus) +} +#endif + +#endif /* DDS_DURABILITY_H */ diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c new file mode 100644 index 0000000000..471c12ea50 --- /dev/null +++ b/src/durability/src/dds_durability.c @@ -0,0 +1,44 @@ +/* + * Copyright(c) 2006 to 2019 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +#include "dds/durability/dds_durability.h" +#include "ddsc/dds.h" + + +dds_return_t dds_durability_init2 (struct ddsi_domaingv* gv) +{ + printf("!!!!!!!!!!!!!!!!!!! src/durability/core/src/dds_durability_init()\n"); + return DDS_RETCODE_OK; +} + +dds_return_t dds_durability_fini2 (void) +{ + printf("!!!!!!!!!!!!!!!!!!! src/durability/core/src/dds_durability_fini()\n"); + return DDS_RETCODE_OK; +} + +void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc) +{ + /* create the administration to store transient data */ + /* create a durability reader that sucks and stores it in the store */ + + DDSRT_UNUSED_ARG(reader); + return; +} + +void dds_durability_wait_for_ds (uint32_t quorum, dds_time_t timeout) +{ + (void)quorum; + (void)timeout; + return; +} + + From 183915202c68f1256254c3782d94794726f6a440 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 10 Oct 2023 11:03:10 +0200 Subject: [PATCH 010/207] Add durability as a trace category and initialize durability when the first participant is created Signed-off-by: TheFixer --- docs/manual/config/config_file_reference.rst | 3 +- docs/manual/options.md | 3 +- etc/cyclonedds.rnc | 4 +- etc/cyclonedds.xsd | 4 +- src/core/ddsc/src/dds_domain.c | 8 - src/core/ddsc/src/dds_participant.c | 15 + src/core/ddsc/src/dds_write.c | 12 + src/core/ddsi/src/ddsi__cfgelems.h | 4 +- src/core/ddsi/src/ddsi_config.c | 4 +- src/ddsrt/include/dds/ddsrt/log.h | 4 +- src/durability/CMakeLists.txt | 6 +- .../dds/durability/client_durability.h | 223 ++++++ .../include/dds/durability/dds_durability.h | 7 +- src/durability/src/client_durability.c | 606 ++++++++++++++++ src/durability/src/dds_durability.c | 677 +++++++++++++++++- 15 files changed, 1546 insertions(+), 34 deletions(-) create mode 100644 src/durability/include/dds/durability/client_durability.h create mode 100644 src/durability/src/client_durability.c diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index a9c4280258..639f6c9896 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -2546,7 +2546,7 @@ The default value is: ``false`` ------------------------------------ One of: -* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, content, shm, trace +* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, durability, content, shm, trace * Or empty This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are: @@ -2578,6 +2578,7 @@ This element enables individual logging categories. These are enabled in additio * topic: tracing of topic definitions * plist: tracing of discovery parameter list interpretation + * durability: tracing of durable data In addition, there is the keyword trace that enables all but radmin, topic, plist and whc. diff --git a/docs/manual/options.md b/docs/manual/options.md index 3227bcdbe2..1e326d0186 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -1766,7 +1766,7 @@ The default value is: `false` #### //CycloneDDS/Domain/Tracing/Category One of: -* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, content, shm, trace +* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, durability, content, shm, trace * Or empty This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are: @@ -1798,6 +1798,7 @@ This element enables individual logging categories. These are enabled in additio * topic: tracing of topic definitions * plist: tracing of discovery parameter list interpretation + * durability: tracing of durable data In addition, there is the keyword trace that enables all but radmin, topic, plist and whc. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is trace. diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index 02ded851fa..d313715aa7 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -1240,12 +1240,12 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
  • whc: tracing of writer history cache changes
  • tcp: tracing of TCP-specific activity
  • topic: tracing of topic definitions
  • -
  • plist: tracing of discovery parameter list interpretation
  • +
  • plist: tracing of discovery parameter list interpretation
  • durability: tracing of durable data
  • In addition, there is the keyword trace that enables all but radmin, topic, plist and whc

    .

    The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is trace.

    The default value is: <empty>

    """ ] ] element Category { - xsd:token { pattern = "((fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|shm|trace)(,(fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|shm|trace))*)|" } + xsd:token { pattern = "((fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|durability|content|shm|trace)(,(fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|durability|content|shm|trace))*)|" } }? & [ a:documentation [ xml:lang="en" """

    This option specifies where the logging is printed to. Note that stdout and stderr are treated as special values, representing "standard out" and "standard error" respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings.

    diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index 4ab6d375b9..62d391da87 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -1864,14 +1864,14 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> <li><i>whc</i>: tracing of writer history cache changes</li> <li><i>tcp</i>: tracing of TCP-specific activity</li> <li><i>topic</i>: tracing of topic definitions</li> -<li><i>plist</i>: tracing of discovery parameter list interpretation</li></ul> +<li><i>plist</i>: tracing of discovery parameter list interpretation</li><li><i>durability</i>: tracing of durable data</li></ul> <p>In addition, there is the keyword <i>trace</i> that enables all but <i>radmin</i>, <i>topic</i>, <i>plist</i> and <i>whc</i></p>. <p>The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is <i>trace</i>.</p> <p>The default value is: <code>&lt;empty&gt;</code></p> - + diff --git a/src/core/ddsc/src/dds_domain.c b/src/core/ddsc/src/dds_domain.c index 6a5c356998..d2612033d7 100644 --- a/src/core/ddsc/src/dds_domain.c +++ b/src/core/ddsc/src/dds_domain.c @@ -32,10 +32,6 @@ #include "dds__serdata_default.h" #include "dds__psmx.h" -#ifdef DDS_HAS_DURABILITY -#include "dds/durability/dds_durability.h" -#endif - static dds_return_t dds_domain_free (dds_entity *vdomain); const struct dds_entity_deriver dds_entity_deriver_domain = { @@ -307,10 +303,6 @@ dds_entity_t dds_create_domain (const dds_domainid_t domain, const char *config) ret = dds_domain_create_internal_xml_or_raw (&dom, domain, false, &config_src); dds_entity_unpin_and_drop_ref (&dds_global.m_entity); -#ifdef DDS_HAS_DURABILITY - dds_durability_init2(&dom->gv); -#endif - return ret; } diff --git a/src/core/ddsc/src/dds_participant.c b/src/core/ddsc/src/dds_participant.c index bb661c36fb..dd3e8a6169 100644 --- a/src/core/ddsc/src/dds_participant.c +++ b/src/core/ddsc/src/dds_participant.c @@ -27,6 +27,10 @@ #include "dds__builtin.h" #include "dds__qos.h" +#ifdef DDS_HAS_DURABILITY +#include "dds/durability/dds_durability.h" +#endif + DECL_ENTITY_LOCK_UNLOCK (dds_participant) #define DDS_PARTICIPANT_STATUS_MASK (0u) @@ -57,6 +61,11 @@ static dds_return_t dds_participant_delete (dds_entity *e) if ((ret = ddsi_delete_participant (&e->m_domain->gv, &e->m_guid)) < 0) DDS_CERROR (&e->m_domain->gv.logconfig, "dds_participant_delete: internal error %"PRId32"\n", ret); ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); + +#ifdef DDS_HAS_DURABILITY + dds_durability_fini(); +#endif + return DDS_RETCODE_OK; } @@ -157,9 +166,15 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ ddsrt_mutex_unlock (&dom->m_entity.m_mutex); dds_entity_init_complete (&pp->m_entity); + /* drop temporary extra ref to domain, dds_init */ dds_entity_unpin_and_drop_ref (&dom->m_entity); dds_entity_unpin_and_drop_ref (&dds_global.m_entity); + +#ifdef DDS_HAS_DURABILITY + dds_durability_init (domain, &dom->gv); +#endif + return ret; err_entity_init: diff --git a/src/core/ddsc/src/dds_write.c b/src/core/ddsc/src/dds_write.c index 7f51867bb9..9e70d9cc89 100644 --- a/src/core/ddsc/src/dds_write.c +++ b/src/core/ddsc/src/dds_write.c @@ -31,6 +31,10 @@ #include "dds__loaned_sample.h" #include "dds__psmx.h" +#ifdef DDS_HAS_DURABILITY +#include "dds/durability/dds_durability.h" +#endif + struct ddsi_serdata_plain { struct ddsi_serdata p; }; struct ddsi_serdata_any { struct ddsi_serdata a; }; @@ -772,6 +776,14 @@ dds_return_t dds_write_impl (dds_writer *wr, const void *data, dds_time_t timest if (!evaluate_topic_filter (wr, data, sdkind)) return DDS_RETCODE_OK; +#ifdef DDS_HAS_DURABILITY + if ((ddsi_wr->xqos->durability.kind == DDS_DURABILITY_TRANSIENT) || (ddsi_wr->xqos->durability.kind == DDS_DURABILITY_PERSISTENT)) { + if ((ret = dds_durability_check_quorum_reached(wr)) != DDS_RETCODE_OK) { + return DDS_RETCODE_PRECONDITION_NOT_MET; + } + } +#endif + // I. psmx loan => assert (psmx && is_memcpy_safe) // a. psmx only // - no need for a serdata, so skip everything and deliver loan via PSMX diff --git a/src/core/ddsi/src/ddsi__cfgelems.h b/src/core/ddsi/src/ddsi__cfgelems.h index a0ccf089fa..5f757799b9 100644 --- a/src/core/ddsi/src/ddsi__cfgelems.h +++ b/src/core/ddsi/src/ddsi__cfgelems.h @@ -138,7 +138,6 @@ static struct cfgelem entity_autonaming_attributes[] = { END_MARKER }; - static struct cfgelem general_cfgelems[] = { STRING("MulticastRecvNetworkInterfaceAddresses", NULL, 1, "preferred", MEMBER(networkRecvAddressStrings), @@ -1962,6 +1961,7 @@ static struct cfgelem tracing_cfgelems[] = { "
  • tcp: tracing of TCP-specific activity
  • \n" "
  • topic: tracing of topic definitions
  • \n" "
  • plist: tracing of discovery parameter list interpretation
  • " + "
  • durability: tracing of durable data
  • " "\n" "

    In addition, there is the keyword trace that enables all " "but radmin, topic, plist and whc

    .\n" @@ -1973,7 +1973,7 @@ static struct cfgelem tracing_cfgelems[] = { VALUES( "fatal","error","warning","info","config","discovery","data","radmin", "timing","traffic","topic","tcp","plist","whc","throttle","rhc", - "content","shm","trace" + "durability","content","shm","trace" )), ENUM("Verbosity", NULL, 1, "none", NOMEMBER, diff --git a/src/core/ddsi/src/ddsi_config.c b/src/core/ddsi/src/ddsi_config.c index 52c9d624b9..611d780c64 100644 --- a/src/core/ddsi/src/ddsi_config.c +++ b/src/core/ddsi/src/ddsi_config.c @@ -1007,10 +1007,10 @@ GENERIC_ENUM_CTYPE (shm_loglevel, enum ddsi_shm_loglevel) /* "trace" is special: it enables (nearly) everything */ static const char *tracemask_names[] = { - "fatal", "error", "warning", "info", "config", "discovery", "data", "radmin", "timing", "traffic", "topic", "tcp", "plist", "whc", "throttle", "rhc", "content", "trace", NULL + "fatal", "error", "warning", "info", "config", "discovery", "data", "radmin", "timing", "traffic", "topic", "tcp", "plist", "whc", "throttle", "rhc", "durability", "content", "trace", NULL }; static const uint32_t tracemask_codes[] = { - DDS_LC_FATAL, DDS_LC_ERROR, DDS_LC_WARNING, DDS_LC_INFO, DDS_LC_CONFIG, DDS_LC_DISCOVERY, DDS_LC_DATA, DDS_LC_RADMIN, DDS_LC_TIMING, DDS_LC_TRAFFIC, DDS_LC_TOPIC, DDS_LC_TCP, DDS_LC_PLIST, DDS_LC_WHC, DDS_LC_THROTTLE, DDS_LC_RHC, DDS_LC_CONTENT, DDS_LC_ALL + DDS_LC_FATAL, DDS_LC_ERROR, DDS_LC_WARNING, DDS_LC_INFO, DDS_LC_CONFIG, DDS_LC_DISCOVERY, DDS_LC_DATA, DDS_LC_RADMIN, DDS_LC_TIMING, DDS_LC_TRAFFIC, DDS_LC_TOPIC, DDS_LC_TCP, DDS_LC_PLIST, DDS_LC_WHC, DDS_LC_THROTTLE, DDS_LC_RHC, DDS_LC_DUR, DDS_LC_CONTENT, DDS_LC_ALL }; static enum update_result uf_tracemask (struct ddsi_cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) diff --git a/src/ddsrt/include/dds/ddsrt/log.h b/src/ddsrt/include/dds/ddsrt/log.h index 53730aa12d..5167b0ef58 100644 --- a/src/ddsrt/include/dds/ddsrt/log.h +++ b/src/ddsrt/include/dds/ddsrt/log.h @@ -76,12 +76,14 @@ extern "C" { #define DDS_LC_RHC (65536u) /** Include content in traces. */ #define DDS_LC_CONTENT (131072u) +/** Debug/trace messages related to Durability */ +#define DDS_LC_DUR (262144u) /** All common trace categories. */ #define DDS_LC_ALL \ (DDS_LC_FATAL | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_INFO | \ DDS_LC_CONFIG | DDS_LC_DISCOVERY | DDS_LC_DATA | DDS_LC_TRACE | \ DDS_LC_TIMING | DDS_LC_TRAFFIC | DDS_LC_TCP | DDS_LC_THROTTLE | \ - DDS_LC_CONTENT) + DDS_LC_CONTENT | DDS_LC_DUR) /** @}*/ #define DDS_LOG_MASK \ diff --git a/src/durability/CMakeLists.txt b/src/durability/CMakeLists.txt index 30cba56886..aec416df73 100644 --- a/src/durability/CMakeLists.txt +++ b/src/durability/CMakeLists.txt @@ -20,10 +20,12 @@ target_include_directories( "$") set(headers - "${source_dir}/include/dds/durability/dds_durability.h") + "${source_dir}/include/dds/durability/dds_durability.h" + "${source_dir}/include/dds/durability/client_durability.h") set(sources - "${source_dir}/src/dds_durability.c") + "${source_dir}/src/dds_durability.c" + "${source_dir}/src/client_durability.c") target_sources(durability INTERFACE ${headers} ${sources}) diff --git a/src/durability/include/dds/durability/client_durability.h b/src/durability/include/dds/durability/client_durability.h new file mode 100644 index 0000000000..5f2649c6b3 --- /dev/null +++ b/src/durability/include/dds/durability/client_durability.h @@ -0,0 +1,223 @@ +/**************************************************************** + + IMPORTANT: + + The file contains the definitions for the client durability related topics. + This file is partially copied from the output generated by durabledupport.idl + because we cannot generate code from an idl file due to cyclic dependencies + in idlc_generate(). + +*****************************************************************/ +#ifndef CLIENT_DURABILITY_H +#define CLIENT_DURABILITY_H + +#include "dds/ddsc/dds_public_impl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint8_t DurableSupport_id_t[16]; + +#define DurableSupport_id_t__alloc() \ +((DurableSupport_id_t*) dds_alloc (sizeof (DurableSupport_id_t))); + +typedef uint64_t DurableSupport_session_id_t; + +#define DurableSupport_session_id_t__alloc() \ +((DurableSupport_session_id_t*) dds_alloc (sizeof (DurableSupport_session_id_t))); + +typedef uint16_t DurableSupport_session_kind_t; + +#define DurableSupport_session_kind_t__alloc() \ +((DurableSupport_session_kind_t*) dds_alloc (sizeof (DurableSupport_session_kind_t))); + +typedef uint16_t DurableSupport_beadtype_t; + +#define DurableSupport_beadtype_t__alloc() \ +((DurableSupport_beadtype_t*) dds_alloc (sizeof (DurableSupport_beadtype_t))); + +typedef struct DurableSupport_status +{ + DurableSupport_id_t id; + char * hostname; + char * name; +} DurableSupport_status; + +extern const dds_topic_descriptor_t DurableSupport_status_desc; + +#define DurableSupport_status__alloc() \ +((DurableSupport_status*) dds_alloc (sizeof (DurableSupport_status))); + +#define DurableSupport_status_free(d,o) \ +dds_sample_free ((d), &DurableSupport_status_desc, (o)) + +typedef struct DurableSupport_request_id_t +{ + DurableSupport_id_t client; + uint64_t seq; +} DurableSupport_request_id_t; + +extern const dds_topic_descriptor_t DurableSupport_request_id_t_desc; + +#define DurableSupport_request_id_t__alloc() \ +((DurableSupport_request_id_t*) dds_alloc (sizeof (DurableSupport_request_id_t))); + +#define DurableSupport_request_id_t_free(d,o) \ +dds_sample_free ((d), &DurableSupport_request_id_t_desc, (o)) + +#ifndef DDS_SEQUENCE_STRING_DEFINED +#define DDS_SEQUENCE_STRING_DEFINED +typedef struct dds_sequence_string +{ + uint32_t _maximum; + uint32_t _length; + char **_buffer; + bool _release; +} dds_sequence_string; + +#define dds_sequence_string__alloc() \ +((dds_sequence_string*) dds_alloc (sizeof (dds_sequence_string))); + +#define dds_sequence_string_allocbuf(l) \ +((char **) dds_alloc ((l) * sizeof (char*))) +#endif /* DDS_SEQUENCE_STRING_DEFINED */ + +typedef struct DurableSupport_request +{ + struct DurableSupport_request_id_t requestid; + char * partition; + char * tpname; + dds_sequence_string alignment_partition; +} DurableSupport_request; + +extern const dds_topic_descriptor_t DurableSupport_request_desc; + +#define DurableSupport_request__alloc() \ +((DurableSupport_request*) dds_alloc (sizeof (DurableSupport_request))); + +#define DurableSupport_request_free(d,o) \ +dds_sample_free ((d), &DurableSupport_request_desc, (o)) + +#define DurableSupport_BEADTYPE_SESSION 1 +#define DurableSupport_BEADTYPE_SET 2 +#define DurableSupport_BEADTYPE_WRITER 3 +#define DurableSupport_BEADTYPE_DATA 4 +#define DurableSupport_SESSION_KIND_START 1 +#define DurableSupport_SESSION_KIND_END 2 +#define DurableSupport_SESSION_KIND_ABORT 3 + +typedef struct DurableSupport_session_t +{ + DurableSupport_session_kind_t kind; + DurableSupport_session_id_t session_id; +} DurableSupport_session_t; + +#ifndef DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED +#define DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED +typedef struct dds_sequence_DurableSupport_id_t +{ + uint32_t _maximum; + uint32_t _length; + DurableSupport_id_t *_buffer; + bool _release; +} dds_sequence_DurableSupport_id_t; + +#define dds_sequence_DurableSupport_id_t__alloc() \ +((dds_sequence_DurableSupport_id_t*) dds_alloc (sizeof (dds_sequence_DurableSupport_id_t))); + +#define dds_sequence_DurableSupport_id_t_allocbuf(l) \ +((DurableSupport_id_t *) dds_alloc ((l) * sizeof (DurableSupport_id_t))) +#endif /* DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED */ + +typedef struct DurableSupport_set_t +{ + char * partition; + char * tpname; + uint32_t flags; + dds_sequence_DurableSupport_id_t addressees; +} DurableSupport_set_t; + +typedef struct DurableSupport_range +{ + uint64_t lb; + uint64_t ub; +} DurableSupport_range; + +#ifndef DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED +#define DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED +typedef struct dds_sequence_DurableSupport_range +{ + uint32_t _maximum; + uint32_t _length; + struct DurableSupport_range *_buffer; + bool _release; +} dds_sequence_DurableSupport_range; + +#define dds_sequence_DurableSupport_range__alloc() \ +((dds_sequence_DurableSupport_range*) dds_alloc (sizeof (dds_sequence_DurableSupport_range))); + +#define dds_sequence_DurableSupport_range_allocbuf(l) \ +((struct DurableSupport_range *) dds_alloc ((l) * sizeof (struct DurableSupport_range))) +#endif /* DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED */ + +typedef struct DurableSupport_writer_t +{ + DurableSupport_id_t id; + uint32_t flags; + dds_sequence_DurableSupport_range ranges; +} DurableSupport_writer_t; + +#ifndef DDS_SEQUENCE_OCTET_DEFINED +#define DDS_SEQUENCE_OCTET_DEFINED +typedef struct dds_sequence_octet +{ + uint32_t _maximum; + uint32_t _length; + uint8_t *_buffer; + bool _release; +} dds_sequence_octet; + +#define dds_sequence_octet__alloc() \ +((dds_sequence_octet*) dds_alloc (sizeof (dds_sequence_octet))); + +#define dds_sequence_octet_allocbuf(l) \ +((uint8_t *) dds_alloc ((l) * sizeof (uint8_t))) +#endif /* DDS_SEQUENCE_OCTET_DEFINED */ + +typedef struct DurableSupport_data_t +{ + dds_sequence_octet blob; +} DurableSupport_data_t; + +typedef struct DurableSupport_content +{ + DurableSupport_beadtype_t _d; + union + { + struct DurableSupport_session_t session; + struct DurableSupport_set_t set; + struct DurableSupport_writer_t writer; + struct DurableSupport_data_t data; + } _u; +} DurableSupport_content; + +typedef struct DurableSupport_bead +{ + DurableSupport_id_t id; + struct DurableSupport_content body; +} DurableSupport_bead; + +extern const dds_topic_descriptor_t DurableSupport_bead_desc; + +#define DurableSupport_bead__alloc() \ +((DurableSupport_bead*) dds_alloc (sizeof (DurableSupport_bead))); + +#define DurableSupport_bead_free(d,o) \ +dds_sample_free ((d), &DurableSupport_bead_desc, (o)) + +#ifdef __cplusplus +} +#endif + +#endif /* CLIENT_DURABILITY_H */ diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h index 65cf52600e..c7b8a1f5cf 100644 --- a/src/durability/include/dds/durability/dds_durability.h +++ b/src/durability/include/dds/durability/dds_durability.h @@ -25,10 +25,11 @@ extern "C" { typedef int (*plugin_init)(const char *argument, void **context, struct ddsi_domaingv *gv); typedef int (*plugin_finalize)(void *context); -dds_return_t dds_durability_init2 (struct ddsi_domaingv* gv); -dds_return_t dds_durability_fini2 (void); +dds_return_t dds_durability_init (const dds_domainid_t domain, struct ddsi_domaingv *gv); +dds_return_t dds_durability_fini (void); void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc); -void dds_durability_wait_for_ds (uint32_t quorum, dds_time_t timeout); +dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer); +bool dds_durability_is_terminating (void); #if defined (__cplusplus) } diff --git a/src/durability/src/client_durability.c b/src/durability/src/client_durability.c new file mode 100644 index 0000000000..ea5429a4d8 --- /dev/null +++ b/src/durability/src/client_durability.c @@ -0,0 +1,606 @@ +/**************************************************************** + + IMPORTANT: + + The file contains the definitions for the client durability related topics. + This file is partially copied from the output generated by durabledupport.idl + because we cannot generate code from an idl file due to cyclic dependencies + in idlc_generate(). + +*****************************************************************/ +#include "../include/dds/durability/client_durability.h" + +static const uint32_t DurableSupport_status_ops [] = +{ + /* status */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_status, id), 16u, + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_status, hostname), + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_status, name), + DDS_OP_RTS, + + /* key: id */ + DDS_OP_KOF | 1, 1u /* order: 0 */ +}; + +static const dds_key_descriptor_t DurableSupport_status_keys[1] = +{ + { "id", 9, 0 } +}; + +/* Type Information: + [MINIMAL 1609a972dd9ffc746226aaae0ce7] (#deps: 1) + - [MINIMAL 43f53a2be35b432cc735e9431a89] + [COMPLETE 3ae8d3b6272f54c8257bf018eda8] (#deps: 1) + - [COMPLETE aca4d5a256d39713924333e85c6d] +*/ +#define TYPE_INFO_CDR_DurableSupport_status (const unsigned char []){ \ + 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x16, 0x09, 0xa9, 0x72, 0xdd, 0x9f, 0xfc, 0x74, 0x62, 0x26, 0xaa, \ + 0xae, 0x0c, 0xe7, 0x00, 0x58, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x3a, 0xe8, 0xd3, \ + 0xb6, 0x27, 0x2f, 0x54, 0xc8, 0x25, 0x7b, 0xf0, 0x18, 0xed, 0xa8, 0x00, 0x8f, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ + 0x40, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_status 148u +#define TYPE_MAP_CDR_DurableSupport_status (const unsigned char []){ \ + 0x9a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0x16, 0x09, 0xa9, 0x72, 0xdd, 0x9f, 0xfc, \ + 0x74, 0x62, 0x26, 0xaa, 0xae, 0x0c, 0xe7, 0x00, 0x54, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x08, 0x97, 0xac, 0xf4, \ + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0xb0, 0x68, 0x93, 0x1c, \ + 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ + 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ + 0xf4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf2, 0x3a, 0xe8, 0xd3, 0xb6, 0x27, 0x2f, 0x54, \ + 0xc8, 0x25, 0x7b, 0xf0, 0x18, 0xed, 0xa8, 0x00, 0x8b, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x74, 0x61, 0x74, \ + 0x75, 0x73, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x09, 0x00, 0x00, 0x00, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, \ + 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ + 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0xf2, 0x3a, 0xe8, 0xd3, 0xb6, 0x27, 0x2f, 0x54, 0xc8, 0x25, 0x7b, 0xf0, 0x18, 0xed, 0xa8, 0xf1, \ + 0x16, 0x09, 0xa9, 0x72, 0xdd, 0x9f, 0xfc, 0x74, 0x62, 0x26, 0xaa, 0xae, 0x0c, 0xe7, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_status 476u +const dds_topic_descriptor_t DurableSupport_status_desc = +{ + .m_size = sizeof (DurableSupport_status), + .m_align = dds_alignof (DurableSupport_status), + .m_flagset = DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 1u, + .m_typename = "DurableSupport::status", + .m_keys = DurableSupport_status_keys, + .m_nops = 5, + .m_ops = DurableSupport_status_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_status, .sz = TYPE_INFO_CDR_SZ_DurableSupport_status }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_status, .sz = TYPE_MAP_CDR_SZ_DurableSupport_status } +}; + +static const uint32_t DurableSupport_request_id_t_ops [] = +{ + /* request_id_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), + DDS_OP_RTS +}; + +/* Type Information: + [MINIMAL 28dabddcc42d4b6a3d640fd522a4] (#deps: 1) + - [MINIMAL 43f53a2be35b432cc735e9431a89] + [COMPLETE 852fffc913b7ee54aadae7a1859a] (#deps: 1) + - [COMPLETE aca4d5a256d39713924333e85c6d] +*/ +#define TYPE_INFO_CDR_DurableSupport_request_id_t (const unsigned char []){ \ + 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, \ + 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, \ + 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ + 0x40, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_request_id_t 148u +#define TYPE_MAP_CDR_DurableSupport_request_id_t (const unsigned char []){ \ + 0x8a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ + 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, \ + 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, \ + 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ + 0xe4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ + 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ + 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0xf1, \ + 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_request_id_t 444u +const dds_topic_descriptor_t DurableSupport_request_id_t_desc = +{ + .m_size = sizeof (DurableSupport_request_id_t), + .m_align = dds_alignof (DurableSupport_request_id_t), + .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 0u, + .m_typename = "DurableSupport::request_id_t", + .m_keys = NULL, + .m_nops = 4, + .m_ops = DurableSupport_request_id_t_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request_id_t, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request_id_t }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request_id_t, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request_id_t } +}; + +static const uint32_t DurableSupport_request_ops [] = +{ + /* request */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_EXT, offsetof (DurableSupport_request, requestid), (3u << 16u) + 10u /* request_id_t */, + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, partition), + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STR, offsetof (DurableSupport_request, alignment_partition), + DDS_OP_RTS, + + /* request_id_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), + DDS_OP_RTS, + + /* key: requestid.client */ + DDS_OP_KOF | 2, 1u /* order: 0 */, 1u /* order: 0 */, + + /* key: requestid.seq */ + DDS_OP_KOF | 2, 1u /* order: 0 */, 4u /* order: 1 */ +}; + +static const dds_key_descriptor_t DurableSupport_request_keys[2] = +{ + { "requestid.client", 18, 0 }, + { "requestid.seq", 21, 1 } +}; + +/* Type Information: + [MINIMAL 54af0d70dd88f2a169924dd8b880] (#deps: 2) + - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] + - [MINIMAL 43f53a2be35b432cc735e9431a89] + [COMPLETE 77ef4931b703e23e4f8f33c76508] (#deps: 2) + - [COMPLETE 852fffc913b7ee54aadae7a1859a] + - [COMPLETE aca4d5a256d39713924333e85c6d] +*/ +#define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ + 0xc0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x54, 0xaf, 0x0d, 0x70, 0xdd, 0x88, 0xf2, 0xa1, 0x69, 0x92, 0x4d, \ + 0xd8, 0xb8, 0x80, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ + 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x77, 0xef, 0x49, 0x31, 0xb7, 0x03, 0xe2, 0x3e, 0x4f, 0x8f, 0x33, \ + 0xc7, 0x65, 0x08, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ + 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ + 0x40, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_request 196u +#define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ + 0x06, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0x54, 0xaf, 0x0d, 0x70, 0xdd, 0x88, 0xf2, \ + 0xa1, 0x69, 0x92, 0x4d, 0xd8, 0xb8, 0x80, 0x00, 0x69, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, \ + 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x3c, 0xb0, 0x21, 0x74, 0x00, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ + 0x11, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, \ + 0x00, 0xd8, 0xc7, 0x47, 0x1e, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, \ + 0x0f, 0xd5, 0x22, 0xa4, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, \ + 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, \ + 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ + 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xbc, 0x01, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0xf2, 0x77, 0xef, 0x49, 0x31, 0xb7, 0x03, 0xe2, 0x3e, 0x4f, 0x8f, 0x33, \ + 0xc7, 0x65, 0x08, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x00, \ + 0x96, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, \ + 0x9a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, \ + 0x64, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, \ + 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, \ + 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x02, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ + 0x46, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0xf2, 0x77, 0xef, 0x49, 0x31, 0xb7, 0x03, 0xe2, 0x3e, 0x4f, 0x8f, 0x33, \ + 0xc7, 0x65, 0x08, 0xf1, 0x54, 0xaf, 0x0d, 0x70, 0xdd, 0x88, 0xf2, 0xa1, 0x69, 0x92, 0x4d, 0xd8, \ + 0xb8, 0x80, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, \ + 0x9a, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, \ + 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_request 814u +const dds_topic_descriptor_t DurableSupport_request_desc = +{ + .m_size = sizeof (DurableSupport_request), + .m_align = dds_alignof (DurableSupport_request), + .m_flagset = DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 2u, + .m_typename = "DurableSupport::request", + .m_keys = DurableSupport_request_keys, + .m_nops = 10, + .m_ops = DurableSupport_request_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request } +}; + +static const uint32_t DurableSupport_bead_ops [] = +{ + /* bead */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_bead, id), 16u, + DDS_OP_ADR | DDS_OP_TYPE_EXT, offsetof (DurableSupport_bead, body), (3u << 16u) + 4u /* content */, + DDS_OP_RTS, + + /* content */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_content, _d), 4u, (20u << 16u) + 4u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 17 /* session_t */, 1, offsetof (DurableSupport_content, _u.session), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 19 /* set_t */, 2, offsetof (DurableSupport_content, _u.set), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 31 /* writer_t */, 3, offsetof (DurableSupport_content, _u.writer), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 44 /* data_t */, 4, offsetof (DurableSupport_content, _u.data), 0u, + DDS_OP_RTS, + + /* session_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_2BY, offsetof (DurableSupport_session_t, kind), + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_session_t, session_id), + DDS_OP_RTS, + + /* set_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, partition), + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, tpname), + DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_set_t, flags), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_ARR, offsetof (DurableSupport_set_t, addressees), sizeof (DurableSupport_id_t), (8u << 16u) + 4u, + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, 0u, 16u, + DDS_OP_RTS, + DDS_OP_RTS, + + /* writer_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_writer_t, id), 16u, + DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_writer_t, flags), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_writer_t, ranges), sizeof (DurableSupport_range), (4u << 16u) + 5u /* range */, + DDS_OP_RTS, + + /* range */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, lb), + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, ub), + DDS_OP_RTS, + + /* data_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_data_t, blob), + DDS_OP_RTS, + + /* key: id */ + DDS_OP_KOF | 1, 1u /* order: 0 */ +}; + +static const dds_key_descriptor_t DurableSupport_bead_keys[1] = +{ + { "id", 73, 0 } +}; + +/* Type Information: + [MINIMAL 1915eb63b1ad4283c95c42298512] (#deps: 9) + - [MINIMAL 43f53a2be35b432cc735e9431a89] + - [MINIMAL 219813f96895eb7a5bddfe02219f] + - [MINIMAL 80455e796dd3437163cb532089da] + - [MINIMAL 7fe2256248fb0dc7c6a9b6c616fb] + - [MINIMAL d8398b259af5a04792e296996c27] + - [MINIMAL 0d686e35dcd446cd843b793a485c] + - [MINIMAL 2f19a070996d925b553ac288a028] + - [MINIMAL ef038b7b19448c9ce27fa1c268cd] + - [MINIMAL a580b28d8a19d4a49d2794aae844] + [COMPLETE a89c569f6d508f3372a8c6407126] (#deps: 10) + - [COMPLETE aca4d5a256d39713924333e85c6d] + - [COMPLETE 28eef02baeaad008f0cda9febf47] + - [COMPLETE 105e7fa73d9700c1960716873c88] + - [COMPLETE 5de973c540260a829429a905efcd] + - [COMPLETE 838f13c80cfd7a0061fb91f88e49] + - [COMPLETE 9c5d42ec81585355d169823828eb] + - [COMPLETE dd9a1bfb3c68ff5066e4b763a939] + - [COMPLETE 1b62cfe76a5bdbc5e39d9f6d3975] + - [COMPLETE d8d43c2295c185a21b9591a7126c] + - [COMPLETE a092964f6f76e3d643846ba36f9b] +*/ +#define TYPE_INFO_CDR_DurableSupport_bead (const unsigned char []){ \ + 0x28, 0x02, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x00, 0x01, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x19, 0x15, 0xeb, 0x63, 0xb1, 0xad, 0x42, 0x83, 0xc9, 0x5c, 0x42, \ + 0x29, 0x85, 0x12, 0x00, 0x55, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, \ + 0x09, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x21, 0x98, 0x13, 0xf9, 0x68, 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0x00, \ + 0xcc, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ + 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0x00, \ + 0x55, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ + 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, \ + 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, \ + 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, 0x28, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, \ + 0x37, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, \ + 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0x18, 0x01, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa8, 0x9c, 0x56, \ + 0x9f, 0x6d, 0x50, 0x8f, 0x33, 0x72, 0xa8, 0xc6, 0x40, 0x71, 0x26, 0x00, 0x83, 0x00, 0x00, 0x00, \ + 0x0a, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ + 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x28, 0xee, 0xf0, 0x2b, 0xae, 0xaa, 0xd0, \ + 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, 0x47, 0x00, 0x13, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, \ + 0x39, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, \ + 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, \ + 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, \ + 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0x00, \ + 0xb5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, 0x5b, 0xdb, \ + 0xc5, 0xe3, 0x9d, 0x9f, 0x6d, 0x39, 0x75, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, \ + 0x61, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, \ + 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x00, 0x4f, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_bead 556u +#define TYPE_MAP_CDR_DurableSupport_bead (const unsigned char []){ \ + 0xc0, 0x03, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xf1, 0x19, 0x15, 0xeb, 0x63, 0xb1, 0xad, 0x42, \ + 0x83, 0xc9, 0x5c, 0x42, 0x29, 0x85, 0x12, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x21, 0x98, 0x13, 0xf9, 0x68, \ + 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ + 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x21, 0x98, 0x13, 0xf9, 0x68, \ + 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, \ + 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ + 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ + 0xa4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, \ + 0xfb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0xd6, 0xf4, 0x0c, \ + 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, \ + 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf1, 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, \ + 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xa8, 0x2f, 0xee, 0xe3, \ + 0x24, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ + 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ + 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x7f, 0xe2, 0x25, 0x62, \ + 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x80, \ + 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xd9, 0x39, 0xaa, \ + 0xf7, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ + 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x7f, 0xc8, 0xef, \ + 0x54, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, \ + 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x06, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ + 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, 0x46, 0xcd, \ + 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ + 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ + 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ + 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x73, 0xed, \ + 0xc9, 0x6c, 0xf1, 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, \ + 0x28, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, \ + 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, \ + 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x8d, 0x81, 0x02, 0xfb, 0xf1, 0xef, \ + 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x00, 0x00, \ + 0x33, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x08, 0x26, 0x40, 0x3e, 0xc6, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x08, 0x1c, 0x78, 0xb4, 0x86, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, \ + 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \ + 0xee, 0x26, 0x90, 0x8b, 0xcf, 0x05, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xf2, 0xa8, 0x9c, 0x56, \ + 0x9f, 0x6d, 0x50, 0x8f, 0x33, 0x72, 0xa8, 0xc6, 0x40, 0x71, 0x26, 0x00, 0x7f, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x62, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0x28, 0xee, 0xf0, 0x2b, 0xae, 0xaa, 0xd0, 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, \ + 0x47, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, \ + 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, \ + 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ + 0xf2, 0x28, 0xee, 0xf0, 0x2b, 0xae, 0xaa, 0xd0, 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, 0x47, 0x00, \ + 0x0f, 0x01, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x00, 0x13, 0x00, 0x00, 0x00, \ + 0x11, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, \ + 0x88, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, \ + 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x08, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, \ + 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, \ + 0x5b, 0xdb, 0xc5, 0xe3, 0x9d, 0x9f, 0x6d, 0x39, 0x75, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xa0, \ + 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, \ + 0x00, 0x00, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, \ + 0x3c, 0x88, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x62, 0x65, 0x61, 0x64, 0x74, 0x79, 0x70, 0x65, \ + 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x5d, 0xe9, \ + 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x89, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x83, \ + 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x6b, 0x69, 0x6e, 0x64, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, \ + 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, \ + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, \ + 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, \ + 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, \ + 0x82, 0x38, 0x28, 0xeb, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, \ + 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, \ + 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, \ + 0xb1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, \ + 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, \ + 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, \ + 0x5c, 0x6d, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, \ + 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, 0x5b, 0xdb, 0xc5, 0xe3, 0x9d, \ + 0x9f, 0x6d, 0x39, 0x75, 0xa1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, \ + 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, \ + 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x5d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x61, 0x6e, 0x67, \ + 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6c, 0x62, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, \ + 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x4b, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x61, 0x74, 0x61, \ + 0x5f, 0x74, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, \ + 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0xf2, 0xa8, 0x9c, 0x56, 0x9f, 0x6d, 0x50, 0x8f, 0x33, 0x72, 0xa8, 0xc6, 0x40, 0x71, 0x26, 0xf1, \ + 0x19, 0x15, 0xeb, 0x63, 0xb1, 0xad, 0x42, 0x83, 0xc9, 0x5c, 0x42, 0x29, 0x85, 0x12, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x28, 0xee, 0xf0, \ + 0x2b, 0xae, 0xaa, 0xd0, 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, 0x47, 0xf1, 0x21, 0x98, 0x13, 0xf9, \ + 0x68, 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, \ + 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, \ + 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, \ + 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, \ + 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, \ + 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, \ + 0x53, 0x20, 0x89, 0xda, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, \ + 0x38, 0x28, 0xeb, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ + 0x6c, 0x27, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, \ + 0x39, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, \ + 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, 0x5b, 0xdb, 0xc5, 0xe3, 0x9d, 0x9f, 0x6d, 0x39, 0x75, 0xf1, \ + 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, 0x28, 0xf2, 0xd8, \ + 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, 0xef, 0x03, \ + 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0xf2, 0xa0, 0x92, 0x96, \ + 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, \ + 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_bead 2794u +const dds_topic_descriptor_t DurableSupport_bead_desc = +{ + .m_size = sizeof (DurableSupport_bead), + .m_align = dds_alignof (DurableSupport_bead), + .m_flagset = DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 1u, + .m_typename = "DurableSupport::bead", + .m_keys = DurableSupport_bead_keys, + .m_nops = 35, + .m_ops = DurableSupport_bead_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_bead, .sz = TYPE_INFO_CDR_SZ_DurableSupport_bead }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_bead, .sz = TYPE_MAP_CDR_SZ_DurableSupport_bead } +}; diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 471c12ea50..d48bf8494a 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -9,36 +9,693 @@ * * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ +#include "dds/ddsi/ddsi_domaingv.h" #include "dds/durability/dds_durability.h" +#include "dds/durability/client_durability.h" +#include "dds/ddsrt/atomics.h" +#include "dds/ddsrt/string.h" +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/threads.h" +#include "dds/ddsrt/log.h" #include "ddsc/dds.h" +#include +#define TRACE(...) DDS_CLOG (DDS_LC_DUR, &domaingv->logconfig, __VA_ARGS__) -dds_return_t dds_durability_init2 (struct ddsi_domaingv* gv) +struct known_ds_t { + ddsrt_avl_node_t node; + DurableSupport_id_t id; /* id key */ + char id_str[37]; /* cached string representation of the id */ + char *hostname; /* advertised hostname */ + char *name; /* human readable name */ +}; + +static char *dc_stringify_id(const DurableSupport_id_t id, char *buf) +{ + assert(buf); + snprintf (buf, 37, "%02x%02x%02x%02x\055%02x%02x\055%02x%02x\055%02x%02x\055%02x%02x%02x%02x%02x%02x", + id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], + id[8], id[9], id[10], id[11], id[12], id[13], id[14], id[15]); + return buf; +} + +static int cmp_known_ds (const void *a, const void *b) +{ + return memcmp(a, b, 16); +} + +static void cleanup_known_ds (void *n) +{ + struct known_ds_t *known_ds = (struct known_ds_t *)n; + ddsrt_free(known_ds->hostname); + ddsrt_free(known_ds->name); + ddsrt_free(known_ds); +} + +static const ddsrt_avl_ctreedef_t known_ds_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct known_ds_t, node), offsetof (struct known_ds_t, id), cmp_known_ds, 0); + +struct com_t { + dds_entity_t participant; /* durable client participant */ + dds_entity_t status_subscriber; /* subscriber used to receive status messages */ + dds_entity_t request_publisher; /* publisher to send requests */ + dds_entity_t response_subscriber; /* subscriber used to receive response messages */ + dds_entity_t tp_status; /* status topic */ + dds_entity_t rd_status; /* status reader */ + dds_entity_t rc_status; /* status read condition */ + dds_entity_t tp_request; /* request topic */ + dds_entity_t wr_request; /* request writer */ + dds_entity_t tp_response; /* response topic */ + dds_entity_t rd_response; /* response reader */ + dds_entity_t rc_response; /* response read condition */ + dds_listener_t *status_listener; /* listener on status topic */ + dds_entity_t ws; +}; + +/* This struct contains the main durable client administration. + * This struct is initialized when an application creates the first participant, and + * deinitialized when the last participant is deleted. + * In case an application tries to create multiple participants at once (e.q., + * using different threads), we only want to initialize the durable client + * administration only once. For that purpose, we keep an atomic refcount to + * that tracks how many participants are created. + * we only want a + */ +struct dc_t { + struct { + char *request_partition; /* partition to send requests too; by default same as */ + uint32_t quorum; /*quorum of durable services needed to unblock durable writers */ + } cfg; + ddsrt_atomic_uint32_t refcount; /* refcount, increased/decreased when a participant is created/deleted */ + struct ddsi_domaingv *gv; /* reference to ddsi domain settings */ + struct com_t *com; /* ptr to durable client communication infra structure */ + bool quorum_reached; + ddsrt_thread_t recv_tid; /* receiver thread */ + ddsrt_threadattr_t recv_tattr; /* receiver thread attributes */ + ddsrt_mutex_t recv_mutex; /* recv mutex */ + ddsrt_cond_t recv_cond; /* recv condition */ + ddsrt_atomic_uint32_t termflag; /* termination flag, initialized to 0 */ + ddsrt_avl_ctree_t known_ds; /* tree containing all known ds's */ +}; + +static struct dc_t dc = { 0 }; /* static durable client structure */ + +static unsigned split_string (const char ***p_ps, char **p_bufcopy, const char *buf, const char delimiter) +{ + const char *b; + const char **ps; + char *bufcopy, *bc; + unsigned i, nps; + nps = 1; + for (b = buf; *b; b++) { + nps += (*b == delimiter); + } + ps = dds_alloc(nps * sizeof(*ps)); + bufcopy = ddsrt_strdup(buf); + i = 0; + bc = bufcopy; + while (1) { + ps[i++] = bc; + while (*bc && *bc != delimiter) bc++; + if (*bc == 0) break; + *bc++ = 0; + } + assert(i == nps); + *p_ps = ps; + *p_bufcopy = bufcopy; + return nps; +} + +#if 0 +/* callback function to update the sequence number administration of a container + * and to optionally monitor the contents of data containers */ +static void default_data_available_cb (dds_entity_t rd, void *arg) +{ +#define MAX_SAMPLES 100 + int samplecount; + static void *samples[MAX_SAMPLES]; + dds_sample_info_t info[MAX_SAMPLES]; + + (void)arg; + + samplecount = dds_read_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ALIVE_INSTANCE_STATE); + printf("LH *** samplecount = %d\n", samplecount); + if (samplecount < 0) { + printf("LH *** dds_read_mask for status reader failed: %s", dds_strretcode(-samplecount)); + goto samplecount_err; + } + for (int j = 0; j < samplecount; j++) { + DurableSupport_status *status = (DurableSupport_status *)samples[j]; + printf("LH *** recv status(): name=%s\n", status->name); + info[j].publication_handle(); + + } +samplecount_err: +#undef MAX_SAMPLES + return; +} +#endif + +static void evaluate_quorum_reached (struct dc_t *dc, const uint32_t cnt) +{ + if (dc->quorum_reached) { + if (cnt < dc->cfg.quorum) { + /* quorum changed from reached to not reached */ + dc->quorum_reached = false; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum droppped below threshold (%" PRIu32 ")\n", dc->cfg.quorum); + } + } else { + if (cnt >= dc->cfg.quorum) { + /* quorum changed from not reached to reached */ + dc->quorum_reached = true; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum threshold (%" PRIu32 ") reached\n", dc->cfg.quorum); + } + } +} + +static struct known_ds_t *create_known_ds (struct dc_t *dc, DurableSupport_id_t id, const char *name, const char *hostname) +{ + struct known_ds_t *known_ds; + char id_str[37]; /* guid */ + + assert(name); + assert(hostname); + /* the ds is not known yet by the dc, let's create it */ + if ((known_ds = (struct known_ds_t *)ddsrt_malloc(sizeof(struct known_ds_t))) == NULL) { + goto err_alloc_known_ds; + } + memcpy(known_ds->id, id, 16); + dc_stringify_id(known_ds->id, known_ds->id_str); + known_ds->name = ddsrt_strdup(name); + known_ds->hostname = ddsrt_strdup(hostname); + ddsrt_avl_cinsert(&known_ds_td, &dc->known_ds, known_ds); + return known_ds; + +err_alloc_known_ds: + DDS_ERROR("Failed to create ds for id \"%s\"\n", dc_stringify_id(id, id_str)); + return NULL; +} + +static int get_host_specific_partition_name (char *buf, size_t len) +{ + char hostname[256]; + dds_return_t ret; + int l; + + if ((len == 0) || (buf == NULL)) { + DDS_ERROR("No storage for hostname available, unable to determine the host specific partition\n"); + return -1; + } + if ((ret = ddsrt_gethostname(hostname, 256)) < 0) { + DDS_ERROR("Hostname limit of 256 exceeded, unable to determine the host specific partition [%s]\n", dds_strretcode(ret)); + return -1; + } + if ((l = snprintf(buf, len, "%s", hostname)) < 0) { + DDS_ERROR("Failed to construct the host specific partition name [%s]\n", dds_strretcode(ret)); + return -1; + } + if (len <= (size_t)l) { + DDS_ERROR("Host specific partition name '%s' too long\n", buf); + return -1; + } + return 0; +} + +/* add a participant specific partition to the configured partition for client requests */ +/* create a comma separated list consisting of the 'hostname' followed by the + * list configured by cfg->request_partition. + * The combined length may not exceed 1024 characters (including the '\0' terminator) */ +static int create_request_partition_expression (struct com_t *com, char **request_partition) +{ + char req_pname[1024] = { 0 }; + int result = 0; + + (void)com; + if ((result = get_host_specific_partition_name(req_pname, 1024)) < 0) { + DDS_ERROR("Failed to create request partition expression\n"); + return -1; + } + /* todo: perhaps add a configurable set of request partitions */ + /* set the request partition*/ + *request_partition = ddsrt_strdup(req_pname); + return 0; +} + + +/* set up durable client infrastructure */ +static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, struct ddsi_domaingv *gv) +{ + struct com_t *com; + dds_qos_t *tqos = NULL; + dds_qos_t *status_sqos = NULL, *status_rqos = NULL; + dds_qos_t *request_pqos = NULL, *request_wqos = NULL; + dds_qos_t *response_sqos = NULL, *response_rqos = NULL; + const char **ps1, **ps2; + char *bufcopy1, *bufcopy2; + unsigned nps; + dds_return_t ret; + char *request_partition = NULL; + + (void)dc; + if ((com = (struct com_t *)ddsrt_malloc(sizeof(struct com_t))) == NULL) { + DDS_ERROR("failed to allocate dc communication infrastructure\n"); + goto err_alloc_com; + } + /* create participant, subscriber and publisher for durable client support */ + if ((com->participant = dds_create_participant(domainid, NULL, NULL)) < 0) { + DDS_ERROR("failed to create dc participant [%s]\n", dds_strretcode(-com->participant)); + goto err_create_participant; + } + if ((status_sqos = dds_create_qos()) == NULL) { + DDS_ERROR("failed to create the dc status subscriber qos\n"); + goto err_alloc_status_sqos; + } + /* todo: LH make the partition used to receive status message configurable */ + nps = split_string(&ps1, &bufcopy1, "durable_support", ','); + dds_qset_partition (status_sqos, nps, ps1); + if ((com->status_subscriber = dds_create_subscriber(com->participant, status_sqos, NULL)) < 0) { + DDS_ERROR("failed to create dc status subscriber [%s]\n", dds_strretcode(-com->status_subscriber)); + goto err_status_subscriber; + } + /* create status reader */ + if ((tqos = dds_create_qos()) == NULL) { + DDS_ERROR("failed to create the dc status topic qos\n"); + goto err_alloc_tqos; + } + dds_qset_durability(tqos, DDS_DURABILITY_TRANSIENT_LOCAL); + dds_qset_reliability(tqos, DDS_RELIABILITY_RELIABLE, DDS_SECS (1)); + dds_qset_destination_order(tqos, DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP); + dds_qset_history(tqos, DDS_HISTORY_KEEP_LAST, 1); + dds_qset_ignorelocal (tqos, DDS_IGNORELOCAL_PARTICIPANT); + if ((com->tp_status = dds_create_topic (com->participant, &DurableSupport_status_desc, "ds_status", tqos, NULL)) < 0) { + DDS_ERROR("failed to create dc status topic [%s]\n", dds_strretcode(-com->tp_status)); + goto err_tp_status; + } + if ((status_rqos = dds_create_qos()) == NULL) { + DDS_ERROR("failed to create dc status reader qos\n"); + goto err_alloc_status_rqos; + } + if ((ret = dds_copy_qos(status_rqos, tqos)) < DDS_RETCODE_OK) { + DDS_ERROR("failed to copy dc status topic qos [%s]\n", dds_strretcode(-ret)); + goto err_copy_status_rqos; + } + if ((com->rd_status = dds_create_reader(com->status_subscriber, com->tp_status, status_rqos, NULL)) < 0) { + DDS_ERROR("failed to create dc status reader [%s]\n", dds_strretcode(-com->rd_status)); + goto err_rd_status; + } + if ((com->rc_status = dds_create_readcondition (com->rd_status, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE)) < 0) { + DDS_ERROR("failed to create dc status read condition [%s]\n", dds_strretcode(-com->rc_status)); + goto err_rc_status; + } + /* create dc_request writer */ + if (create_request_partition_expression(com, &request_partition) < 0) { + DDS_ERROR("failed to create dc request partition\n"); + goto err_request_partition; + } + nps = split_string(&ps2, &bufcopy2, request_partition, ','); + assert(nps > 0); + if ((request_pqos = dds_create_qos()) == NULL) { + DDS_ERROR("failed to create dc publisher qos for request topic\n"); + goto err_alloc_request_pqos; + } + dds_qset_partition (request_pqos, nps, ps2); + if ((com->request_publisher = dds_create_publisher(com->participant, request_pqos, NULL)) < 0) { + DDS_ERROR("Failed to create dc publisher for request topic [%s]\n", dds_strretcode(-com->request_publisher)); + goto err_request_publisher; + } + dds_qset_durability(tqos, DDS_DURABILITY_VOLATILE); + dds_qset_history(tqos, DDS_HISTORY_KEEP_ALL, DDS_LENGTH_UNLIMITED); + if ((com->tp_request = dds_create_topic (com->participant, &DurableSupport_request_desc, "dc_request", tqos, NULL)) < 0) { + DDS_ERROR("failed to create the dc request topic [%s]\n", dds_strretcode(-com->tp_request)); + goto err_tp_request; + } + if ((request_wqos = dds_create_qos()) == NULL) { + DDS_ERROR("failed to create dc request writer qos\n"); + goto err_alloc_request_wqos; + } + if ((ret = dds_copy_qos(request_wqos, tqos)) < DDS_RETCODE_OK) { + DDS_ERROR("failed to copy dc request topic qos [%s]\n", dds_strretcode(-ret)); + goto err_copy_request_wqos; + } + if ((com->wr_request = dds_create_writer(com->request_publisher, com->tp_request, request_wqos, NULL)) < 0) { + DDS_ERROR("failed to create dc request writer [%s]\n", dds_strretcode(-com->wr_request)); + goto err_wr_request; + } + /* create dc_response reader */ + if ((response_sqos = dds_create_qos()) == NULL) { + DDS_ERROR("failed to create the dc response subscriber qos qos\n"); + goto err_alloc_response_sqos; + } + dds_qset_partition (response_sqos, nps, ps2); + if ((com->response_subscriber = dds_create_subscriber(com->participant, response_sqos, NULL)) < 0) { + DDS_ERROR("failed to create dc response subscriber [%s]\n", dds_strretcode(-com->response_subscriber)); + goto err_response_subscriber; + } + if ((com->tp_response = dds_create_topic (com->participant, &DurableSupport_bead_desc, "dc_response", tqos, NULL)) < 0) { + DDS_ERROR("failed to create dc response topic [%s]\n", dds_strretcode(-com->tp_response)); + goto err_tp_response; + } + if ((response_rqos = dds_create_qos()) == NULL) { + DDS_ERROR("failed to create dc response reader qos\n"); + goto err_alloc_response_rqos; + } + if ((ret = dds_copy_qos(response_rqos, tqos)) < DDS_RETCODE_OK) { + DDS_ERROR("failed to copy dc response topic qos [%s]\n", dds_strretcode(-ret)); + goto err_copy_response_rqos; + } + if ((com->rd_response = dds_create_reader(com->response_subscriber, com->tp_response, response_rqos, NULL)) < 0) { + DDS_ERROR("failed to create dc response reader [%s]\n", dds_strretcode(-com->rd_response)); + goto err_rd_response; + } + if ((com->rc_response = dds_create_readcondition (com->rd_response, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE)) < 0) { + DDS_ERROR("failed to create dc response read condition [%s]\n", dds_strretcode(-com->rc_response)); + goto err_rc_response; + } + /* create waitset and attach read conditions */ + if ((com->ws = dds_create_waitset(com->participant)) < 0) { + DDS_ERROR("failed to create dc waitset [%s]\n", dds_strretcode(-com->ws)); + goto err_waitset; + } + if ((ret = dds_waitset_attach (com->ws, com->rc_status, com->rd_status)) < 0) { + DDS_ERROR("failed to attach dc status reader to waitset [%s]\n", dds_strretcode(-ret)); + goto err_attach_rd_status; + } + if ((ret = dds_waitset_attach (com->ws, com->rc_response, com->rd_response)) < 0) { + DDS_ERROR("failed to attach dc response reader to waitset [%s]\n", dds_strretcode(-ret)); + goto err_attach_rd_response; + } + if ((ret = dds_waitset_attach (com->ws, com->ws, com->ws)) < 0) { + DDS_ERROR("failed to attach waitset to itself [%s]\n", dds_strretcode(-ret)); + goto err_attach_ws; + } + DDS_CLOG(DDS_LC_DUR, &gv->logconfig, "dc infrastructure created\n"); + dds_free(request_partition); + dds_delete_qos(tqos); + dds_delete_qos(status_sqos); + dds_delete_qos(status_rqos); + dds_delete_qos(request_pqos); + dds_delete_qos(request_wqos); + dds_delete_qos(response_sqos); + dds_delete_qos(response_rqos); + dds_free(bufcopy1); + dds_free(bufcopy2); + dds_free(ps1); + dds_free(ps2); + return com; + +err_attach_ws: + dds_waitset_detach(com->ws, com->rc_response); +err_attach_rd_response: + dds_waitset_detach(com->ws, com->rc_status); +err_attach_rd_status: + dds_delete(com->ws); +err_waitset: + dds_delete(com->rc_response); +err_rc_response: + dds_delete(com->rd_response); +err_rd_response: +err_copy_response_rqos: + dds_delete_qos(response_rqos); +err_alloc_response_rqos: + dds_delete(com->tp_response); +err_tp_response: + dds_delete(com->response_subscriber); +err_response_subscriber : + dds_delete_qos(response_sqos); +err_alloc_response_sqos: + dds_delete(com->wr_request); +err_wr_request: +err_copy_request_wqos: + dds_delete_qos(request_wqos); +err_alloc_request_wqos: + dds_delete(com->tp_request); +err_tp_request: + dds_delete(com->request_publisher); +err_request_publisher: + dds_delete_qos(request_pqos); +err_alloc_request_pqos: + dds_free(request_partition); + dds_free(bufcopy2); + dds_free(ps2); +err_request_partition: + dds_delete(com->rc_status); +err_rc_status: + dds_delete(com->rd_status); +err_rd_status: +err_copy_status_rqos: + dds_delete_qos(status_rqos); +err_alloc_status_rqos: + dds_delete(com->tp_status); +err_tp_status: + dds_delete_qos(tqos); +err_alloc_tqos: + dds_delete(com->status_subscriber); +err_status_subscriber: + dds_delete_qos(status_sqos); + dds_free(bufcopy1); + dds_free(ps1); +err_alloc_status_sqos: + dds_delete(com->participant); +err_create_participant: + ddsrt_free(com); +err_alloc_com: + return NULL; +} + +static void dc_com_free (struct com_t *com) +{ + assert(com); + DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "destroying dc infrastructure\n"); + dds_delete(com->participant); + ddsrt_free(com); + dc.com = NULL; + return; +} + +static void dc_lost_ds (struct dc_t *dc, DurableSupport_status *status) +{ + struct known_ds_t *known_ds; + uint32_t total; + + /* lookup the ds entry in the list of available ds's */ + if ((known_ds = ddsrt_avl_clookup (&known_ds_td, &dc->known_ds, status->id)) == NULL) { + /* ds not known, so nothing lost */ + return; + } + ddsrt_avl_cdelete(&known_ds_td, &dc->known_ds, known_ds); + total = (uint32_t)ddsrt_avl_ccount(&dc->known_ds); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "durable service \"%s\" (%s@%s) lost (total: %" PRIu32 ")\n", known_ds->id_str, known_ds->name, known_ds->hostname, total); + cleanup_known_ds(known_ds); + /* a ds has been removed. + * we might have to reevaluate the quorum */ + evaluate_quorum_reached(dc, total); +} + +static void dc_ds_discovered (struct dc_t *dc, DurableSupport_status *status) +{ + struct known_ds_t *known_ds; + uint32_t total; + + /* lookup the ds entry in the list of available ds's */ + if ((known_ds = ddsrt_avl_clookup (&known_ds_td, &dc->known_ds, status->id)) != NULL) { + /* ds already known */ + return; + } + known_ds = create_known_ds(dc, status->id, status->name, status->hostname); + total = (uint32_t)ddsrt_avl_ccount(&dc->known_ds); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "durable service \"%s\" (%s@%s) discovered (total: %" PRIu32 ")\n", known_ds->id_str, known_ds->name, known_ds->hostname, total); + /* reevalute if the quorum has been reached */ + evaluate_quorum_reached(dc, total); +} + +static int dc_process_status (dds_entity_t rd, struct dc_t *dc) { - printf("!!!!!!!!!!!!!!!!!!! src/durability/core/src/dds_durability_init()\n"); +#define MAX_SAMPLES 100 + + static void *samples[MAX_SAMPLES]; + static dds_sample_info_t info[MAX_SAMPLES]; + int samplecount; + int j; + + samplecount = dds_take_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE); + if (samplecount < 0) { + DDS_ERROR("durable client failed to take ds_status [%s]", dds_strretcode(-samplecount)); + } else { + /* call the handler function to process the status sample */ + for (j = 0; !dds_triggered(dc->com->ws) && j < samplecount; j++) { + DurableSupport_status *status = (DurableSupport_status *)samples[j]; + if ((info[j].instance_state == DDS_IST_NOT_ALIVE_DISPOSED) || (info[j].instance_state == DDS_IST_NOT_ALIVE_NO_WRITERS)) { + /* a DS is not available any more, remove from the list of known DS's */ + dc_lost_ds(dc, status); + } else if (info[j].valid_data) { + /* a DS is available */ + + /* todo: check if the participant of the status topic contains the IDENT, + * so we are sure that this is a durable . This prevents that the client + * is fooled that a ds is present when some malicious node sends a + * status without the IDENT. However, for testing purposes we actually + * might want to fool a client. + * + * We might want to use dds_get_matched_publication_data() to retrieve the + * builtin endpoint for the writer that wrote the data, and check it's + * participant for the presence of the IDENT. */ + + dc_ds_discovered(dc, status); + } + } + } + return samplecount; +#undef MAX_SAMPLES +} + + +static uint32_t recv_handler (void *a) +{ + struct dc_t *dc = (struct dc_t *)a; + dds_duration_t timeout = DDS_INFINITY; + dds_attach_t wsresults[1]; + size_t wsresultsize = sizeof(wsresults)/sizeof(wsresults[0]); + int n; + int j; + + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "start durable client thread\n"); + while (!dds_triggered(dc->com->ws)) { + n = dds_waitset_wait_until (dc->com->ws, wsresults, wsresultsize, timeout); + if (n < 0) { + DDS_ERROR("Error in dds_waitset_wait_until [%s]\n", dds_strretcode(n)); + } else if (n > 0) { + for (j=0; j < n && (size_t)j < wsresultsize; j++) { + if (wsresults[j] == dc->com->rd_status) { + dc_process_status(dc->com->rd_status, dc); + } + } + } + } + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "stop durable client thread\n"); + return 0; +} + +dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_domaingv *gv) +{ + dds_return_t rc; + + /* a participant is created, increase the refcount. + * If this is not the first participant, then there is + * no reason to initialize the durable client */ + if (ddsrt_atomic_inc32_nv(&dc.refcount) > 1) { + return DDS_RETCODE_OK; + } + /* This is the first participant, so let's create a durable client (dc). + * The dc will also create a new participant, therefore + * increase the refcount for this participant as well. */ + ddsrt_atomic_inc32(&dc.refcount); + dc.gv = gv; + /* LH: the quorum is now initialized to 0. + * if set to 1, the transient_publisher cannot terminate if it has writers that are blocked. + * This is because the writers are only unblocked when dds_durability_fini(), + * but this function never gets called because the blocking transient_publisher application + * keeps a participant alive. */ + dc.cfg.quorum = 1; + ddsrt_avl_cinit(&known_ds_td, &dc.known_ds); + if ((dc.com = dc_com_new(&dc, domainid, gv))== NULL) { + DDS_ERROR("failed to initialize the durable client infrastructure\n"); + goto err_com_new; + } + /* start a thread to process messages coming from a ds */ + ddsrt_threadattr_init(&dc.recv_tattr); + if ((rc = ddsrt_thread_create(&dc.recv_tid, "dc", &dc.recv_tattr, recv_handler, &dc)) != DDS_RETCODE_OK) { + goto err_recv_thread; + } return DDS_RETCODE_OK; + +err_recv_thread: + dc.com = NULL; +err_com_new: + ddsrt_avl_cfree(&known_ds_td, &dc.known_ds, cleanup_known_ds); + return DDS_RETCODE_ERROR; } -dds_return_t dds_durability_fini2 (void) +/* make sure that dc terminates when the last participant is destroyed */ +dds_return_t dds_durability_fini (void) { - printf("!!!!!!!!!!!!!!!!!!! src/durability/core/src/dds_durability_fini()\n"); + dds_return_t rc; + uint32_t refcount; + + /* The durable client is deinitialized when the last participant is about + * to be removed. Note that the durable client itself also has a partition, + * so there are in fact 2 partitions (the last "real" partition, and the durable + * client partition. */ + refcount = ddsrt_atomic_dec32_nv(&dc.refcount); + if (refcount != 2) { + /* skip */ + return DDS_RETCODE_OK; + } + if (dc.com) { + /* indicate the the durable client is teminating */ + ddsrt_atomic_st32 (&dc.termflag, 1); + /* force the dc thread to terminate */ + if ((rc = dds_waitset_set_trigger(dc.com->ws, true)) < 0) { + DDS_ERROR("failed to trigger dc recv thread [%s]", dds_strretcode(rc)); + } + /* wait until the recv thread is terminated */ + if ((rc = ddsrt_thread_join(dc.recv_tid, NULL)) < 0) { + DDS_ERROR("failed to join the dc recv thread [%s]", dds_strretcode(rc)); + } + dc_com_free(dc.com); + ddsrt_avl_cfree(&known_ds_td, &dc.known_ds, cleanup_known_ds); + } return DDS_RETCODE_OK; } +bool dds_durability_is_terminating (void) +{ + return (ddsrt_atomic_ld32(&dc.termflag) > 0); +} + void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc) { /* create the administration to store transient data */ /* create a durability reader that sucks and stores it in the store */ - DDSRT_UNUSED_ARG(reader); + (void)rhc; + (void)reader; return; } -void dds_durability_wait_for_ds (uint32_t quorum, dds_time_t timeout) +/* This function checks if the writer has reached the quorum of matching durable containers + * + * It is NOT sufficient to verify if the quorum of durable services is reached. + * If a writer would unblock when the quorum of durable services is reached, then + * it is by no means certain that the durable writer has discovered the corresponding + * data containers of these durable services. Data that has is published before the + * data containers have been discovered by the writers, would not be delivered to + * the data containers. + * + * For this reason, the quorum must be calculated based on the number of discovered + * data containers for a writer. This also implies that if a writer has reached a quorum, + * some other writer may not have reached the quorum yet. + * + * return + * DDS_RETCODE_OK if quorum is reached + * DDS_PRECONDITION_NOT_MET otherwise + */ +dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer) { - (void)quorum; - (void)timeout; - return; -} +/* temporarily disabled */ +(void)writer; +#if 0 + uint32_t nds; + + if (writer == NULL) { + return DDS_RETCODE_PRECONDITION_NOT_MET; + } + /* quorum not reached if the number of discovered ds's is less than the quorum */ + if ((nds = (uint32_t)ddsrt_avl_ccount(&dc.known_ds)) < dc.cfg.quorum) { + printf("LH *** not enough ds\n"); + return DDS_RETCODE_PRECONDITION_NOT_MET; + } + /* */ +#endif + return DDS_RETCODE_OK; +} From 1e9ff016809c92b68c0fdc3a9626f94585685ba2 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 10 Oct 2023 11:23:52 +0200 Subject: [PATCH 011/207] Do send a nack if a gap for durable data i detected Signed-off-by: TheFixer --- src/core/ddsi/src/ddsi_receive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ddsi/src/ddsi_receive.c b/src/core/ddsi/src/ddsi_receive.c index 0653bf1f29..e4783dd41d 100644 --- a/src/core/ddsi/src/ddsi_receive.c +++ b/src/core/ddsi/src/ddsi_receive.c @@ -1000,7 +1000,7 @@ static int handle_AckNack (struct ddsi_receiver_state *rst, ddsrt_etime_t tnow, enqueued = 1; seq_xmit = ddsi_writer_read_seq_xmit (wr); ddsi_gap_info_init(&gi); - const bool gap_for_already_acked = ddsi_vendor_is_eclipse (rst->vendor) && prd->c.xqos->durability.kind == DDS_DURABILITY_VOLATILE && seqbase <= rn->seq; + const bool gap_for_already_acked = ddsi_vendor_is_eclipse (rst->vendor) && prd->c.xqos->durability.kind != DDS_DURABILITY_TRANSIENT_LOCAL && seqbase <= rn->seq; const ddsi_seqno_t min_seq_to_rexmit = gap_for_already_acked ? rn->seq + 1 : 0; uint32_t limit = wr->rexmit_burst_size_limit; for (uint32_t i = 0; i < numbits && seqbase + i <= seq_xmit && enqueued && limit > 0; i++) From 91d41742719eae1f66462a9d8bf0bf6f77db8756 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 13 Oct 2023 16:26:38 +0200 Subject: [PATCH 012/207] Quorum implementation based on subscription matched for durable writers Signed-off-by: TheFixer --- src/core/ddsc/src/dds__types.h | 4 + src/core/ddsc/src/dds_write.c | 9 +- src/core/ddsc/src/dds_writer.c | 13 + .../include/dds/durability/dds_durability.h | 2 + src/durability/src/dds_durability.c | 600 +++++++++++++++--- 5 files changed, 526 insertions(+), 102 deletions(-) diff --git a/src/core/ddsc/src/dds__types.h b/src/core/ddsc/src/dds__types.h index 3c8bbfa721..9048246181 100644 --- a/src/core/ddsc/src/dds__types.h +++ b/src/core/ddsc/src/dds__types.h @@ -414,6 +414,10 @@ typedef struct dds_writer { bool whc_batch; /* FIXME: channels + latency budget */ struct dds_loan_pool *m_loans; /* administration of associated loans */ +#ifdef DDS_HAS_DURABILITY + bool quorum_reached; /* quorum reached indicator for durable writer; when false, publication of data is not permitted */ +#endif + /* Status metrics */ dds_liveliness_lost_status_t m_liveliness_lost_status; diff --git a/src/core/ddsc/src/dds_write.c b/src/core/ddsc/src/dds_write.c index 9e70d9cc89..58a21f9561 100644 --- a/src/core/ddsc/src/dds_write.c +++ b/src/core/ddsc/src/dds_write.c @@ -777,8 +777,15 @@ dds_return_t dds_write_impl (dds_writer *wr, const void *data, dds_time_t timest return DDS_RETCODE_OK; #ifdef DDS_HAS_DURABILITY + /* check if the quorum of durable services for the writer is fulfilled + * + * LH: + * todo this currently is solution to handle the case when the quorum is not yet reached. + * A better solution would be to use the max_blocking_time and use it to figure out + * if the quorum is reached within this time frame. The headbang period would then be + * used to check if the quorum is met. */ if ((ddsi_wr->xqos->durability.kind == DDS_DURABILITY_TRANSIENT) || (ddsi_wr->xqos->durability.kind == DDS_DURABILITY_PERSISTENT)) { - if ((ret = dds_durability_check_quorum_reached(wr)) != DDS_RETCODE_OK) { + if (!wr->quorum_reached) { return DDS_RETCODE_PRECONDITION_NOT_MET; } } diff --git a/src/core/ddsc/src/dds_writer.c b/src/core/ddsc/src/dds_writer.c index 85d8961cb9..ab9a8ec8e9 100644 --- a/src/core/ddsc/src/dds_writer.c +++ b/src/core/ddsc/src/dds_writer.c @@ -38,6 +38,10 @@ #include "dds__statistics.h" #include "dds__psmx.h" +#ifdef DDS_HAS_DURABILITY +#include "dds/durability/dds_durability.h" +#endif + DECL_ENTITY_LOCK_UNLOCK (dds_writer) #define DDS_WRITER_STATUS_MASK \ @@ -422,6 +426,11 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit if ((rc = dds_endpoint_add_psmx_endpoint (&wr->m_endpoint, wqos, &tp->m_ktopic->psmx_topics, DDS_PSMX_ENDPOINT_TYPE_WRITER)) != DDS_RETCODE_OK) goto err_pipe_open; +#if DDS_HAS_DURABILITY + /* quorum applies only to durable writers, initially quorum is not reached */ + wr->quorum_reached = (wqos->durability.kind <= DDS_DURABILITY_VOLATILE) ? true : false; +#endif + struct ddsi_sertype *sertype = ddsi_sertype_derive_sertype (tp->m_stype, data_representation, wqos->present & DDSI_QP_TYPE_CONSISTENCY_ENFORCEMENT ? wqos->type_consistency : ddsi_default_qos_topic.type_consistency); if (!sertype) @@ -442,6 +451,10 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit dds_topic_unpin (tp); dds_publisher_unlock (pub); +#ifdef DDS_HAS_DURABILITY + dds_durability_new_local_writer(writer); +#endif + // start async thread if not already started and the latency budget is non zero ddsrt_mutex_lock (&gv->sendq_running_lock); if (async_mode && !gv->sendq_running) { diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h index c7b8a1f5cf..af8a6ab7c0 100644 --- a/src/durability/include/dds/durability/dds_durability.h +++ b/src/durability/include/dds/durability/dds_durability.h @@ -28,9 +28,11 @@ typedef int (*plugin_finalize)(void *context); dds_return_t dds_durability_init (const dds_domainid_t domain, struct ddsi_domaingv *gv); dds_return_t dds_durability_fini (void); void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc); +dds_return_t dds_durability_new_local_writer (dds_entity_t writer); dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer); bool dds_durability_is_terminating (void); + #if defined (__cplusplus) } #endif diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index d48bf8494a..2f32307361 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -19,16 +19,13 @@ #include "dds/ddsrt/log.h" #include "ddsc/dds.h" #include +#include "dds__writer.h" -#define TRACE(...) DDS_CLOG (DDS_LC_DUR, &domaingv->logconfig, __VA_ARGS__) +#define DEFAULT_QOURUM 1 +#define DEFAULT_IDENT "durable_support" -struct known_ds_t { - ddsrt_avl_node_t node; - DurableSupport_id_t id; /* id key */ - char id_str[37]; /* cached string representation of the id */ - char *hostname; /* advertised hostname */ - char *name; /* human readable name */ -}; + +#define TRACE(...) DDS_CLOG (DDS_LC_DUR, &domaingv->logconfig, __VA_ARGS__) static char *dc_stringify_id(const DurableSupport_id_t id, char *buf) { @@ -39,20 +36,94 @@ static char *dc_stringify_id(const DurableSupport_id_t id, char *buf) return buf; } -static int cmp_known_ds (const void *a, const void *b) + +struct server_t { + ddsrt_avl_node_t node; + DurableSupport_id_t id; /* id key */ + char id_str[37]; /* cached string representation of the id */ + char *hostname; /* advertised hostname */ + char *name; /* human readable name */ +}; + +static int cmp_server (const void *a, const void *b) { return memcmp(a, b, 16); } -static void cleanup_known_ds (void *n) +static void cleanup_server (void *n) +{ + struct server_t *server = (struct server_t *)n; + ddsrt_free(server->hostname); + ddsrt_free(server->name); + ddsrt_free(server); +} + +static const ddsrt_avl_ctreedef_t server_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct server_t, node), offsetof (struct server_t, id), cmp_server, 0); + + +struct quorum_entry_key_t { + char *partition; /* the partition of the data container; should be a singleton */ + char *tpname; /* topic name */ + /* LH: todo: add a type id to support xtypes */ +}; + +struct quorum_entry_t { + ddsrt_avl_node_t node; + struct quorum_entry_key_t key; + uint32_t cnt; /* the number of data containers found for this partition/topic combination */ +}; + +static int cmp_quorum_entry (const void *a, const void *b) +{ + struct quorum_entry_key_t *qk1 = (struct quorum_entry_key_t *)a; + struct quorum_entry_key_t *qk2 = (struct quorum_entry_key_t *)b; + int cmp; + + if ((cmp = strcmp(qk1->partition, qk2->partition)) < 0) { + return -1; + } else if (cmp > 0) { + return 1; + } else if ((cmp = strcmp(qk1->tpname, qk2->tpname)) < 0) { + return -1; + } else if (cmp > 0) { + return 1; + } else { + return 0; + } +} + +static void cleanup_quorum_entry (void *n) { - struct known_ds_t *known_ds = (struct known_ds_t *)n; - ddsrt_free(known_ds->hostname); - ddsrt_free(known_ds->name); - ddsrt_free(known_ds); + struct quorum_entry_t *qe = (struct quorum_entry_t *)n; + ddsrt_free(qe->key.partition); + ddsrt_free(qe->key.tpname); + ddsrt_free(qe); } -static const ddsrt_avl_ctreedef_t known_ds_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct known_ds_t, node), offsetof (struct known_ds_t, id), cmp_known_ds, 0); +static const ddsrt_avl_ctreedef_t quorum_entry_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct quorum_entry_t, node), offsetof (struct quorum_entry_t, key), cmp_quorum_entry, 0); + +struct handle_to_quorum_entry_t { + ddsrt_avl_node_t node; + dds_instance_handle_t ih; + struct quorum_entry_t *qe_ref; /* reference to quorum entry */ +}; + +static int cmp_instance_handle (const void *a, const void *b) +{ + dds_instance_handle_t *ih1 = (dds_instance_handle_t *)a; + dds_instance_handle_t *ih2 = (dds_instance_handle_t *)b; + + return (*ih1 < *ih2) ? -1 : ((*ih1 > *ih2) ? 1 : 0); +} + +static void cleanup_handle_to_quorum_entry (void *n) +{ + struct handle_to_quorum_entry_t *hqe = (struct handle_to_quorum_entry_t *)n; + + ddsrt_free(hqe); +} + +static const ddsrt_avl_ctreedef_t handle_to_quorum_entry_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct handle_to_quorum_entry_t, node), offsetof (struct handle_to_quorum_entry_t, ih), cmp_instance_handle, 0); struct com_t { dds_entity_t participant; /* durable client participant */ @@ -67,6 +138,9 @@ struct com_t { dds_entity_t tp_response; /* response topic */ dds_entity_t rd_response; /* response reader */ dds_entity_t rc_response; /* response read condition */ + dds_entity_t rd_participant; /* participant reader */ + dds_entity_t rd_subinfo; /* DCPSSubscription reader */ + dds_entity_t rc_subinfo; /* DCPSSubscription read condition */ dds_listener_t *status_listener; /* listener on status topic */ dds_entity_t ws; }; @@ -84,6 +158,7 @@ struct dc_t { struct { char *request_partition; /* partition to send requests too; by default same as */ uint32_t quorum; /*quorum of durable services needed to unblock durable writers */ + char *ident; /* ds identification */ } cfg; ddsrt_atomic_uint32_t refcount; /* refcount, increased/decreased when a participant is created/deleted */ struct ddsi_domaingv *gv; /* reference to ddsi domain settings */ @@ -94,7 +169,11 @@ struct dc_t { ddsrt_mutex_t recv_mutex; /* recv mutex */ ddsrt_cond_t recv_cond; /* recv condition */ ddsrt_atomic_uint32_t termflag; /* termination flag, initialized to 0 */ - ddsrt_avl_ctree_t known_ds; /* tree containing all known ds's */ + ddsrt_avl_ctree_t servers; /* tree containing all discovered durable servers */ + dds_listener_t *subinfo_listener; /* listener to detect remote containers */ + dds_listener_t *quorum_listener; /* listener to check if a quorum is reached */ + ddsrt_avl_ctree_t quorum_entries; /* tree containing quora for all discovered data containers */ + ddsrt_avl_ctree_t handle_to_quorum_entries; /* tree that maps subscription handles to references to quorum entries */ }; static struct dc_t dc = { 0 }; /* static durable client structure */ @@ -155,42 +234,25 @@ static void default_data_available_cb (dds_entity_t rd, void *arg) } #endif -static void evaluate_quorum_reached (struct dc_t *dc, const uint32_t cnt) +static struct server_t *create_server (struct dc_t *dc, DurableSupport_id_t id, const char *name, const char *hostname) { - if (dc->quorum_reached) { - if (cnt < dc->cfg.quorum) { - /* quorum changed from reached to not reached */ - dc->quorum_reached = false; - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum droppped below threshold (%" PRIu32 ")\n", dc->cfg.quorum); - } - } else { - if (cnt >= dc->cfg.quorum) { - /* quorum changed from not reached to reached */ - dc->quorum_reached = true; - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum threshold (%" PRIu32 ") reached\n", dc->cfg.quorum); - } - } -} - -static struct known_ds_t *create_known_ds (struct dc_t *dc, DurableSupport_id_t id, const char *name, const char *hostname) -{ - struct known_ds_t *known_ds; + struct server_t *server; char id_str[37]; /* guid */ assert(name); assert(hostname); /* the ds is not known yet by the dc, let's create it */ - if ((known_ds = (struct known_ds_t *)ddsrt_malloc(sizeof(struct known_ds_t))) == NULL) { - goto err_alloc_known_ds; + if ((server = (struct server_t *)ddsrt_malloc(sizeof(struct server_t))) == NULL) { + goto err_alloc_server; } - memcpy(known_ds->id, id, 16); - dc_stringify_id(known_ds->id, known_ds->id_str); - known_ds->name = ddsrt_strdup(name); - known_ds->hostname = ddsrt_strdup(hostname); - ddsrt_avl_cinsert(&known_ds_td, &dc->known_ds, known_ds); - return known_ds; + memcpy(server->id, id, 16); + dc_stringify_id(server->id, server->id_str); + server->name = ddsrt_strdup(name); + server->hostname = ddsrt_strdup(hostname); + ddsrt_avl_cinsert(&server_td, &dc->servers, server); + return server; -err_alloc_known_ds: +err_alloc_server: DDS_ERROR("Failed to create ds for id \"%s\"\n", dc_stringify_id(id, id_str)); return NULL; } @@ -370,6 +432,20 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc response read condition [%s]\n", dds_strretcode(-com->rc_response)); goto err_rc_response; } + /* create participant reader (to discover participants of remote durable services) */ + if ((com->rd_participant = dds_create_reader(com->participant, DDS_BUILTIN_TOPIC_DCPSPARTICIPANT, NULL, NULL)) < 0) { + DDS_ERROR("failed to create dc participant reader [%s]\n", dds_strretcode(-com->rd_participant)); + goto err_rd_participant; + } + /* subinfo reader and listener to detect remote data containers */ + if ((com->rd_subinfo = dds_create_reader(com->participant, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL)) < 0) { + DDS_ERROR("failed to create dc subinfo reader [%s]\n", dds_strretcode(-com->rd_subinfo)); + goto err_rd_subinfo; + } + if ((com->rc_subinfo = dds_create_readcondition(com->rd_subinfo, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE)) < 0) { + DDS_ERROR("failed to create dc subinfo read condition [%s]\n", dds_strretcode(-com->rc_subinfo)); + goto err_rc_subinfo; + } /* create waitset and attach read conditions */ if ((com->ws = dds_create_waitset(com->participant)) < 0) { DDS_ERROR("failed to create dc waitset [%s]\n", dds_strretcode(-com->ws)); @@ -409,6 +485,12 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, err_attach_rd_status: dds_delete(com->ws); err_waitset: + dds_delete(com->rc_subinfo); +err_rc_subinfo: + dds_delete(com->rd_subinfo); +err_rd_subinfo: + dds_delete(com->rd_participant); +err_rd_participant: dds_delete(com->rc_response); err_rc_response: dds_delete(com->rd_response); @@ -471,40 +553,35 @@ static void dc_com_free (struct com_t *com) return; } -static void dc_lost_ds (struct dc_t *dc, DurableSupport_status *status) +static void dc_server_lost (struct dc_t *dc, DurableSupport_status *status) { - struct known_ds_t *known_ds; + struct server_t *server; uint32_t total; /* lookup the ds entry in the list of available ds's */ - if ((known_ds = ddsrt_avl_clookup (&known_ds_td, &dc->known_ds, status->id)) == NULL) { + if ((server = ddsrt_avl_clookup (&server_td, &dc->servers, status->id)) == NULL) { /* ds not known, so nothing lost */ return; } - ddsrt_avl_cdelete(&known_ds_td, &dc->known_ds, known_ds); - total = (uint32_t)ddsrt_avl_ccount(&dc->known_ds); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "durable service \"%s\" (%s@%s) lost (total: %" PRIu32 ")\n", known_ds->id_str, known_ds->name, known_ds->hostname, total); - cleanup_known_ds(known_ds); - /* a ds has been removed. - * we might have to reevaluate the quorum */ - evaluate_quorum_reached(dc, total); + ddsrt_avl_cdelete(&server_td, &dc->servers, server); + total = (uint32_t)ddsrt_avl_ccount(&dc->servers); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "durable service \"%s\" (%s@%s) lost (total: %" PRIu32 ")\n", server->id_str, server->name, server->hostname, total); + cleanup_server(server); } -static void dc_ds_discovered (struct dc_t *dc, DurableSupport_status *status) +static void dc_server_discovered (struct dc_t *dc, DurableSupport_status *status) { - struct known_ds_t *known_ds; + struct server_t *server; uint32_t total; /* lookup the ds entry in the list of available ds's */ - if ((known_ds = ddsrt_avl_clookup (&known_ds_td, &dc->known_ds, status->id)) != NULL) { + if ((server = ddsrt_avl_clookup (&server_td, &dc->servers, status->id)) != NULL) { /* ds already known */ return; } - known_ds = create_known_ds(dc, status->id, status->name, status->hostname); - total = (uint32_t)ddsrt_avl_ccount(&dc->known_ds); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "durable service \"%s\" (%s@%s) discovered (total: %" PRIu32 ")\n", known_ds->id_str, known_ds->name, known_ds->hostname, total); - /* reevalute if the quorum has been reached */ - evaluate_quorum_reached(dc, total); + server = create_server(dc, status->id, status->name, status->hostname); + total = (uint32_t)ddsrt_avl_ccount(&dc->servers); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "durable service \"%s\" (%s@%s) discovered (total: %" PRIu32 ")\n", server->id_str, server->name, server->hostname, total); } static int dc_process_status (dds_entity_t rd, struct dc_t *dc) @@ -525,21 +602,15 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) DurableSupport_status *status = (DurableSupport_status *)samples[j]; if ((info[j].instance_state == DDS_IST_NOT_ALIVE_DISPOSED) || (info[j].instance_state == DDS_IST_NOT_ALIVE_NO_WRITERS)) { /* a DS is not available any more, remove from the list of known DS's */ - dc_lost_ds(dc, status); + dc_server_lost(dc, status); } else if (info[j].valid_data) { - /* a DS is available */ - - /* todo: check if the participant of the status topic contains the IDENT, - * so we are sure that this is a durable . This prevents that the client - * is fooled that a ds is present when some malicious node sends a - * status without the IDENT. However, for testing purposes we actually - * might want to fool a client. - * - * We might want to use dds_get_matched_publication_data() to retrieve the - * builtin endpoint for the writer that wrote the data, and check it's - * participant for the presence of the IDENT. */ - - dc_ds_discovered(dc, status); + /* To avoid reacting to malicious status messages we want to verify if + * the status message originates from a "real" DS by verifying if its participant + * contains the IDENT in the user data. To do this we actually need to retrieve + * the builtin endpoint that represents the status writer that published this + * status, and check if the participant of this writer has the IDENT in its + * userdata. For now, we skip this check. */ + dc_server_discovered(dc, status); } } } @@ -547,6 +618,270 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } +/* verifies if the user data of the endpoint contains the identifier + * that indicates that this endpoint is a durable container */ +static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *ep, const char *ident) +{ + dds_builtintopic_endpoint_t template; + dds_builtintopic_participant_t *participant; + dds_instance_handle_t ih; + dds_return_t rc; + static void *samples[1]; + static dds_sample_info_t info[1]; + void *userdata; + size_t size = 0; + char id_str[37]; + bool result = false; + + assert(ep); + /* by convention, if the ident == NULL then return true */ + if (ident == NULL) { + return true; + } + /* lookup the instance handle of the builtin participant endpoint that + * contains the participant of the subinfo */ + memcpy(template.key.v,ep->participant_key.v,16); + if ((ih = dds_lookup_instance(com->rd_participant, &template)) == DDS_HANDLE_NIL) { + DDS_ERROR("Failed to lookup the participant of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); + goto err_lookup_instance; + } + if ((rc = dds_read_instance(com->rd_participant, samples, info, 1, 1, ih)) <= 0) { + DDS_ERROR("Failed to read the participant of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); + goto err_read_instance; + } + if (info[0].valid_data) { + participant = (dds_builtintopic_participant_t *)samples[0]; + /* get the user data */ + if (!dds_qget_userdata(participant->qos, &userdata, &size)) { + DDS_ERROR("Unable to retrieve the user data of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); + goto err_qget_userdata; + } + if ((size != strlen(ident)) || (userdata == NULL) || (strcmp(userdata, ident) != 0)) { + /* the user data of the participant of the durable reader does not contain the ident, + * so the endoint is not from a remote DS */ + result = false; + } else { + /* this endpoint's participant is a ds */ + result = true; + } + dds_free(userdata); + } + return result; + +err_lookup_instance: +err_read_instance: +err_qget_userdata: + return false; +} + +static void dc_free_partitions (uint32_t plen, char **partitions) +{ + uint32_t i; + + if (partitions == NULL) { + return; + } + for (i=0; i < plen; i++) { + ddsrt_free(partitions[i]); + } + ddsrt_free(partitions); +} + + +static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer) +{ + dds_qos_t *qos; + dds_writer *wr; + dds_return_t rc; + uint32_t plen, i; + char **partitions; + struct quorum_entry_key_t key; + struct quorum_entry_t *qe; + bool quorum_reached = true; + + assert(writer); + assert(dc); + + qos = dds_create_qos(); + if ((rc = dds_get_qos(writer, qos)) < 0) { + DDS_ERROR("failed to get qos from writer [%s]", dds_strretcode(rc)); + goto err_get_qos; + } + if (!dds_qget_partition(qos, &plen, &partitions)) { + DDS_ERROR("failed to get partitions from qos\n"); + goto err_qget_partition; + } + assert(plen > 0); + if ((rc = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) { + DDS_ERROR("failed to lock writer\n"); + goto err_writer_lock; + } + key.tpname = ddsrt_strdup(wr->m_topic->m_name); + /* nothing to do if quorum was already reached */ + if (!wr->quorum_reached) { + for (i=0; i < plen && quorum_reached; i++) { + /* lookup the quorum entry and if a quorum has reached for all relevant data containers */ + key.partition = ddsrt_strdup(partitions[i]); + if ((qe = ddsrt_avl_clookup (&quorum_entry_td, &dc->quorum_entries, &key)) == NULL) { + quorum_reached = false; + } else { + quorum_reached = (qe->cnt >= dc->cfg.quorum); + } + ddsrt_free(key.partition); + } + wr->quorum_reached = quorum_reached; + } + ddsrt_free(key.tpname); + dds_writer_unlock (wr); +err_writer_lock: + dc_free_partitions(plen, partitions); +err_qget_partition: +err_get_qos: + dds_delete_qos(qos); + return; +} + +/* get a quorum counter for the builtin endoint and create a quorum counter for the endpoint */ +static struct quorum_entry_t *dc_get_or_create_quorum_entry (struct dc_t *dc, dds_builtintopic_endpoint_t *ep) +{ + struct quorum_entry_t *qe; + struct quorum_entry_key_t key; + uint32_t plen; + char **partitions; + + if (!dds_qget_partition(ep->qos, &plen, &partitions)) { + DDS_ERROR("failed to get partitions from qos\n"); + goto err_qget_partition; + } + assert(plen == 1); + key.tpname = ddsrt_strdup(ep->topic_name); + key.partition = ddsrt_strdup(partitions[0]); + if ((qe = ddsrt_avl_clookup (&quorum_entry_td, &dc->quorum_entries, &key)) == NULL) { + /* create quorum entry */ + if ((qe = (struct quorum_entry_t *)ddsrt_malloc(sizeof(struct quorum_entry_t))) == NULL) { + DDS_ERROR("failed to allocate quorum entry\n"); + goto err_alloc_quorum_entry; + } + qe->key.partition = ddsrt_strdup(key.partition); + qe->key.tpname = ddsrt_strdup(key.tpname); + qe->cnt = 0; + ddsrt_avl_cinsert(&quorum_entry_td, &dc->quorum_entries, qe); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum entry for \"%s.%s\" created\n", qe->key.partition, qe->key.tpname); + } + ddsrt_free(key.tpname); + ddsrt_free(key.partition); + dc_free_partitions(plen, partitions); + return qe; + +err_alloc_quorum_entry: + ddsrt_free(key.tpname); + ddsrt_free(key.partition); + dc_free_partitions(plen, partitions); +err_qget_partition: + return NULL; +} + +static struct quorum_entry_t *dc_link_handle_to_quorum_entry (struct dc_t *dc, dds_instance_handle_t ih, struct quorum_entry_t *qe) +{ + struct handle_to_quorum_entry_t *hqe; + + assert(qe); + /* link the handle to the quorum entry, so we can lookup the + * quorum entry if the data container identified by the handle + * disappears */ + if ((hqe = (struct handle_to_quorum_entry_t *)ddsrt_malloc(sizeof(struct handle_to_quorum_entry_t))) == NULL) { + DDS_ERROR("failed to allocate handle_to_quorum_entry_t\n"); + goto err_alloc_hqe; + } + hqe->ih = ih; + hqe->qe_ref = qe; + ddsrt_avl_cinsert(&handle_to_quorum_entry_td, &dc->handle_to_quorum_entries, hqe); + qe->cnt++; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for \"%s.%s\" bumped to %" PRIu32 " (ih %" PRIx64 ")\n", qe->key.partition, qe->key.tpname, qe->cnt, ih); + return qe; + +err_alloc_hqe: + return NULL; +} + +/* Update the quorum entry when a data container leaves. + * Returns a reference to the quorum entry as long as there are still containers, or NULL otherwise */ +static struct quorum_entry_t *dc_unlink_handle_to_quorum_entry (struct dc_t *dc, dds_instance_handle_t ih) +{ + struct handle_to_quorum_entry_t *hqe; + struct quorum_entry_t *qe = NULL; + ddsrt_avl_dpath_t dpath_hqe, dpath_qe; + + /* look up the quorum entry via the instance handle */ + if ((hqe = ddsrt_avl_clookup_dpath (&handle_to_quorum_entry_td, &dc->handle_to_quorum_entries, &ih, &dpath_hqe)) != NULL) { + qe = hqe->qe_ref; + assert(qe); + assert(qe->cnt > 0); + qe->cnt--; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for \"%s.%s\" decreased to %" PRIu32 " (ih %" PRIx64 ")\n", qe->key.partition, qe->key.tpname, qe->cnt, ih); + if (qe->cnt == 0) { + /* by unlinking this subscription info, the last reference to the quorum entry is now gone. + * We can now garbage collect the quorum entry itself. */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum entry for \"%s.%s\" deleted\n", qe->key.partition, qe->key.tpname); + if (ddsrt_avl_clookup_dpath(&quorum_entry_td, &dc->quorum_entries, &qe->key, &dpath_qe)) { + ddsrt_avl_cdelete_dpath(&quorum_entry_td, &dc->quorum_entries, qe, &dpath_qe); + cleanup_quorum_entry(qe); + qe = NULL; + } + } + ddsrt_avl_cdelete_dpath(&handle_to_quorum_entry_td, &dc->handle_to_quorum_entries, hqe, &dpath_hqe); + cleanup_handle_to_quorum_entry(hqe); + } + return qe; +} + +/* called when there is a match for a durable writer */ +static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publication_matched_status_t status, void *arg) +{ + struct dc_t *dc = (struct dc_t *)arg; + dds_instance_handle_t ih; + dds_builtintopic_endpoint_t *ep; + struct quorum_entry_t *qe; + + /* a reader has matched with a durable writer. */ + /* check if the reader is a data container. + * If so, this might affect the quorum */ + assert(writer); + if ((ih = status.last_subscription_handle) == DDS_HANDLE_NIL) { + DDS_ERROR("failed to receive valid last_subscription_handle\n"); + goto err_last_subscription_handle; + } + if ((ep = dds_get_matched_subscription_data(writer, ih)) != NULL) { + if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { + /* a data container has matched with this writer. + * Increase the quorum counter for this container. + * If no quorum counter existed, then create one. + * Also link the subscription handle to the quorum counter, + * so that we can decrease the quorum counter in case the + * data container does not exist. */ + if ((qe = dc_get_or_create_quorum_entry(dc, ep)) == NULL) { + goto err_inc_or_create_quorum_entry; + } + dc_link_handle_to_quorum_entry(dc, ih, qe); + /* a relevant data container from a durable service for this writer has become available. + * Reevaluate if the quorum has been reached */ + dc_check_quorum_reached(dc, writer); + } + dds_builtintopic_free_endpoint(ep); + } else { + /* the endpoint that represents a data container is not available any more. + * decrease the quorum counter for the data container associated with + * the handle. If the quorum counter reaches 0, we'll garbage collect + * the quorum counter entry. */ + qe = dc_unlink_handle_to_quorum_entry(dc, ih); + /* a data container from a durable service has been lost. + * reevaluate if the quorum still holds */ + dc_check_quorum_reached(dc, writer); + } + err_inc_or_create_quorum_entry: +err_last_subscription_handle: + return; +} static uint32_t recv_handler (void *a) { @@ -554,9 +889,23 @@ static uint32_t recv_handler (void *a) dds_duration_t timeout = DDS_INFINITY; dds_attach_t wsresults[1]; size_t wsresultsize = sizeof(wsresults)/sizeof(wsresults[0]); - int n; - int j; + int n, j; + dds_return_t rc; + if ((dc->quorum_listener = dds_create_listener(dc)) == NULL) { + DDS_ERROR("failed to create quorum listener\n"); + goto err_create_quorum_listener; + } + dds_lset_publication_matched(dc->quorum_listener, default_durable_writer_matched_cb); + if ((dc->subinfo_listener = dds_create_listener(dc)) == NULL) { + DDS_ERROR("failed to create subinfo listener\n"); + goto err_create_subinfo_listener; + } + // dds_lset_data_available(dc->subinfo_listener, default_evaluate_quorum_cb); + if ((rc = dds_set_listener(dc->com->rd_subinfo, dc->subinfo_listener)) < 0) { + DDS_ERROR("Unable to set the subinfo listener\n"); + goto err_set_listener; + } DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "start durable client thread\n"); while (!dds_triggered(dc->com->ws)) { n = dds_waitset_wait_until (dc->com->ws, wsresults, wsresultsize, timeout); @@ -570,8 +919,19 @@ static uint32_t recv_handler (void *a) } } } + dds_delete_listener(dc->subinfo_listener); + dc->subinfo_listener = NULL; + dds_delete_listener(dc->quorum_listener); + dc->quorum_listener = NULL; DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "stop durable client thread\n"); return 0; + +err_set_listener: + dds_delete_listener(dc->subinfo_listener); +err_create_subinfo_listener: + dds_delete_listener(dc->quorum_listener); +err_create_quorum_listener: + return 1; } dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_domaingv *gv) @@ -589,13 +949,11 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom * increase the refcount for this participant as well. */ ddsrt_atomic_inc32(&dc.refcount); dc.gv = gv; - /* LH: the quorum is now initialized to 0. - * if set to 1, the transient_publisher cannot terminate if it has writers that are blocked. - * This is because the writers are only unblocked when dds_durability_fini(), - * but this function never gets called because the blocking transient_publisher application - * keeps a participant alive. */ - dc.cfg.quorum = 1; - ddsrt_avl_cinit(&known_ds_td, &dc.known_ds); + dc.cfg.quorum = DEFAULT_QOURUM; /* LH: currently hardcoded set to 1, should be made configurable in future */ + dc.cfg.ident = ddsrt_strdup(DEFAULT_IDENT); + ddsrt_avl_cinit(&server_td, &dc.servers); + ddsrt_avl_cinit(&quorum_entry_td, &dc.quorum_entries); + ddsrt_avl_cinit(&handle_to_quorum_entry_td, &dc.handle_to_quorum_entries); if ((dc.com = dc_com_new(&dc, domainid, gv))== NULL) { DDS_ERROR("failed to initialize the durable client infrastructure\n"); goto err_com_new; @@ -608,9 +966,10 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom return DDS_RETCODE_OK; err_recv_thread: - dc.com = NULL; + dc_com_free(dc.com); err_com_new: - ddsrt_avl_cfree(&known_ds_td, &dc.known_ds, cleanup_known_ds); + ddsrt_avl_cfree(&quorum_entry_td, &dc.quorum_entries, cleanup_quorum_entry); + ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); return DDS_RETCODE_ERROR; } @@ -641,8 +1000,11 @@ dds_return_t dds_durability_fini (void) DDS_ERROR("failed to join the dc recv thread [%s]", dds_strretcode(rc)); } dc_com_free(dc.com); - ddsrt_avl_cfree(&known_ds_td, &dc.known_ds, cleanup_known_ds); + ddsrt_avl_cfree(&handle_to_quorum_entry_td, &dc.handle_to_quorum_entries, cleanup_handle_to_quorum_entry); + ddsrt_avl_cfree(&quorum_entry_td, &dc.quorum_entries, cleanup_quorum_entry); + ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); } + ddsrt_free(dc.cfg.ident); return DDS_RETCODE_OK; } @@ -680,22 +1042,58 @@ void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc */ dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer) { -/* temporarily disabled */ -(void)writer; -#if 0 - uint32_t nds; + /* temporarily disabled */ + (void)writer; + return DDS_RETCODE_OK; +} +dds_return_t dds_durability_new_local_writer (dds_entity_t writer) +{ + dds_durability_kind_t dkind; + dds_qos_t *qos; + dds_return_t rc = DDS_RETCODE_ERROR; + dds_guid_t wguid; + char id_str[37]; - if (writer == NULL) { - return DDS_RETCODE_PRECONDITION_NOT_MET; + /* check if the writer is a durable writer, and if so, we need to keep track of the quorum */ + assert(writer); + qos = dds_create_qos(); + if ((rc = dds_get_qos(writer, qos)) < 0) { + DDS_ERROR("failed to get qos from writer [%s]", dds_strretcode(rc)); + goto err_get_qos; } - /* quorum not reached if the number of discovered ds's is less than the quorum */ - if ((nds = (uint32_t)ddsrt_avl_ccount(&dc.known_ds)) < dc.cfg.quorum) { - printf("LH *** not enough ds\n"); - return DDS_RETCODE_PRECONDITION_NOT_MET; + if (!dds_qget_durability(qos, &dkind)) { + DDS_ERROR("failed to retrieve durability qos"); + goto err_qget_durability; } - /* */ -#endif - + if ((dkind == DDS_DURABILITY_TRANSIENT) || (dkind == DDS_DURABILITY_PERSISTENT)) { + assert(dc.quorum_listener); + /* The writer is durable, so subjected to reaching a quorum before + * it can start publishing. We set a publication_matched listener on + * the writer. Each time a matching durable data container is discovered + * the listener will be triggered, causing relevant quora to be updated + * accordingly. + * + * Note that setting a publication_matched listener implies that we do NOT + * allow that user application can set a listener on durable writers. + * This is currently a limitation. */ + if ((rc = dds_get_guid(writer, &wguid)) != DDS_RETCODE_OK) { + DDS_ERROR("failed to retrieve writer guid"); + goto err_get_guid; + } + DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "durable writer \"%s\" subject to quorum checking\n", dc_stringify_id(wguid.v, id_str)); + if ((rc = dds_set_listener(writer, dc.quorum_listener)) < 0) { + DDS_ERROR("Unable to set the quorum listener on writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); + goto err_set_listener; + } + } + dds_delete_qos(qos); return DDS_RETCODE_OK; + +err_set_listener: +err_get_guid: +err_qget_durability: +err_get_qos: + dds_delete_qos(qos); + return rc; } From 05be93c5daa834ac5af3933b7e9318d093e28f52 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Mon, 16 Oct 2023 12:04:03 +0200 Subject: [PATCH 013/207] quorum checking for durable writers Signed-off-by: TheFixer --- src/core/ddsc/src/dds_write.c | 14 ++ src/core/ddsc/src/dds_writer.c | 2 +- .../include/dds/durability/dds_durability.h | 3 + src/durability/src/dds_durability.c | 173 +++++++++++++++++- 4 files changed, 183 insertions(+), 9 deletions(-) diff --git a/src/core/ddsc/src/dds_write.c b/src/core/ddsc/src/dds_write.c index 58a21f9561..1b8e3d33fc 100644 --- a/src/core/ddsc/src/dds_write.c +++ b/src/core/ddsc/src/dds_write.c @@ -46,6 +46,19 @@ dds_return_t dds_write (dds_entity_t writer, const void *data) if (data == NULL) return DDS_RETCODE_BAD_PARAMETER; +#ifdef DDS_HAS_DURABILITY + /* determine if the quorum of durable services for the writer is fulfilled. + * + * LH: This implementation may be suboptimal, because determining whether the + * quorum is fulfilled, and the actual publication of the data is not done + * within the same writer lock. So after the quorum has been established, + * and before the data is published, the quorum could have been dropped. + * Chances for this to happen are slim, but still ... */ + if ((ret = dds_durability_wait_for_quorum(writer)) != DDS_RETCODE_OK) { + return ret; + } +#endif + if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) return ret; ret = dds_write_impl (wr, data, dds_time (), 0); @@ -822,6 +835,7 @@ dds_return_t dds_write_impl (dds_writer *wr, const void *data, dds_time_t timest // - deliver serdata // c. no psmx // - ddsi_serdata_from_sample, deliver serdata + ddsi_thread_state_awake (thrst, &wr->m_entity.m_domain->gv); struct ddsi_serdata *serdata; struct dds_loaned_sample *psmx_loan; diff --git a/src/core/ddsc/src/dds_writer.c b/src/core/ddsc/src/dds_writer.c index ab9a8ec8e9..6776154561 100644 --- a/src/core/ddsc/src/dds_writer.c +++ b/src/core/ddsc/src/dds_writer.c @@ -428,7 +428,7 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit #if DDS_HAS_DURABILITY /* quorum applies only to durable writers, initially quorum is not reached */ - wr->quorum_reached = (wqos->durability.kind <= DDS_DURABILITY_VOLATILE) ? true : false; + wr->quorum_reached = (wqos->durability.kind <= DDS_DURABILITY_TRANSIENT_LOCAL) ? true : false; #endif struct ddsi_sertype *sertype = ddsi_sertype_derive_sertype (tp->m_stype, data_representation, diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h index af8a6ab7c0..1db1572ac3 100644 --- a/src/durability/include/dds/durability/dds_durability.h +++ b/src/durability/include/dds/durability/dds_durability.h @@ -29,7 +29,10 @@ dds_return_t dds_durability_init (const dds_domainid_t domain, struct ddsi_domai dds_return_t dds_durability_fini (void); void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc); dds_return_t dds_durability_new_local_writer (dds_entity_t writer); +dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer); + dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer); + bool dds_durability_is_terminating (void); diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 2f32307361..d5fe416e65 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -20,6 +20,7 @@ #include "ddsc/dds.h" #include #include "dds__writer.h" +#include "dds/ddsi/ddsi_endpoint.h" #define DEFAULT_QOURUM 1 #define DEFAULT_IDENT "durable_support" @@ -296,7 +297,7 @@ static int create_request_partition_expression (struct com_t *com, char **reques DDS_ERROR("Failed to create request partition expression\n"); return -1; } - /* todo: perhaps add a configurable set of request partitions */ + /* todo: LH perhaps add a configurable set of request partitions */ /* set the request partition*/ *request_partition = ddsrt_strdup(req_pname); return 0; @@ -687,8 +688,35 @@ static void dc_free_partitions (uint32_t plen, char **partitions) ddsrt_free(partitions); } +static ddsi_guid_prefix_t dc_ddsi_hton_guid_prefix (ddsi_guid_prefix_t p) +{ + int i; + for (i = 0; i < 3; i++) + p.u[i] = ddsrt_toBE4u (p.u[i]); + return p; +} + +static ddsi_entityid_t dc_ddsi_hton_entityid (ddsi_entityid_t e) +{ + e.u = ddsrt_toBE4u (e.u); + return e; +} + +static ddsi_guid_t dc_ddsi_hton_guid (ddsi_guid_t g) +{ + g.prefix = dc_ddsi_hton_guid_prefix (g.prefix); + g.entityid = dc_ddsi_hton_entityid (g.entityid); + return g; +} + +static void dc_ddsiguid2guid (dds_guid_t *dds_guid, const ddsi_guid_t *ddsi_guid) +{ + ddsi_guid_t tmp; + tmp = dc_ddsi_hton_guid (*ddsi_guid); + memcpy (dds_guid, &tmp, sizeof (*dds_guid)); +} -static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer) +static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer, bool new_qe) { dds_qos_t *qos; dds_writer *wr; @@ -717,10 +745,12 @@ static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer) goto err_writer_lock; } key.tpname = ddsrt_strdup(wr->m_topic->m_name); - /* nothing to do if quorum was already reached */ - if (!wr->quorum_reached) { + if (((!wr->quorum_reached) && (new_qe)) || ((wr->quorum_reached) && (!new_qe))) { + /* the quorum was not reached and a new quorum entry has been found, or + * the quorum was reached and a quorum entry has been lost + * In both cases check if the quorum still holds */ for (i=0; i < plen && quorum_reached; i++) { - /* lookup the quorum entry and if a quorum has reached for all relevant data containers */ + /* lookup the quorum entry, and determine if a quorum has reached for all relevant data containers */ key.partition = ddsrt_strdup(partitions[i]); if ((qe = ddsrt_avl_clookup (&quorum_entry_td, &dc->quorum_entries, &key)) == NULL) { quorum_reached = false; @@ -729,7 +759,14 @@ static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer) } ddsrt_free(key.partition); } - wr->quorum_reached = quorum_reached; + if (wr->quorum_reached != quorum_reached) { + dds_guid_t guid; + char id_str[37]; + + wr->quorum_reached = quorum_reached; + dc_ddsiguid2guid(&guid, &wr->m_entity.m_guid); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for writer \"%s\" %s\n", dc_stringify_id(guid.v, id_str), quorum_reached ? "reached" : "lost"); + } } ddsrt_free(key.tpname); dds_writer_unlock (wr); @@ -741,6 +778,8 @@ static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer) return; } + + /* get a quorum counter for the builtin endoint and create a quorum counter for the endpoint */ static struct quorum_entry_t *dc_get_or_create_quorum_entry (struct dc_t *dc, dds_builtintopic_endpoint_t *ep) { @@ -865,7 +904,7 @@ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publicat dc_link_handle_to_quorum_entry(dc, ih, qe); /* a relevant data container from a durable service for this writer has become available. * Reevaluate if the quorum has been reached */ - dc_check_quorum_reached(dc, writer); + dc_check_quorum_reached(dc, writer, true); } dds_builtintopic_free_endpoint(ep); } else { @@ -876,7 +915,7 @@ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publicat qe = dc_unlink_handle_to_quorum_entry(dc, ih); /* a data container from a durable service has been lost. * reevaluate if the quorum still holds */ - dc_check_quorum_reached(dc, writer); + dc_check_quorum_reached(dc, writer, false); } err_inc_or_create_quorum_entry: err_last_subscription_handle: @@ -1097,3 +1136,121 @@ dds_return_t dds_durability_new_local_writer (dds_entity_t writer) dds_delete_qos(qos); return rc; } + +#if 0 +dds_return_t dds_durability_wait_for_quorum (dds_writer *wr) +{ + dds_return_t ret = DDS_RETCODE_ERROR; + ddsrt_mtime_t tnow = ddsrt_time_monotonic (); + ddsrt_mtime_t timeout; + dds_duration_t sleep_duration; + dds_entity_t writer; + + /* This function is called from dds_write() while the writer lock is held. + * To make sure that we temporarily release the writer lock + * while we wait until the quorum has been reached, we need access + * to the entity handle in order to acquire the lock each time + * we recheck.*/ + writer = (dds_entity_t)wr->m_entity.m_hdllink.hdl; + /* No need to check for quorum for non-durable writers */ + if (wr->m_wr->xqos->durability.kind <= DDS_DURABILITY_TRANSIENT_LOCAL) { + ret = DDS_RETCODE_OK; + goto done; + } + timeout = ddsrt_mtime_add_duration (tnow, wr->m_wr->xqos->reliability.max_blocking_time); + /* If the quorum is reached we'll immediately return DDS_RETCODE_OK. + * Note that for volatile and transient-local writers the quorum + * is but definition reached, so this function will always return with + * DDS_RETCODE_OK in those case. */ + if (wr->quorum_reached) { + ret = DDS_RETCODE_OK; + goto done; + } + /* The quorum for a durable writer is not reached. + * We will head bang until the quorum is reached. + * To prevent starvation we use a max 10ms sleep in between. + * If the quorum is reached within the max_blocking_time, + * DDS_RETCODE_OK is returned, otherwise DDS_PRECONDITION_NOT_MET + * is returned. */ + do { + sleep_duration = DDS_MSECS(10); + dds_writer_unlock(wr); + dds_sleepfor (sleep_duration); + if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) { + goto err_writer_lock; + } + tnow = ddsrt_time_monotonic (); + if (tnow.v >= timeout.v) { + ret = DDS_RETCODE_PRECONDITION_NOT_MET; + break; + } + if (wr->quorum_reached) { + ret = DDS_RETCODE_OK; + break; + } + } while (true); +done: + dds_writer_unlock(wr); +err_writer_lock: + return ret; +} +#endif + +/* Retrieve the quorum_reached value from the dds_writer that corresponds to the writer entity */ +static dds_return_t dds_durability_get_quorum_reached (dds_entity_t writer, bool *quorum_reached, ddsrt_mtime_t *timeout) +{ + dds_return_t ret = DDS_RETCODE_OK; + dds_writer *wr; + ddsrt_mtime_t tnow; + + *quorum_reached = false; + if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) { + goto err_writer_lock; + } + /* determine the timeout lazily */ + if (timeout->v == DDS_TIME_INVALID) { + tnow = ddsrt_time_monotonic (); + *timeout = ddsrt_mtime_add_duration (tnow,wr->m_wr->xqos->reliability.max_blocking_time); + } + /* retrieve quorum reached */ + *quorum_reached = wr->quorum_reached; + dds_writer_unlock(wr); +err_writer_lock: + return ret; +} + +dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) +{ + dds_return_t ret = DDS_RETCODE_ERROR; + ddsrt_mtime_t tnow = ddsrt_time_monotonic (); + ddsrt_mtime_t timeout; + dds_duration_t tdur; + bool quorum_reached; + + /* Check if the quorum for a durable writer is reached. + * If not, we will head bang until the quorum is reached. + * To prevent starvation we use a 10ms sleep in between. + * When the quorum is reached within the max_blocking_time, + * DDS_RETCODE_OK is returned, otherwise DDS_PRECONDITION_NOT_MET + * is returned. The max_blocking_time itself is retrieved lazily + * on the first call to dds_durability_get_quorum_reached(). */ + timeout.v = DDS_TIME_INVALID; + do { + if ((ret = dds_durability_get_quorum_reached(writer, &quorum_reached, &timeout)) != DDS_RETCODE_OK) { + break; + } + if (quorum_reached) { + ret = DDS_RETCODE_OK; + break; + } + tnow = ddsrt_time_monotonic(); + if (tnow.v >= timeout.v) { + ret = DDS_RETCODE_PRECONDITION_NOT_MET; + break; + } + tdur = (timeout.v -tnow.v <= DDS_MSECS(10)) ? timeout.v - tnow.v : DDS_MSECS(10); + dds_sleepfor (tdur); + } while (true); /* Note: potential but deliberate infinite loop when max_blocking_time is set to DDS_INFINITY. */ + return ret; +} + From 76fde62abeab6b85473d61155f7737641440b483 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 17 Oct 2023 10:25:01 +0200 Subject: [PATCH 014/207] Use similar idl files for durable client as for durable server Signed-off-by: TheFixer --- src/core/ddsc/src/dds_reader.c | 9 + src/durability/CMakeLists.txt | 4 +- .../include/dds/durability/dds_durability.h | 2 +- .../{client_durability.h => durablesupport.h} | 161 ++++-- src/durability/src/dds_durability.c | 49 +- .../{client_durability.c => durablesupport.c} | 546 ++++++++++++------ 6 files changed, 549 insertions(+), 222 deletions(-) rename src/durability/include/dds/durability/{client_durability.h => durablesupport.h} (67%) rename src/durability/src/{client_durability.c => durablesupport.c} (67%) diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index 390c941a80..6bd66b8e6e 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -51,6 +51,10 @@ #include "dds/ddsi/ddsi_tkmap.h" #endif +#ifdef DDS_HAS_DURABILITY +#include "dds/durability/dds_durability.h" +#endif + DECL_ENTITY_LOCK_UNLOCK (dds_reader) #define DDS_READER_STATUS_MASK \ @@ -765,6 +769,11 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe dds_topic_allow_set_qos (tp); dds_topic_unpin (tp); dds_subscriber_unlock (sub); + +#ifdef DDS_HAS_DURABILITY + dds_durability_new_local_reader(reader, rhc); +#endif + return reader; err_psmx_endpoint_setcb: diff --git a/src/durability/CMakeLists.txt b/src/durability/CMakeLists.txt index aec416df73..434c38867a 100644 --- a/src/durability/CMakeLists.txt +++ b/src/durability/CMakeLists.txt @@ -21,11 +21,11 @@ target_include_directories( set(headers "${source_dir}/include/dds/durability/dds_durability.h" - "${source_dir}/include/dds/durability/client_durability.h") + "${source_dir}/include/dds/durability/durablesupport.h") set(sources "${source_dir}/src/dds_durability.c" - "${source_dir}/src/client_durability.c") + "${source_dir}/src/durablesupport.c") target_sources(durability INTERFACE ${headers} ${sources}) diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h index 1db1572ac3..08d34d746d 100644 --- a/src/durability/include/dds/durability/dds_durability.h +++ b/src/durability/include/dds/durability/dds_durability.h @@ -27,7 +27,7 @@ typedef int (*plugin_finalize)(void *context); dds_return_t dds_durability_init (const dds_domainid_t domain, struct ddsi_domaingv *gv); dds_return_t dds_durability_fini (void); -void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc); +dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc); dds_return_t dds_durability_new_local_writer (dds_entity_t writer); dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer); diff --git a/src/durability/include/dds/durability/client_durability.h b/src/durability/include/dds/durability/durablesupport.h similarity index 67% rename from src/durability/include/dds/durability/client_durability.h rename to src/durability/include/dds/durability/durablesupport.h index 5f2649c6b3..1318821ee9 100644 --- a/src/durability/include/dds/durability/client_durability.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -8,8 +8,8 @@ in idlc_generate(). *****************************************************************/ -#ifndef CLIENT_DURABILITY_H -#define CLIENT_DURABILITY_H +#ifndef DURABLE_SUPPORT_H +#define DURABLE_SUPPORT_H #include "dds/ddsc/dds_public_impl.h" @@ -52,52 +52,92 @@ extern const dds_topic_descriptor_t DurableSupport_status_desc; #define DurableSupport_status_free(d,o) \ dds_sample_free ((d), &DurableSupport_status_desc, (o)) -typedef struct DurableSupport_request_id_t +typedef struct DurableSupport_range { - DurableSupport_id_t client; - uint64_t seq; -} DurableSupport_request_id_t; + uint64_t lb; + uint64_t ub; +} DurableSupport_range; -extern const dds_topic_descriptor_t DurableSupport_request_id_t_desc; +#ifndef DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED +#define DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED +typedef struct dds_sequence_DurableSupport_range +{ + uint32_t _maximum; + uint32_t _length; + struct DurableSupport_range *_buffer; + bool _release; +} dds_sequence_DurableSupport_range; -#define DurableSupport_request_id_t__alloc() \ -((DurableSupport_request_id_t*) dds_alloc (sizeof (DurableSupport_request_id_t))); +#define dds_sequence_DurableSupport_range__alloc() \ +((dds_sequence_DurableSupport_range*) dds_alloc (sizeof (dds_sequence_DurableSupport_range))); -#define DurableSupport_request_id_t_free(d,o) \ -dds_sample_free ((d), &DurableSupport_request_id_t_desc, (o)) +#define dds_sequence_DurableSupport_range_allocbuf(l) \ +((struct DurableSupport_range *) dds_alloc ((l) * sizeof (struct DurableSupport_range))) +#endif /* DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED */ -#ifndef DDS_SEQUENCE_STRING_DEFINED -#define DDS_SEQUENCE_STRING_DEFINED -typedef struct dds_sequence_string +typedef struct DurableSupport_writer +{ + DurableSupport_id_t id; + uint32_t flags; + dds_sequence_DurableSupport_range ranges; +} DurableSupport_writer; + +#ifndef DDS_SEQUENCE_DURABLESUPPORT_WRITER_DEFINED +#define DDS_SEQUENCE_DURABLESUPPORT_WRITER_DEFINED +typedef struct dds_sequence_DurableSupport_writer { uint32_t _maximum; uint32_t _length; - char **_buffer; + struct DurableSupport_writer *_buffer; bool _release; -} dds_sequence_string; +} dds_sequence_DurableSupport_writer; -#define dds_sequence_string__alloc() \ -((dds_sequence_string*) dds_alloc (sizeof (dds_sequence_string))); +#define dds_sequence_DurableSupport_writer__alloc() \ +((dds_sequence_DurableSupport_writer*) dds_alloc (sizeof (dds_sequence_DurableSupport_writer))); -#define dds_sequence_string_allocbuf(l) \ -((char **) dds_alloc ((l) * sizeof (char*))) -#endif /* DDS_SEQUENCE_STRING_DEFINED */ +#define dds_sequence_DurableSupport_writer_allocbuf(l) \ +((struct DurableSupport_writer *) dds_alloc ((l) * sizeof (struct DurableSupport_writer))) +#endif /* DDS_SEQUENCE_DURABLESUPPORT_WRITER_DEFINED */ -typedef struct DurableSupport_request +typedef struct DurableSupport_set { - struct DurableSupport_request_id_t requestid; char * partition; char * tpname; - dds_sequence_string alignment_partition; -} DurableSupport_request; + uint32_t flags; + dds_sequence_DurableSupport_writer writers; +} DurableSupport_set; -extern const dds_topic_descriptor_t DurableSupport_request_desc; +#ifndef DDS_SEQUENCE_DURABLESUPPORT_SET_DEFINED +#define DDS_SEQUENCE_DURABLESUPPORT_SET_DEFINED +typedef struct dds_sequence_DurableSupport_set +{ + uint32_t _maximum; + uint32_t _length; + struct DurableSupport_set *_buffer; + bool _release; +} dds_sequence_DurableSupport_set; -#define DurableSupport_request__alloc() \ -((DurableSupport_request*) dds_alloc (sizeof (DurableSupport_request))); +#define dds_sequence_DurableSupport_set__alloc() \ +((dds_sequence_DurableSupport_set*) dds_alloc (sizeof (dds_sequence_DurableSupport_set))); -#define DurableSupport_request_free(d,o) \ -dds_sample_free ((d), &DurableSupport_request_desc, (o)) +#define dds_sequence_DurableSupport_set_allocbuf(l) \ +((struct DurableSupport_set *) dds_alloc ((l) * sizeof (struct DurableSupport_set))) +#endif /* DDS_SEQUENCE_DURABLESUPPORT_SET_DEFINED */ + +typedef struct DurableSupport_state +{ + DurableSupport_id_t id; + char * name; + dds_sequence_DurableSupport_set sets; +} DurableSupport_state; + +extern const dds_topic_descriptor_t DurableSupport_state_desc; + +#define DurableSupport_state__alloc() \ +((DurableSupport_state*) dds_alloc (sizeof (DurableSupport_state))); + +#define DurableSupport_state_free(d,o) \ +dds_sample_free ((d), &DurableSupport_state_desc, (o)) #define DurableSupport_BEADTYPE_SESSION 1 #define DurableSupport_BEADTYPE_SET 2 @@ -106,7 +146,6 @@ dds_sample_free ((d), &DurableSupport_request_desc, (o)) #define DurableSupport_SESSION_KIND_START 1 #define DurableSupport_SESSION_KIND_END 2 #define DurableSupport_SESSION_KIND_ABORT 3 - typedef struct DurableSupport_session_t { DurableSupport_session_kind_t kind; @@ -138,12 +177,6 @@ typedef struct DurableSupport_set_t dds_sequence_DurableSupport_id_t addressees; } DurableSupport_set_t; -typedef struct DurableSupport_range -{ - uint64_t lb; - uint64_t ub; -} DurableSupport_range; - #ifndef DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED #define DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED typedef struct dds_sequence_DurableSupport_range @@ -216,8 +249,60 @@ extern const dds_topic_descriptor_t DurableSupport_bead_desc; #define DurableSupport_bead_free(d,o) \ dds_sample_free ((d), &DurableSupport_bead_desc, (o)) +typedef int64_t DurableSupport_duration_t; + +#define DurableSupport_duration_t__alloc() \ +((DurableSupport_duration_t*) dds_alloc (sizeof (DurableSupport_duration_t))); + +typedef struct DurableSupport_request_id_t +{ + DurableSupport_id_t client; + uint64_t seq; +} DurableSupport_request_id_t; + +extern const dds_topic_descriptor_t DurableSupport_request_id_t_desc; + +#define DurableSupport_request_id_t__alloc() \ +((DurableSupport_request_id_t*) dds_alloc (sizeof (DurableSupport_request_id_t))); + +#define DurableSupport_request_id_t_free(d,o) \ +dds_sample_free ((d), &DurableSupport_request_id_t_desc, (o)) + +#ifndef DDS_SEQUENCE_STRING_DEFINED +#define DDS_SEQUENCE_STRING_DEFINED +typedef struct dds_sequence_string +{ + uint32_t _maximum; + uint32_t _length; + char **_buffer; + bool _release; +} dds_sequence_string; + +#define dds_sequence_string__alloc() \ +((dds_sequence_string*) dds_alloc (sizeof (dds_sequence_string))); + +#define dds_sequence_string_allocbuf(l) \ +((char **) dds_alloc ((l) * sizeof (char*))) +#endif /* DDS_SEQUENCE_STRING_DEFINED */ + +typedef struct DurableSupport_request +{ + struct DurableSupport_request_id_t requestid; + dds_sequence_string partitions; + char * tpname; + DurableSupport_duration_t timeout; +} DurableSupport_request; + +extern const dds_topic_descriptor_t DurableSupport_request_desc; + +#define DurableSupport_request__alloc() \ +((DurableSupport_request*) dds_alloc (sizeof (DurableSupport_request))); + +#define DurableSupport_request_free(d,o) \ +dds_sample_free ((d), &DurableSupport_request_desc, (o)) + #ifdef __cplusplus } #endif -#endif /* CLIENT_DURABILITY_H */ +#endif /* DURABLE_SUPPORT_H */ diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index d5fe416e65..66778e282b 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -11,7 +11,7 @@ */ #include "dds/ddsi/ddsi_domaingv.h" #include "dds/durability/dds_durability.h" -#include "dds/durability/client_durability.h" +#include "dds/durability/durablesupport.h" #include "dds/ddsrt/atomics.h" #include "dds/ddsrt/string.h" #include "dds/ddsrt/heap.h" @@ -157,6 +157,8 @@ struct com_t { */ struct dc_t { struct { + DurableSupport_id_t id; /* the id of this client */ + char id_str[37]; /* string representation of the service id */ char *request_partition; /* partition to send requests too; by default same as */ uint32_t quorum; /*quorum of durable services needed to unblock durable writers */ char *ident; /* ds identification */ @@ -292,7 +294,7 @@ static int create_request_partition_expression (struct com_t *com, char **reques char req_pname[1024] = { 0 }; int result = 0; - (void)com; + (void)com; if ((result = get_host_specific_partition_name(req_pname, 1024)) < 0) { DDS_ERROR("Failed to create request partition expression\n"); return -1; @@ -317,6 +319,7 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, unsigned nps; dds_return_t ret; char *request_partition = NULL; + dds_guid_t guid; (void)dc; if ((com = (struct com_t *)ddsrt_malloc(sizeof(struct com_t))) == NULL) { @@ -328,6 +331,15 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc participant [%s]\n", dds_strretcode(-com->participant)); goto err_create_participant; } + /* use the participant guid as the identification of this client */ + if ((ret = dds_get_guid(com->participant, &guid)) != DDS_RETCODE_OK) { + DDS_ERROR("failed to get dc participant guid [%s]\n", dds_strretcode(-ret)); + goto err_get_guid; + } + /* get and cache the id of the participant */ + memcpy(dc->cfg.id, guid.v, 16); + (void)dc_stringify_id(dc->cfg.id, dc->cfg.id_str); + /* create subscriber */ if ((status_sqos = dds_create_qos()) == NULL) { DDS_ERROR("failed to create the dc status subscriber qos\n"); goto err_alloc_status_sqos; @@ -537,6 +549,7 @@ err_response_subscriber : dds_free(bufcopy1); dds_free(ps1); err_alloc_status_sqos: +err_get_guid: dds_delete(com->participant); err_create_participant: ddsrt_free(com); @@ -554,6 +567,25 @@ static void dc_com_free (struct com_t *com) return; } +static dds_return_t dc_com_send_request (struct com_t *com, dds_entity_t reader) +{ + /* check for publication_matched() on the dc_request writer tomake sure that the request arrives */ + /* create a request */ + /* set the request on the pending liust */ + /* send the request */ + + /* note: we allow doing a request for volatile readers */ + DurableSupport_request *request; + + request = DurableSupport_request__alloc(); + memcpy(request->requestid.client, dc.cfg.id, 16); + DurableSupport_request_free(request, DDS_FREE_ALL); + + (void)com; + (void)reader; + return DDS_RETCODE_OK; +} + static void dc_server_lost (struct dc_t *dc, DurableSupport_status *status) { struct server_t *server; @@ -985,9 +1017,12 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom } /* This is the first participant, so let's create a durable client (dc). * The dc will also create a new participant, therefore - * increase the refcount for this participant as well. */ + * increase the refcount for this participant as well. + * The guid of the participant for client durability will be used + * to identify this client. */ ddsrt_atomic_inc32(&dc.refcount); dc.gv = gv; + /* Note: dc.cfg.id will be set once we create the participant in dc_com_new() */ dc.cfg.quorum = DEFAULT_QOURUM; /* LH: currently hardcoded set to 1, should be made configurable in future */ dc.cfg.ident = ddsrt_strdup(DEFAULT_IDENT); ddsrt_avl_cinit(&server_td, &dc.servers); @@ -1052,14 +1087,18 @@ bool dds_durability_is_terminating (void) return (ddsrt_atomic_ld32(&dc.termflag) > 0); } -void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc) +dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc) { /* create the administration to store transient data */ /* create a durability reader that sucks and stores it in the store */ + /* send a request */ + + dc_com_send_request (dc.com, reader); + (void)rhc; (void)reader; - return; + return DDS_RETCODE_OK;; } /* This function checks if the writer has reached the quorum of matching durable containers diff --git a/src/durability/src/client_durability.c b/src/durability/src/durablesupport.c similarity index 67% rename from src/durability/src/client_durability.c rename to src/durability/src/durablesupport.c index ea5429a4d8..4a19d54e8f 100644 --- a/src/durability/src/client_durability.c +++ b/src/durability/src/durablesupport.c @@ -1,14 +1,12 @@ /**************************************************************** - IMPORTANT: - - The file contains the definitions for the client durability related topics. - This file is partially copied from the output generated by durabledupport.idl - because we cannot generate code from an idl file due to cyclic dependencies - in idlc_generate(). + Generated by Eclipse Cyclone DDS IDL to C Translator + File name: /home/lex/Repositories/TheFixer/durable_support/build/src/durablesupport.c + Source: /home/lex/Repositories/TheFixer/durable_support/src/durablesupport.idl + Cyclone DDS: V0.11.0 *****************************************************************/ -#include "../include/dds/durability/client_durability.h" +#include "../include/dds/durability/durablesupport.h" static const uint32_t DurableSupport_status_ops [] = { @@ -18,7 +16,7 @@ static const uint32_t DurableSupport_status_ops [] = DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_status, hostname), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_status, name), DDS_OP_RTS, - + /* key: id */ DDS_OP_KOF | 1, 1u /* order: 0 */ }; @@ -95,200 +93,183 @@ const dds_topic_descriptor_t DurableSupport_status_desc = .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_status, .sz = TYPE_MAP_CDR_SZ_DurableSupport_status } }; -static const uint32_t DurableSupport_request_id_t_ops [] = +static const uint32_t DurableSupport_state_ops [] = { - /* request_id_t */ + /* state */ DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), - DDS_OP_RTS -}; - -/* Type Information: - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] (#deps: 1) - - [MINIMAL 43f53a2be35b432cc735e9431a89] - [COMPLETE 852fffc913b7ee54aadae7a1859a] (#deps: 1) - - [COMPLETE aca4d5a256d39713924333e85c6d] -*/ -#define TYPE_INFO_CDR_DurableSupport_request_id_t (const unsigned char []){ \ - 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, \ - 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, \ - 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x40, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_request_id_t 148u -#define TYPE_MAP_CDR_DurableSupport_request_id_t (const unsigned char []){ \ - 0x8a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ - 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ - 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, \ - 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, \ - 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ - 0xe4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ - 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ - 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ - 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0xf1, \ - 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_request_id_t 444u -const dds_topic_descriptor_t DurableSupport_request_id_t_desc = -{ - .m_size = sizeof (DurableSupport_request_id_t), - .m_align = dds_alignof (DurableSupport_request_id_t), - .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 0u, - .m_typename = "DurableSupport::request_id_t", - .m_keys = NULL, - .m_nops = 4, - .m_ops = DurableSupport_request_id_t_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request_id_t, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request_id_t }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request_id_t, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request_id_t } -}; + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_state, id), 16u, + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_state, name), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_state, sets), sizeof (DurableSupport_set), (4u << 16u) + 5u /* set */, + DDS_OP_RTS, -static const uint32_t DurableSupport_request_ops [] = -{ - /* request */ + /* set */ DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_EXT, offsetof (DurableSupport_request, requestid), (3u << 16u) + 10u /* request_id_t */, - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, partition), - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STR, offsetof (DurableSupport_request, alignment_partition), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, partition), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, tpname), + DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_set, flags), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_set, writers), sizeof (DurableSupport_writer), (4u << 16u) + 5u /* writer */, DDS_OP_RTS, - /* request_id_t */ + /* writer */ DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_writer, id), 16u, + DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_writer, flags), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_writer, ranges), sizeof (DurableSupport_range), (4u << 16u) + 5u /* range */, DDS_OP_RTS, - /* key: requestid.client */ - DDS_OP_KOF | 2, 1u /* order: 0 */, 1u /* order: 0 */, - - /* key: requestid.seq */ - DDS_OP_KOF | 2, 1u /* order: 0 */, 4u /* order: 1 */ + /* range */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, lb), + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, ub), + DDS_OP_RTS, + + /* key: id */ + DDS_OP_KOF | 1, 1u /* order: 0 */ }; -static const dds_key_descriptor_t DurableSupport_request_keys[2] = +static const dds_key_descriptor_t DurableSupport_state_keys[1] = { - { "requestid.client", 18, 0 }, - { "requestid.seq", 21, 1 } + { "id", 40, 0 } }; /* Type Information: - [MINIMAL 54af0d70dd88f2a169924dd8b880] (#deps: 2) - - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] + [MINIMAL 29c25c35d5510f091b9d2951e87d] (#deps: 4) - [MINIMAL 43f53a2be35b432cc735e9431a89] - [COMPLETE 77ef4931b703e23e4f8f33c76508] (#deps: 2) - - [COMPLETE 852fffc913b7ee54aadae7a1859a] + - [MINIMAL 4c34d21c8ec2020e687b75390553] + - [MINIMAL 7b73d4df4f265b2da8c52f3c3a8e] + - [MINIMAL ef038b7b19448c9ce27fa1c268cd] + [COMPLETE a4dc41b7052cef5bfdb62c313d77] (#deps: 4) - [COMPLETE aca4d5a256d39713924333e85c6d] + - [COMPLETE ec0a17f45bf4c4917bb5db3c5b18] + - [COMPLETE 3be64a4fbc92a7b2f612cbd52a3a] + - [COMPLETE d8d43c2295c185a21b9591a7126c] */ -#define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ - 0xc0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x54, 0xaf, 0x0d, 0x70, 0xdd, 0x88, 0xf2, 0xa1, 0x69, 0x92, 0x4d, \ - 0xd8, 0xb8, 0x80, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ - 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x77, 0xef, 0x49, 0x31, 0xb7, 0x03, 0xe2, 0x3e, 0x4f, 0x8f, 0x33, \ - 0xc7, 0x65, 0x08, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ - 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x40, 0x00, 0x00, 0x00\ +#define TYPE_INFO_CDR_DurableSupport_state (const unsigned char []){ \ + 0x20, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x29, 0xc2, 0x5c, 0x35, 0xd5, 0x51, 0x0f, 0x09, 0x1b, 0x9d, 0x29, \ + 0x51, 0xe8, 0x7d, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, 0x05, 0x53, 0x00, \ + 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, \ + 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, \ + 0x37, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa4, 0xdc, 0x41, 0xb7, 0x05, 0x2c, 0xef, 0x5b, 0xfd, 0xb6, 0x2c, \ + 0x31, 0x3d, 0x77, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xec, 0x0a, 0x17, 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, 0x3c, 0x5b, 0x18, 0x00, \ + 0xae, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, \ + 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, \ + 0x61, 0x00, 0x00, 0x00\ } -#define TYPE_INFO_CDR_SZ_DurableSupport_request 196u -#define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ - 0x06, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0x54, 0xaf, 0x0d, 0x70, 0xdd, 0x88, 0xf2, \ - 0xa1, 0x69, 0x92, 0x4d, 0xd8, 0xb8, 0x80, 0x00, 0x69, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, \ - 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x3c, 0xb0, 0x21, 0x74, 0x00, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ - 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ - 0x11, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, \ - 0x00, 0xd8, 0xc7, 0x47, 0x1e, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, \ - 0x0f, 0xd5, 0x22, 0xa4, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, \ - 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, \ - 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ - 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xbc, 0x01, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0xf2, 0x77, 0xef, 0x49, 0x31, 0xb7, 0x03, 0xe2, 0x3e, 0x4f, 0x8f, 0x33, \ - 0xc7, 0x65, 0x08, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x00, \ - 0x96, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, \ - 0x9a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, \ - 0x64, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, \ - 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, \ - 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x02, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ +#define TYPE_INFO_CDR_SZ_DurableSupport_state 292u +#define TYPE_MAP_CDR_DurableSupport_state (const unsigned char []){ \ + 0xef, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf1, 0x29, 0xc2, 0x5c, 0x35, 0xd5, 0x51, 0x0f, \ + 0x09, 0x1b, 0x9d, 0x29, 0x51, 0xe8, 0x7d, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0xb0, 0x68, 0x93, 0x1c, \ + 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ + 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, 0x05, 0x53, 0x17, 0x8d, \ + 0x51, 0x02, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, \ + 0x89, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x10, 0x02, 0xf1, 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, 0x05, \ + 0x53, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x0b, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, \ + 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0xbf, 0x63, 0x9b, 0x5f, 0xf1, 0x7b, \ + 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0x00, 0x00, 0x00, \ + 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x56, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, \ + 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, \ + 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x8d, 0x81, 0x02, 0xfb, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, \ + 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x26, \ + 0x40, 0x3e, 0xc6, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x1c, \ + 0x78, 0xb4, 0x86, 0x00, 0xe5, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf2, 0xa4, 0xdc, 0x41, \ + 0xb7, 0x05, 0x2c, 0xef, 0x5b, 0xfd, 0xb6, 0x2c, 0x31, 0x3d, 0x77, 0x00, 0x9b, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x02, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ - 0x46, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0x73, 0x74, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x70, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, \ + 0x27, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, \ + 0xec, 0x0a, 0x17, 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, 0x3c, 0x5b, 0x18, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, \ + 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0xf2, 0x77, 0xef, 0x49, 0x31, 0xb7, 0x03, 0xe2, 0x3e, 0x4f, 0x8f, 0x33, \ - 0xc7, 0x65, 0x08, 0xf1, 0x54, 0xaf, 0x0d, 0x70, 0xdd, 0x88, 0xf2, 0xa1, 0x69, 0x92, 0x4d, 0xd8, \ - 0xb8, 0x80, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, \ - 0x9a, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, \ - 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0xec, 0x0a, 0x17, \ + 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, 0x3c, 0x5b, 0x18, 0x00, 0xaa, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x73, 0x65, 0x74, 0x00, 0x82, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, \ + 0xbc, 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, \ + 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, \ + 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ + 0x29, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, \ + 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, \ + 0x07, 0x00, 0x00, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, \ + 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x5d, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x6c, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x9a, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf2, 0xa4, 0xdc, 0x41, 0xb7, 0x05, 0x2c, 0xef, \ + 0x5b, 0xfd, 0xb6, 0x2c, 0x31, 0x3d, 0x77, 0xf1, 0x29, 0xc2, 0x5c, 0x35, 0xd5, 0x51, 0x0f, 0x09, \ + 0x1b, 0x9d, 0x29, 0x51, 0xe8, 0x7d, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, \ + 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0xec, 0x0a, 0x17, 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, \ + 0x3c, 0x5b, 0x18, 0xf1, 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, \ + 0x05, 0x53, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, \ + 0x3a, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, \ + 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, \ + 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_request 814u -const dds_topic_descriptor_t DurableSupport_request_desc = +#define TYPE_MAP_CDR_SZ_DurableSupport_state 1406u +const dds_topic_descriptor_t DurableSupport_state_desc = { - .m_size = sizeof (DurableSupport_request), - .m_align = dds_alignof (DurableSupport_request), + .m_size = sizeof (DurableSupport_state), + .m_align = dds_alignof (DurableSupport_state), .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 2u, - .m_typename = "DurableSupport::request", - .m_keys = DurableSupport_request_keys, - .m_nops = 10, - .m_ops = DurableSupport_request_ops, + .m_nkeys = 1u, + .m_typename = "DurableSupport::state", + .m_keys = DurableSupport_state_keys, + .m_nops = 20, + .m_ops = DurableSupport_state_ops, .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request } + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_state, .sz = TYPE_INFO_CDR_SZ_DurableSupport_state }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_state, .sz = TYPE_MAP_CDR_SZ_DurableSupport_state } }; static const uint32_t DurableSupport_bead_ops [] = @@ -341,7 +322,7 @@ static const uint32_t DurableSupport_bead_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_data_t, blob), DDS_OP_RTS, - + /* key: id */ DDS_OP_KOF | 1, 1u /* order: 0 */ }; @@ -604,3 +585,216 @@ const dds_topic_descriptor_t DurableSupport_bead_desc = .type_information = { .data = TYPE_INFO_CDR_DurableSupport_bead, .sz = TYPE_INFO_CDR_SZ_DurableSupport_bead }, .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_bead, .sz = TYPE_MAP_CDR_SZ_DurableSupport_bead } }; + +static const uint32_t DurableSupport_request_id_t_ops [] = +{ + /* request_id_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), + DDS_OP_RTS +}; + +/* Type Information: + [MINIMAL 28dabddcc42d4b6a3d640fd522a4] (#deps: 1) + - [MINIMAL 43f53a2be35b432cc735e9431a89] + [COMPLETE 852fffc913b7ee54aadae7a1859a] (#deps: 1) + - [COMPLETE aca4d5a256d39713924333e85c6d] +*/ +#define TYPE_INFO_CDR_DurableSupport_request_id_t (const unsigned char []){ \ + 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, \ + 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, \ + 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ + 0x40, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_request_id_t 148u +#define TYPE_MAP_CDR_DurableSupport_request_id_t (const unsigned char []){ \ + 0x8a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ + 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, \ + 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, \ + 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ + 0xe4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ + 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ + 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0xf1, \ + 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_request_id_t 444u +const dds_topic_descriptor_t DurableSupport_request_id_t_desc = +{ + .m_size = sizeof (DurableSupport_request_id_t), + .m_align = dds_alignof (DurableSupport_request_id_t), + .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 0u, + .m_typename = "DurableSupport::request_id_t", + .m_keys = NULL, + .m_nops = 4, + .m_ops = DurableSupport_request_id_t_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request_id_t, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request_id_t }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request_id_t, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request_id_t } +}; + +static const uint32_t DurableSupport_request_ops [] = +{ + /* request */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_EXT, offsetof (DurableSupport_request, requestid), (3u << 16u) + 10u /* request_id_t */, + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STR, offsetof (DurableSupport_request, partitions), + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), + DDS_OP_ADR | DDS_OP_TYPE_8BY | DDS_OP_FLAG_SGN, offsetof (DurableSupport_request, timeout), + DDS_OP_RTS, + + /* request_id_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), + DDS_OP_RTS, + + /* key: requestid.client */ + DDS_OP_KOF | 2, 1u /* order: 0 */, 1u /* order: 0 */, + + /* key: requestid.seq */ + DDS_OP_KOF | 2, 1u /* order: 0 */, 4u /* order: 1 */ +}; + +static const dds_key_descriptor_t DurableSupport_request_keys[2] = +{ + { "requestid.client", 18, 0 }, + { "requestid.seq", 21, 1 } +}; + +/* Type Information: + [MINIMAL 20fb854c344bb02af8430115a676] (#deps: 3) + - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] + - [MINIMAL 43f53a2be35b432cc735e9431a89] + - [MINIMAL 84ce9c3d894c1483f859c00d5927] + [COMPLETE 2de91793545eff71a07b9e15f413] (#deps: 3) + - [COMPLETE 852fffc913b7ee54aadae7a1859a] + - [COMPLETE aca4d5a256d39713924333e85c6d] + - [COMPLETE 023df3bd21223779cd1936cef928] +*/ +#define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ + 0xf0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x20, 0xfb, 0x85, 0x4c, 0x34, 0x4b, 0xb0, 0x2a, 0xf8, 0x43, 0x01, \ + 0x15, 0xa6, 0x76, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ + 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, \ + 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x2d, 0xe9, 0x17, \ + 0x93, 0x54, 0x5e, 0xff, 0x71, 0xa0, 0x7b, 0x9e, 0x15, 0xf4, 0x13, 0x00, 0xce, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, \ + 0x7e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ + 0x39, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_request 244u +#define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ + 0x3b, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf1, 0x20, 0xfb, 0x85, 0x4c, 0x34, 0x4b, 0xb0, \ + 0x2a, 0xf8, 0x43, 0x01, 0x15, 0xa6, 0x76, 0x00, 0x79, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, \ + 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x3c, 0xb0, 0x21, 0x74, 0x00, 0x00, 0x00, \ + 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, \ + 0x00, 0xae, 0xa4, 0x67, 0xe1, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, \ + 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, \ + 0x0f, 0xd5, 0x22, 0xa4, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, \ + 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, \ + 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ + 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ + 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, \ + 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ + 0x0d, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf2, 0x2d, 0xe9, 0x17, 0x93, 0x54, 0x5e, 0xff, \ + 0x71, 0xa0, 0x7b, 0x9e, 0x15, 0xf4, 0x13, 0x00, 0xca, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ + 0x65, 0x73, 0x74, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, \ + 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x72, 0x65, 0x71, 0x75, \ + 0x65, 0x73, 0x74, 0x69, 0x64, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, \ + 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, \ + 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, \ + 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ + 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, \ + 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x75, 0x72, 0x61, \ + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf2, 0x2d, 0xe9, 0x17, \ + 0x93, 0x54, 0x5e, 0xff, 0x71, 0xa0, 0x7b, 0x9e, 0x15, 0xf4, 0x13, 0xf1, 0x20, 0xfb, 0x85, 0x4c, \ + 0x34, 0x4b, 0xb0, 0x2a, 0xf8, 0x43, 0x01, 0x15, 0xa6, 0x76, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, \ + 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, \ + 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, \ + 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, \ + 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, \ + 0xc0, 0x0d, 0x59, 0x27\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_request 980u +const dds_topic_descriptor_t DurableSupport_request_desc = +{ + .m_size = sizeof (DurableSupport_request), + .m_align = dds_alignof (DurableSupport_request), + .m_flagset = DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 2u, + .m_typename = "DurableSupport::request", + .m_keys = DurableSupport_request_keys, + .m_nops = 10, + .m_ops = DurableSupport_request_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request } +}; + From 1cae5ab1dd3128ab2770eba5d59364bd316549c0 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 20 Oct 2023 08:45:20 +0200 Subject: [PATCH 015/207] Initialize quorum_reached variable correctly in case quorum threshold is set to 0 (even though we might want to forbid it as an invalid configuration). Signed-off-by: TheFixer --- src/core/ddsc/src/dds_writer.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/core/ddsc/src/dds_writer.c b/src/core/ddsc/src/dds_writer.c index 6776154561..18f4a63e80 100644 --- a/src/core/ddsc/src/dds_writer.c +++ b/src/core/ddsc/src/dds_writer.c @@ -427,8 +427,16 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit goto err_pipe_open; #if DDS_HAS_DURABILITY - /* quorum applies only to durable writers, initially quorum is not reached */ - wr->quorum_reached = (wqos->durability.kind <= DDS_DURABILITY_TRANSIENT_LOCAL) ? true : false; + /* quorum applies only to durable writers. + * By default quorum reached for volatile and transient-local writers + * For durable writer the quorum is initially reached when quorum threshold == 0 + * (but we'll likely prohibit this case as an invalid configuration because + * it may lead to eventual inconsistencies). */ + uint32_t quorum = dds_durability_get_quorum(); + wr->quorum_reached = true; + if (wqos->durability.kind >= DDS_DURABILITY_TRANSIENT) { + wr->quorum_reached = (quorum == 0); + } #endif struct ddsi_sertype *sertype = ddsi_sertype_derive_sertype (tp->m_stype, data_representation, From 8f31f5911beb156d0a52464b904e8907ce006c51 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 20 Oct 2023 09:24:50 +0200 Subject: [PATCH 016/207] Use dds_get_matched_subscriptions() in dc_check_quorum_reched() to determine if a quorum is reached Signed-off-by: TheFixer --- .../include/dds/durability/dds_durability.h | 2 +- src/durability/src/dds_durability.c | 859 ++++++++---------- 2 files changed, 386 insertions(+), 475 deletions(-) diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h index 08d34d746d..37294cd825 100644 --- a/src/durability/include/dds/durability/dds_durability.h +++ b/src/durability/include/dds/durability/dds_durability.h @@ -27,10 +27,10 @@ typedef int (*plugin_finalize)(void *context); dds_return_t dds_durability_init (const dds_domainid_t domain, struct ddsi_domaingv *gv); dds_return_t dds_durability_fini (void); +uint32_t dds_durability_get_quorum (void); dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc); dds_return_t dds_durability_new_local_writer (dds_entity_t writer); dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer); - dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer); bool dds_durability_is_terminating (void); diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 66778e282b..321cdc1fce 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -21,6 +21,7 @@ #include #include "dds__writer.h" #include "dds/ddsi/ddsi_endpoint.h" +#include "dds/ddsrt/avl.h" #define DEFAULT_QOURUM 1 #define DEFAULT_IDENT "durable_support" @@ -37,7 +38,6 @@ static char *dc_stringify_id(const DurableSupport_id_t id, char *buf) return buf; } - struct server_t { ddsrt_avl_node_t node; DurableSupport_id_t id; /* id key */ @@ -61,71 +61,6 @@ static void cleanup_server (void *n) static const ddsrt_avl_ctreedef_t server_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct server_t, node), offsetof (struct server_t, id), cmp_server, 0); - -struct quorum_entry_key_t { - char *partition; /* the partition of the data container; should be a singleton */ - char *tpname; /* topic name */ - /* LH: todo: add a type id to support xtypes */ -}; - -struct quorum_entry_t { - ddsrt_avl_node_t node; - struct quorum_entry_key_t key; - uint32_t cnt; /* the number of data containers found for this partition/topic combination */ -}; - -static int cmp_quorum_entry (const void *a, const void *b) -{ - struct quorum_entry_key_t *qk1 = (struct quorum_entry_key_t *)a; - struct quorum_entry_key_t *qk2 = (struct quorum_entry_key_t *)b; - int cmp; - - if ((cmp = strcmp(qk1->partition, qk2->partition)) < 0) { - return -1; - } else if (cmp > 0) { - return 1; - } else if ((cmp = strcmp(qk1->tpname, qk2->tpname)) < 0) { - return -1; - } else if (cmp > 0) { - return 1; - } else { - return 0; - } -} - -static void cleanup_quorum_entry (void *n) -{ - struct quorum_entry_t *qe = (struct quorum_entry_t *)n; - ddsrt_free(qe->key.partition); - ddsrt_free(qe->key.tpname); - ddsrt_free(qe); -} - -static const ddsrt_avl_ctreedef_t quorum_entry_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct quorum_entry_t, node), offsetof (struct quorum_entry_t, key), cmp_quorum_entry, 0); - -struct handle_to_quorum_entry_t { - ddsrt_avl_node_t node; - dds_instance_handle_t ih; - struct quorum_entry_t *qe_ref; /* reference to quorum entry */ -}; - -static int cmp_instance_handle (const void *a, const void *b) -{ - dds_instance_handle_t *ih1 = (dds_instance_handle_t *)a; - dds_instance_handle_t *ih2 = (dds_instance_handle_t *)b; - - return (*ih1 < *ih2) ? -1 : ((*ih1 > *ih2) ? 1 : 0); -} - -static void cleanup_handle_to_quorum_entry (void *n) -{ - struct handle_to_quorum_entry_t *hqe = (struct handle_to_quorum_entry_t *)n; - - ddsrt_free(hqe); -} - -static const ddsrt_avl_ctreedef_t handle_to_quorum_entry_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct handle_to_quorum_entry_t, node), offsetof (struct handle_to_quorum_entry_t, ih), cmp_instance_handle, 0); - struct com_t { dds_entity_t participant; /* durable client participant */ dds_entity_t status_subscriber; /* subscriber used to receive status messages */ @@ -163,6 +98,7 @@ struct dc_t { uint32_t quorum; /*quorum of durable services needed to unblock durable writers */ char *ident; /* ds identification */ } cfg; + uint64_t seq; /* monotonically increasing sequence number, bumped by 1 for each request by this client */ ddsrt_atomic_uint32_t refcount; /* refcount, increased/decreased when a participant is created/deleted */ struct ddsi_domaingv *gv; /* reference to ddsi domain settings */ struct com_t *com; /* ptr to durable client communication infra structure */ @@ -207,36 +143,6 @@ static unsigned split_string (const char ***p_ps, char **p_bufcopy, const char * return nps; } -#if 0 -/* callback function to update the sequence number administration of a container - * and to optionally monitor the contents of data containers */ -static void default_data_available_cb (dds_entity_t rd, void *arg) -{ -#define MAX_SAMPLES 100 - int samplecount; - static void *samples[MAX_SAMPLES]; - dds_sample_info_t info[MAX_SAMPLES]; - - (void)arg; - - samplecount = dds_read_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ALIVE_INSTANCE_STATE); - printf("LH *** samplecount = %d\n", samplecount); - if (samplecount < 0) { - printf("LH *** dds_read_mask for status reader failed: %s", dds_strretcode(-samplecount)); - goto samplecount_err; - } - for (int j = 0; j < samplecount; j++) { - DurableSupport_status *status = (DurableSupport_status *)samples[j]; - printf("LH *** recv status(): name=%s\n", status->name); - info[j].publication_handle(); - - } -samplecount_err: -#undef MAX_SAMPLES - return; -} -#endif - static struct server_t *create_server (struct dc_t *dc, DurableSupport_id_t id, const char *name, const char *hostname) { struct server_t *server; @@ -305,6 +211,295 @@ static int create_request_partition_expression (struct com_t *com, char **reques return 0; } +/* The following is used to build up an administration to evaluate + * if a writer has reached its quorum for durable containers. + * The administration uses data container counters to count the + * number of data container matches for a given writer. If the writer + * publishes on multiple partitions, we requires that for each of + * these partitions the quorum must be met in order for the publisher + * to start publishing. + * To retrieve the matching data containers for a writer we use + * dds_get_matched_subscriptions(). This call returns the matched + * reader for a given writer, even the onces that occurred before the + * quorum listener has been attached to the writer. To reduce the + * number of calls to dds_get_matched_subscriptions() we only call + * it there is a risk that the quorum changes. + */ +struct data_container_cnt_key_t { + char *partition; +}; + +struct data_container_cnt_t { + ddsrt_avl_node_t node; + struct data_container_cnt_key_t key; + uint32_t cnt; +}; + +static void cleanup_data_container_cnt (void *n) +{ + struct data_container_cnt_t *dcc = (struct data_container_cnt_t *)n; + + ddsrt_free(dcc->key.partition); + ddsrt_free(dcc); +} + +static int cmp_data_container_cnt (const void *a, const void *b) +{ + struct data_container_cnt_key_t *k1 = (struct data_container_cnt_key_t *)a; + struct data_container_cnt_key_t *k2 = (struct data_container_cnt_key_t *)b; + + return strcmp(k1->partition, k2->partition); +} + +static const ddsrt_avl_ctreedef_t data_container_cnt_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct data_container_cnt_t, node), offsetof (struct data_container_cnt_t, key), cmp_data_container_cnt, 0); + + +static struct data_container_cnt_t *create_data_container_cnt (ddsrt_avl_ctree_t *dcc_tree, const char *partition) +{ + struct data_container_cnt_t *dcc; + + assert(partition); + dcc = (struct data_container_cnt_t *)ddsrt_malloc(sizeof(struct data_container_cnt_t)); + dcc->key.partition = ddsrt_strdup(partition); + dcc->cnt = 0; + ddsrt_avl_cinsert(&data_container_cnt_td, dcc_tree, dcc); + return dcc; +} + +static struct data_container_cnt_t *get_data_container_cnt (ddsrt_avl_ctree_t *dcc_tree, const char *partition, bool autocreate) +{ + struct data_container_cnt_t *dcc = NULL; + struct data_container_cnt_key_t key; + + assert(dcc_tree); + assert(partition); + key.partition = ddsrt_strdup(partition); + if (((dcc = ddsrt_avl_clookup (&data_container_cnt_td, dcc_tree, &key)) == NULL) && autocreate) { + dcc = create_data_container_cnt(dcc_tree, partition); + } + ddsrt_free(key.partition); + return dcc; +} + +static void dc_free_partitions (uint32_t plen, char **partitions) +{ + uint32_t i; + + if (partitions == NULL) { + return; + } + for (i=0; i < plen; i++) { + ddsrt_free(partitions[i]); + } + ddsrt_free(partitions); +} + +/* verifies if the user data of the endpoint contains the identifier + * that indicates that this endpoint is a durable container */ +static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *ep, const char *ident) +{ + dds_builtintopic_endpoint_t template; + dds_builtintopic_participant_t *participant; + dds_instance_handle_t ih; + dds_return_t rc; + static void *samples[1]; + static dds_sample_info_t info[1]; + void *userdata; + size_t size = 0; + char id_str[37]; + bool result = false; + + assert(ep); + /* by convention, if the ident == NULL then return true */ + if (ident == NULL) { + return true; + } + /* lookup the instance handle of the builtin participant endpoint that + * contains the participant of the subinfo */ + memcpy(template.key.v,ep->participant_key.v,16); + if ((ih = dds_lookup_instance(com->rd_participant, &template)) == DDS_HANDLE_NIL) { + DDS_ERROR("Failed to lookup the participant of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); + goto err_lookup_instance; + } + if ((rc = dds_read_instance(com->rd_participant, samples, info, 1, 1, ih)) <= 0) { + DDS_ERROR("Failed to read the participant of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); + goto err_read_instance; + } + if (info[0].valid_data) { + participant = (dds_builtintopic_participant_t *)samples[0]; + /* get the user data */ + if (!dds_qget_userdata(participant->qos, &userdata, &size)) { + DDS_ERROR("Unable to retrieve the user data of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); + goto err_qget_userdata; + } + if ((size != strlen(ident)) || (userdata == NULL) || (strcmp(userdata, ident) != 0)) { + /* the user data of the participant of the durable reader does not contain the ident, + * so the endoint is not from a remote DS */ + result = false; + } else { + /* this endpoint's participant is a ds */ + result = true; + } + dds_free(userdata); + } + return result; + +err_lookup_instance: +err_read_instance: +err_qget_userdata: + return false; +} + +/* Determine if the quorum for the writer is reached or not. + * This function also does its job when the quorum threshold is 0, + * even though this case is likely to be prohibited because it + * violates eventual consistency. After all, how can you provide + * historical data if you allow that durable publishers start to + * publish when there is no durable support? */ +static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer, bool wr_appeared) +{ + /* precondition: the writer is only called when we know that the writer is durable */ + + dds_qos_t *qos; + dds_return_t ret; + uint32_t plen, i; + char **partitions; + char *tpname; + dds_writer *wr; + bool old_quorum_reached, quorum_reached = true; + bool to_check = false; + struct data_container_cnt_t *dcc; + dds_guid_t wguid; + char id_str[37]; + + qos = dds_create_qos(); + if ((ret = dds_get_qos(writer, qos)) < 0) { + DDS_ERROR("failed to get qos from writer [%s]\n", dds_strretcode(ret)); + goto err_get_qos; + } + if (!dds_qget_partition(qos, &plen, &partitions)) { + DDS_ERROR("failed to get partitions from qos\n"); + goto err_qget_partition; + } + assert(plen > 0); + if (dds_get_guid(writer, &wguid) < 0) { + DDS_ERROR("failed to writer guid\n"); + goto err_get_guid; + } + /* determine if the quorum is already satisfied or not */ + if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) { + DDS_ERROR("failed to lock writer [%s]\n", dds_strretcode(ret)); + goto err_writer_lock; + } + tpname = ddsrt_strdup(wr->m_topic->m_name); + old_quorum_reached = wr->quorum_reached; + to_check = ((!wr->quorum_reached) && (wr_appeared)) || ((wr->quorum_reached) && (!wr_appeared)); + dds_writer_unlock (wr); + if (to_check) { + dds_instance_handle_t *rd_ihs; + size_t nrds = 128; + ddsrt_avl_ctree_t data_container_counters; + + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "checking quorum for writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); + ddsrt_avl_cinit(&data_container_cnt_td, &data_container_counters); + /* Check if the quorum for the writer is lost or reached. + * We do this by calling dds_get_matched_subscriptions(). + * This is an expensive call, but it works for now. At least we + * are protected against missing publication_matches() that could have + * occurred before the quorum listener was set on the writer. + * We only do this expensive call when there is a possibility + * that the quorum_reached property of the writer changes. + * Because the call to dds_get_matched_subscriptions() requires + * an preallocated list of reader handles and we don't know the + * size of the list beforehand, we dynamically extend the list + * until it is large enough to hold all handles of matching readers. */ + do { + nrds = nrds * 2; + rd_ihs = ddsrt_malloc(nrds * sizeof(dds_instance_handle_t)); + if ((ret = dds_get_matched_subscriptions(writer, rd_ihs, nrds)) > (int32_t)nrds) { + /* allocated list is too small, use a bigger list */ + ddsrt_free(rd_ihs); + } + } while (ret > (int32_t)nrds); + /* We now have a list of handles to readers that match with the writer. + * Determine if the quorum is reached by verifying if the reader + * is a data container, an counting the matches. */ + if ((ret >= 0) && (dc->cfg.quorum > (uint32_t)ret)) { + /* the number of matches is less than the quorum, so we are sure that + * the quorum cannot be reached. */ + quorum_reached = false; + } else if (ret >= 0) { + /* now walk over all reader handles, lookup the reader, + * and determine if the reader is a remote data container. + * If so, we have detected a matching remote data container and + * we increase the count for this container. */ + for (i=0; i < (uint32_t)ret; i++) { + dds_builtintopic_endpoint_t *ep; + + if ((ep = dds_get_matched_subscription_data(writer, rd_ihs[i])) != NULL) { + if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { + /* the matching endpoint represents a data container. + * Increase the count for this container. */ + uint32_t ep_plen; + char **ep_partitions; + + dds_qget_partition(ep->qos, &ep_plen, &ep_partitions); + assert(ep_plen == 1); /* this is a data container, so it must have a singleton as partition */ + dcc = get_data_container_cnt(&data_container_counters, ep_partitions[0], true); + dcc->cnt++; + dc_free_partitions(ep_plen, ep_partitions); + } + dds_builtintopic_free_endpoint(ep); + } + } + /* Determine if the quorum is reached or not. + * We do this by walking over the partitions of the writer, + * lookup the corresponding data container counter, and determine + * if they meet the quorum. Only if the quorum is met for all + * partitions of the writer, then we are sure that the writer meets + * the quorum condition, and publication can proceed. */ + quorum_reached = true; + for (i=0; i < plen; i++) { + if ((dcc = get_data_container_cnt(&data_container_counters, partitions[i], false)) == NULL) { + /* no data container counter found for this partitions of the writer, so + * quorom not reached */ + quorum_reached = false; + break; + } else if (dcc->cnt < dc->cfg.quorum) { + /* quorom not (yet) reached */ + quorum_reached = false; + break; + } + } + } + if (old_quorum_reached != quorum_reached) { + /* the quorum has changed, update the writer quorum setting */ + if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) { + DDS_ERROR("failed to lock writer [%s]\n", dds_strretcode(ret)); + goto err_writer_lock; + } + wr->quorum_reached = quorum_reached; + dds_writer_unlock (wr); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for writer \"%s\" %s\n", dc_stringify_id(wguid.v, id_str), quorum_reached ? "reached" : "lost"); + } else { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for writer \"%s\" still %sreached\n", dc_stringify_id(wguid.v, id_str), quorum_reached ? "" : "not "); + } + ddsrt_avl_cfree(&data_container_cnt_td, &data_container_counters, cleanup_data_container_cnt); + ddsrt_free(rd_ihs); + } + dc_free_partitions(plen, partitions); + ddsrt_free(tpname); + dds_delete_qos(qos); + return; + +err_writer_lock: +err_get_guid: + dc_free_partitions(plen, partitions); +err_qget_partition: +err_get_qos: + dds_delete_qos(qos); + return; +} /* set up durable client infrastructure */ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, struct ddsi_domaingv *gv) @@ -450,7 +645,7 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc participant reader [%s]\n", dds_strretcode(-com->rd_participant)); goto err_rd_participant; } - /* subinfo reader and listener to detect remote data containers */ + /* subinfo reader to detect remote data containers */ if ((com->rd_subinfo = dds_create_reader(com->participant, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL)) < 0) { DDS_ERROR("failed to create dc subinfo reader [%s]\n", dds_strretcode(-com->rd_subinfo)); goto err_rd_subinfo; @@ -567,7 +762,13 @@ static void dc_com_free (struct com_t *com) return; } -static dds_return_t dc_com_send_request (struct com_t *com, dds_entity_t reader) +static uint64_t next_request_seq (struct dc_t *dc) +{ + (dc->seq)++; + return dc->seq; +} + +static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader) { /* check for publication_matched() on the dc_request writer tomake sure that the request arrives */ /* create a request */ @@ -576,14 +777,51 @@ static dds_return_t dc_com_send_request (struct com_t *com, dds_entity_t reader) /* note: we allow doing a request for volatile readers */ DurableSupport_request *request; + dds_qos_t *rqos; + dds_return_t ret = DDS_RETCODE_OK; + uint32_t plen, i; + char **partitions; + if ((rqos = dds_create_qos()) == NULL) { + DDS_ERROR("Unable to create reader qos for dc_request"); + goto err_alloc_rqos; + } + if ((ret = dds_get_qos(reader, rqos)) != DDS_RETCODE_OK) { + DDS_ERROR("Unable to get reader qos for dc_request"); + goto err_get_qos; + } + if (!dds_qget_partition(rqos, &plen, &partitions)) { + DDS_ERROR("Failed to retrieve partition qos for dc_request"); + goto err_qget_partition; + } request = DurableSupport_request__alloc(); memcpy(request->requestid.client, dc.cfg.id, 16); + request->requestid.seq = next_request_seq(&dc); + request->partitions._length = plen; + request->partitions._maximum = plen; + request->partitions._buffer = dds_sequence_string_allocbuf(plen); + request->partitions._release = true; + for (i=0; i < plen; i++) { + request->partitions._buffer[i] = ddsrt_strdup(partitions[i]); + } + request->timeout = DDS_SECS(5); + /* todo: administrate the request */ + if ((ret = dds_write(com->wr_request, request)) < 0) { + DDS_ERROR("com_set_bead_write failed [%s]", dds_strretcode(-ret)); + goto err_request_write; + } + DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "dc_request sent\n"); +err_request_write: + dc_free_partitions(plen, partitions); + dds_delete_qos(rqos); DurableSupport_request_free(request, DDS_FREE_ALL); + return ret; - (void)com; - (void)reader; - return DDS_RETCODE_OK; +err_qget_partition: +err_get_qos: + dds_delete_qos(rqos); +err_alloc_rqos: + return DDS_RETCODE_ERROR; } static void dc_server_lost (struct dc_t *dc, DurableSupport_status *status) @@ -651,268 +889,12 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } -/* verifies if the user data of the endpoint contains the identifier - * that indicates that this endpoint is a durable container */ -static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *ep, const char *ident) -{ - dds_builtintopic_endpoint_t template; - dds_builtintopic_participant_t *participant; - dds_instance_handle_t ih; - dds_return_t rc; - static void *samples[1]; - static dds_sample_info_t info[1]; - void *userdata; - size_t size = 0; - char id_str[37]; - bool result = false; - - assert(ep); - /* by convention, if the ident == NULL then return true */ - if (ident == NULL) { - return true; - } - /* lookup the instance handle of the builtin participant endpoint that - * contains the participant of the subinfo */ - memcpy(template.key.v,ep->participant_key.v,16); - if ((ih = dds_lookup_instance(com->rd_participant, &template)) == DDS_HANDLE_NIL) { - DDS_ERROR("Failed to lookup the participant of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); - goto err_lookup_instance; - } - if ((rc = dds_read_instance(com->rd_participant, samples, info, 1, 1, ih)) <= 0) { - DDS_ERROR("Failed to read the participant of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); - goto err_read_instance; - } - if (info[0].valid_data) { - participant = (dds_builtintopic_participant_t *)samples[0]; - /* get the user data */ - if (!dds_qget_userdata(participant->qos, &userdata, &size)) { - DDS_ERROR("Unable to retrieve the user data of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); - goto err_qget_userdata; - } - if ((size != strlen(ident)) || (userdata == NULL) || (strcmp(userdata, ident) != 0)) { - /* the user data of the participant of the durable reader does not contain the ident, - * so the endoint is not from a remote DS */ - result = false; - } else { - /* this endpoint's participant is a ds */ - result = true; - } - dds_free(userdata); - } - return result; - -err_lookup_instance: -err_read_instance: -err_qget_userdata: - return false; -} - -static void dc_free_partitions (uint32_t plen, char **partitions) -{ - uint32_t i; - - if (partitions == NULL) { - return; - } - for (i=0; i < plen; i++) { - ddsrt_free(partitions[i]); - } - ddsrt_free(partitions); -} - -static ddsi_guid_prefix_t dc_ddsi_hton_guid_prefix (ddsi_guid_prefix_t p) -{ - int i; - for (i = 0; i < 3; i++) - p.u[i] = ddsrt_toBE4u (p.u[i]); - return p; -} - -static ddsi_entityid_t dc_ddsi_hton_entityid (ddsi_entityid_t e) -{ - e.u = ddsrt_toBE4u (e.u); - return e; -} - -static ddsi_guid_t dc_ddsi_hton_guid (ddsi_guid_t g) -{ - g.prefix = dc_ddsi_hton_guid_prefix (g.prefix); - g.entityid = dc_ddsi_hton_entityid (g.entityid); - return g; -} - -static void dc_ddsiguid2guid (dds_guid_t *dds_guid, const ddsi_guid_t *ddsi_guid) -{ - ddsi_guid_t tmp; - tmp = dc_ddsi_hton_guid (*ddsi_guid); - memcpy (dds_guid, &tmp, sizeof (*dds_guid)); -} - -static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer, bool new_qe) -{ - dds_qos_t *qos; - dds_writer *wr; - dds_return_t rc; - uint32_t plen, i; - char **partitions; - struct quorum_entry_key_t key; - struct quorum_entry_t *qe; - bool quorum_reached = true; - - assert(writer); - assert(dc); - - qos = dds_create_qos(); - if ((rc = dds_get_qos(writer, qos)) < 0) { - DDS_ERROR("failed to get qos from writer [%s]", dds_strretcode(rc)); - goto err_get_qos; - } - if (!dds_qget_partition(qos, &plen, &partitions)) { - DDS_ERROR("failed to get partitions from qos\n"); - goto err_qget_partition; - } - assert(plen > 0); - if ((rc = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) { - DDS_ERROR("failed to lock writer\n"); - goto err_writer_lock; - } - key.tpname = ddsrt_strdup(wr->m_topic->m_name); - if (((!wr->quorum_reached) && (new_qe)) || ((wr->quorum_reached) && (!new_qe))) { - /* the quorum was not reached and a new quorum entry has been found, or - * the quorum was reached and a quorum entry has been lost - * In both cases check if the quorum still holds */ - for (i=0; i < plen && quorum_reached; i++) { - /* lookup the quorum entry, and determine if a quorum has reached for all relevant data containers */ - key.partition = ddsrt_strdup(partitions[i]); - if ((qe = ddsrt_avl_clookup (&quorum_entry_td, &dc->quorum_entries, &key)) == NULL) { - quorum_reached = false; - } else { - quorum_reached = (qe->cnt >= dc->cfg.quorum); - } - ddsrt_free(key.partition); - } - if (wr->quorum_reached != quorum_reached) { - dds_guid_t guid; - char id_str[37]; - - wr->quorum_reached = quorum_reached; - dc_ddsiguid2guid(&guid, &wr->m_entity.m_guid); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for writer \"%s\" %s\n", dc_stringify_id(guid.v, id_str), quorum_reached ? "reached" : "lost"); - } - } - ddsrt_free(key.tpname); - dds_writer_unlock (wr); -err_writer_lock: - dc_free_partitions(plen, partitions); -err_qget_partition: -err_get_qos: - dds_delete_qos(qos); - return; -} - - - -/* get a quorum counter for the builtin endoint and create a quorum counter for the endpoint */ -static struct quorum_entry_t *dc_get_or_create_quorum_entry (struct dc_t *dc, dds_builtintopic_endpoint_t *ep) -{ - struct quorum_entry_t *qe; - struct quorum_entry_key_t key; - uint32_t plen; - char **partitions; - - if (!dds_qget_partition(ep->qos, &plen, &partitions)) { - DDS_ERROR("failed to get partitions from qos\n"); - goto err_qget_partition; - } - assert(plen == 1); - key.tpname = ddsrt_strdup(ep->topic_name); - key.partition = ddsrt_strdup(partitions[0]); - if ((qe = ddsrt_avl_clookup (&quorum_entry_td, &dc->quorum_entries, &key)) == NULL) { - /* create quorum entry */ - if ((qe = (struct quorum_entry_t *)ddsrt_malloc(sizeof(struct quorum_entry_t))) == NULL) { - DDS_ERROR("failed to allocate quorum entry\n"); - goto err_alloc_quorum_entry; - } - qe->key.partition = ddsrt_strdup(key.partition); - qe->key.tpname = ddsrt_strdup(key.tpname); - qe->cnt = 0; - ddsrt_avl_cinsert(&quorum_entry_td, &dc->quorum_entries, qe); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum entry for \"%s.%s\" created\n", qe->key.partition, qe->key.tpname); - } - ddsrt_free(key.tpname); - ddsrt_free(key.partition); - dc_free_partitions(plen, partitions); - return qe; - -err_alloc_quorum_entry: - ddsrt_free(key.tpname); - ddsrt_free(key.partition); - dc_free_partitions(plen, partitions); -err_qget_partition: - return NULL; -} - -static struct quorum_entry_t *dc_link_handle_to_quorum_entry (struct dc_t *dc, dds_instance_handle_t ih, struct quorum_entry_t *qe) -{ - struct handle_to_quorum_entry_t *hqe; - - assert(qe); - /* link the handle to the quorum entry, so we can lookup the - * quorum entry if the data container identified by the handle - * disappears */ - if ((hqe = (struct handle_to_quorum_entry_t *)ddsrt_malloc(sizeof(struct handle_to_quorum_entry_t))) == NULL) { - DDS_ERROR("failed to allocate handle_to_quorum_entry_t\n"); - goto err_alloc_hqe; - } - hqe->ih = ih; - hqe->qe_ref = qe; - ddsrt_avl_cinsert(&handle_to_quorum_entry_td, &dc->handle_to_quorum_entries, hqe); - qe->cnt++; - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for \"%s.%s\" bumped to %" PRIu32 " (ih %" PRIx64 ")\n", qe->key.partition, qe->key.tpname, qe->cnt, ih); - return qe; - -err_alloc_hqe: - return NULL; -} - -/* Update the quorum entry when a data container leaves. - * Returns a reference to the quorum entry as long as there are still containers, or NULL otherwise */ -static struct quorum_entry_t *dc_unlink_handle_to_quorum_entry (struct dc_t *dc, dds_instance_handle_t ih) -{ - struct handle_to_quorum_entry_t *hqe; - struct quorum_entry_t *qe = NULL; - ddsrt_avl_dpath_t dpath_hqe, dpath_qe; - - /* look up the quorum entry via the instance handle */ - if ((hqe = ddsrt_avl_clookup_dpath (&handle_to_quorum_entry_td, &dc->handle_to_quorum_entries, &ih, &dpath_hqe)) != NULL) { - qe = hqe->qe_ref; - assert(qe); - assert(qe->cnt > 0); - qe->cnt--; - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for \"%s.%s\" decreased to %" PRIu32 " (ih %" PRIx64 ")\n", qe->key.partition, qe->key.tpname, qe->cnt, ih); - if (qe->cnt == 0) { - /* by unlinking this subscription info, the last reference to the quorum entry is now gone. - * We can now garbage collect the quorum entry itself. */ - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum entry for \"%s.%s\" deleted\n", qe->key.partition, qe->key.tpname); - if (ddsrt_avl_clookup_dpath(&quorum_entry_td, &dc->quorum_entries, &qe->key, &dpath_qe)) { - ddsrt_avl_cdelete_dpath(&quorum_entry_td, &dc->quorum_entries, qe, &dpath_qe); - cleanup_quorum_entry(qe); - qe = NULL; - } - } - ddsrt_avl_cdelete_dpath(&handle_to_quorum_entry_td, &dc->handle_to_quorum_entries, hqe, &dpath_hqe); - cleanup_handle_to_quorum_entry(hqe); - } - return qe; -} - /* called when there is a match for a durable writer */ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publication_matched_status_t status, void *arg) { struct dc_t *dc = (struct dc_t *)arg; dds_instance_handle_t ih; dds_builtintopic_endpoint_t *ep; - struct quorum_entry_t *qe; /* a reader has matched with a durable writer. */ /* check if the reader is a data container. @@ -924,32 +906,16 @@ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publicat } if ((ep = dds_get_matched_subscription_data(writer, ih)) != NULL) { if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { - /* a data container has matched with this writer. - * Increase the quorum counter for this container. - * If no quorum counter existed, then create one. - * Also link the subscription handle to the quorum counter, - * so that we can decrease the quorum counter in case the - * data container does not exist. */ - if ((qe = dc_get_or_create_quorum_entry(dc, ep)) == NULL) { - goto err_inc_or_create_quorum_entry; - } - dc_link_handle_to_quorum_entry(dc, ih, qe); - /* a relevant data container from a durable service for this writer has become available. - * Reevaluate if the quorum has been reached */ + /* A data container has matched with this writer. + * Check if the quorum is met. */ dc_check_quorum_reached(dc, writer, true); } dds_builtintopic_free_endpoint(ep); } else { - /* the endpoint that represents a data container is not available any more. - * decrease the quorum counter for the data container associated with - * the handle. If the quorum counter reaches 0, we'll garbage collect - * the quorum counter entry. */ - qe = dc_unlink_handle_to_quorum_entry(dc, ih); - /* a data container from a durable service has been lost. - * reevaluate if the quorum still holds */ + /* the endpoint is not available any more. + * Check if the quorom has been lost*/ dc_check_quorum_reached(dc, writer, false); } - err_inc_or_create_quorum_entry: err_last_subscription_handle: return; } @@ -961,22 +927,7 @@ static uint32_t recv_handler (void *a) dds_attach_t wsresults[1]; size_t wsresultsize = sizeof(wsresults)/sizeof(wsresults[0]); int n, j; - dds_return_t rc; - if ((dc->quorum_listener = dds_create_listener(dc)) == NULL) { - DDS_ERROR("failed to create quorum listener\n"); - goto err_create_quorum_listener; - } - dds_lset_publication_matched(dc->quorum_listener, default_durable_writer_matched_cb); - if ((dc->subinfo_listener = dds_create_listener(dc)) == NULL) { - DDS_ERROR("failed to create subinfo listener\n"); - goto err_create_subinfo_listener; - } - // dds_lset_data_available(dc->subinfo_listener, default_evaluate_quorum_cb); - if ((rc = dds_set_listener(dc->com->rd_subinfo, dc->subinfo_listener)) < 0) { - DDS_ERROR("Unable to set the subinfo listener\n"); - goto err_set_listener; - } DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "start durable client thread\n"); while (!dds_triggered(dc->com->ws)) { n = dds_waitset_wait_until (dc->com->ws, wsresults, wsresultsize, timeout); @@ -990,19 +941,8 @@ static uint32_t recv_handler (void *a) } } } - dds_delete_listener(dc->subinfo_listener); - dc->subinfo_listener = NULL; - dds_delete_listener(dc->quorum_listener); - dc->quorum_listener = NULL; DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "stop durable client thread\n"); return 0; - -err_set_listener: - dds_delete_listener(dc->subinfo_listener); -err_create_subinfo_listener: - dds_delete_listener(dc->quorum_listener); -err_create_quorum_listener: - return 1; } dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_domaingv *gv) @@ -1026,8 +966,12 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom dc.cfg.quorum = DEFAULT_QOURUM; /* LH: currently hardcoded set to 1, should be made configurable in future */ dc.cfg.ident = ddsrt_strdup(DEFAULT_IDENT); ddsrt_avl_cinit(&server_td, &dc.servers); - ddsrt_avl_cinit(&quorum_entry_td, &dc.quorum_entries); - ddsrt_avl_cinit(&handle_to_quorum_entry_td, &dc.handle_to_quorum_entries); + /* create the quorum listener */ + if ((dc.quorum_listener = dds_create_listener(&dc)) == NULL) { + DDS_ERROR("failed to create quorum listener\n"); + goto err_create_quorum_listener; + } + dds_lset_publication_matched(dc.quorum_listener, default_durable_writer_matched_cb); if ((dc.com = dc_com_new(&dc, domainid, gv))== NULL) { DDS_ERROR("failed to initialize the durable client infrastructure\n"); goto err_com_new; @@ -1042,8 +986,8 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom err_recv_thread: dc_com_free(dc.com); err_com_new: - ddsrt_avl_cfree(&quorum_entry_td, &dc.quorum_entries, cleanup_quorum_entry); - ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); + dds_delete_listener(dc.quorum_listener); +err_create_quorum_listener: return DDS_RETCODE_ERROR; } @@ -1074,8 +1018,6 @@ dds_return_t dds_durability_fini (void) DDS_ERROR("failed to join the dc recv thread [%s]", dds_strretcode(rc)); } dc_com_free(dc.com); - ddsrt_avl_cfree(&handle_to_quorum_entry_td, &dc.handle_to_quorum_entries, cleanup_handle_to_quorum_entry); - ddsrt_avl_cfree(&quorum_entry_td, &dc.quorum_entries, cleanup_quorum_entry); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); } ddsrt_free(dc.cfg.ident); @@ -1093,8 +1035,14 @@ dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rh /* create a durability reader that sucks and stores it in the store */ /* send a request */ - - dc_com_send_request (dc.com, reader); + if (dc.com) { + // dc_send_cached_requests(); + dc_com_request_write(dc.com, reader); + } else { + /* todo: apparently a reader is created before com is initialized. + * cache the request until com becomes available */ + // dc_cache_request(reader, rhc); + } (void)rhc; (void)reader; @@ -1137,7 +1085,7 @@ dds_return_t dds_durability_new_local_writer (dds_entity_t writer) assert(writer); qos = dds_create_qos(); if ((rc = dds_get_qos(writer, qos)) < 0) { - DDS_ERROR("failed to get qos from writer [%s]", dds_strretcode(rc)); + DDS_ERROR("failed to get qos from writer [%s]\n", dds_strretcode(rc)); goto err_get_qos; } if (!dds_qget_durability(qos, &dkind)) { @@ -1159,11 +1107,22 @@ dds_return_t dds_durability_new_local_writer (dds_entity_t writer) DDS_ERROR("failed to retrieve writer guid"); goto err_get_guid; } + /* We now set a quorum listener on the durable writer. + * Each time a matching reader will appear, wewill get notified. + * Existing readers may already have matched before the listener takes effect, + * so these publication_match events may be missed. Luckily, we can request + * all matching readers using dds_get_matched_subscriptions(). + * + * Note: be aware that the same readers can be present in the list provided + * by dds_get_matched_subscriptions(), and can also be triggered by the listener. + * Avoid counting these readers twice! + */ DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "durable writer \"%s\" subject to quorum checking\n", dc_stringify_id(wguid.v, id_str)); if ((rc = dds_set_listener(writer, dc.quorum_listener)) < 0) { DDS_ERROR("Unable to set the quorum listener on writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); goto err_set_listener; } + dc_check_quorum_reached (&dc, writer, true); } dds_delete_qos(qos); return DDS_RETCODE_OK; @@ -1176,65 +1135,6 @@ dds_return_t dds_durability_new_local_writer (dds_entity_t writer) return rc; } -#if 0 -dds_return_t dds_durability_wait_for_quorum (dds_writer *wr) -{ - dds_return_t ret = DDS_RETCODE_ERROR; - ddsrt_mtime_t tnow = ddsrt_time_monotonic (); - ddsrt_mtime_t timeout; - dds_duration_t sleep_duration; - dds_entity_t writer; - - /* This function is called from dds_write() while the writer lock is held. - * To make sure that we temporarily release the writer lock - * while we wait until the quorum has been reached, we need access - * to the entity handle in order to acquire the lock each time - * we recheck.*/ - writer = (dds_entity_t)wr->m_entity.m_hdllink.hdl; - /* No need to check for quorum for non-durable writers */ - if (wr->m_wr->xqos->durability.kind <= DDS_DURABILITY_TRANSIENT_LOCAL) { - ret = DDS_RETCODE_OK; - goto done; - } - timeout = ddsrt_mtime_add_duration (tnow, wr->m_wr->xqos->reliability.max_blocking_time); - /* If the quorum is reached we'll immediately return DDS_RETCODE_OK. - * Note that for volatile and transient-local writers the quorum - * is but definition reached, so this function will always return with - * DDS_RETCODE_OK in those case. */ - if (wr->quorum_reached) { - ret = DDS_RETCODE_OK; - goto done; - } - /* The quorum for a durable writer is not reached. - * We will head bang until the quorum is reached. - * To prevent starvation we use a max 10ms sleep in between. - * If the quorum is reached within the max_blocking_time, - * DDS_RETCODE_OK is returned, otherwise DDS_PRECONDITION_NOT_MET - * is returned. */ - do { - sleep_duration = DDS_MSECS(10); - dds_writer_unlock(wr); - dds_sleepfor (sleep_duration); - if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) { - goto err_writer_lock; - } - tnow = ddsrt_time_monotonic (); - if (tnow.v >= timeout.v) { - ret = DDS_RETCODE_PRECONDITION_NOT_MET; - break; - } - if (wr->quorum_reached) { - ret = DDS_RETCODE_OK; - break; - } - } while (true); -done: - dds_writer_unlock(wr); -err_writer_lock: - return ret; -} -#endif - /* Retrieve the quorum_reached value from the dds_writer that corresponds to the writer entity */ static dds_return_t dds_durability_get_quorum_reached (dds_entity_t writer, bool *quorum_reached, ddsrt_mtime_t *timeout) { @@ -1251,13 +1151,14 @@ static dds_return_t dds_durability_get_quorum_reached (dds_entity_t writer, bool tnow = ddsrt_time_monotonic (); *timeout = ddsrt_mtime_add_duration (tnow,wr->m_wr->xqos->reliability.max_blocking_time); } - /* retrieve quorum reached */ - *quorum_reached = wr->quorum_reached; + /* retrieve quorum reached; by default true if quorum is 0 */ + *quorum_reached = wr->quorum_reached | (dc.cfg.quorum == 0); dds_writer_unlock(wr); err_writer_lock: return ret; } +/* wait for quorum reached, or timeout in case max_blocking_time is expired and quorum not yet reached */ dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) { dds_return_t ret = DDS_RETCODE_ERROR; @@ -1272,7 +1173,11 @@ dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) * When the quorum is reached within the max_blocking_time, * DDS_RETCODE_OK is returned, otherwise DDS_PRECONDITION_NOT_MET * is returned. The max_blocking_time itself is retrieved lazily - * on the first call to dds_durability_get_quorum_reached(). */ + * on the first call to dds_durability_get_quorum_reached(). + * + * LH: A better solution would be to wait on a condition variable, + * and get notified once the quorum is reached (or the max_blocking_time + * times out) */ timeout.v = DDS_TIME_INVALID; do { if ((ret = dds_durability_get_quorum_reached(writer, &quorum_reached, &timeout)) != DDS_RETCODE_OK) { @@ -1293,3 +1198,9 @@ dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) return ret; } +/* get the configured quorum */ +uint32_t dds_durability_get_quorum (void) +{ + return dc.cfg.quorum; +} + From aa2ab4cf56935e925be6334a4083a44a38bee2aa Mon Sep 17 00:00:00 2001 From: Michel van den Hoek Date: Tue, 24 Oct 2023 13:17:27 +0200 Subject: [PATCH 017/207] fix sanitizer error due to double free Signed-off-by: Michel van den Hoek --- src/durability/src/dds_durability.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 321cdc1fce..3a66752f94 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -988,6 +988,7 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom err_com_new: dds_delete_listener(dc.quorum_listener); err_create_quorum_listener: + ddsrt_free(dc.cfg.ident); return DDS_RETCODE_ERROR; } @@ -1019,8 +1020,8 @@ dds_return_t dds_durability_fini (void) } dc_com_free(dc.com); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); + ddsrt_free(dc.cfg.ident); } - ddsrt_free(dc.cfg.ident); return DDS_RETCODE_OK; } From 9aa260309539332407820e7a63e23f85a2b79a4e Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 3 Nov 2023 12:32:41 +0100 Subject: [PATCH 018/207] Publish dc_request when a durable reader is created Signed-off-by: TheFixer --- src/core/ddsc/src/dds_reader.c | 9 +- .../include/dds/durability/dds_durability.h | 4 +- src/durability/src/dds_durability.c | 447 +++++++++++++++--- 3 files changed, 395 insertions(+), 65 deletions(-) diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index 6bd66b8e6e..3a8df71815 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -702,6 +702,11 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe } #endif +#ifdef DDS_HAS_DURABILITY + dds_durability_kind_t dkind; + dds_qget_durability(rqos, &dkind); +#endif + /* Create reader and associated read cache (if not provided by caller) */ struct dds_reader * const rd = dds_alloc (sizeof (*rd)); const dds_entity_t reader = dds_entity_init (&rd->m_entity, &sub->m_entity, DDS_KIND_READER, false, true, rqos, listener, DDS_READER_STATUS_MASK); @@ -771,7 +776,9 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe dds_subscriber_unlock (sub); #ifdef DDS_HAS_DURABILITY - dds_durability_new_local_reader(reader, rhc); + if (dkind >= DDS_DURABILITY_TRANSIENT) { + dds_durability_new_local_reader(reader, rhc); + } #endif return reader; diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h index 37294cd825..0be8256392 100644 --- a/src/durability/include/dds/durability/dds_durability.h +++ b/src/durability/include/dds/durability/dds_durability.h @@ -17,6 +17,9 @@ #include "dds__types.h" #include "dds/ddsc/dds_rhc.h" +/* This is the user data that identifies a durable service */ +#define IDENT "durable_support" + #if defined (__cplusplus) extern "C" { #endif @@ -31,7 +34,6 @@ uint32_t dds_durability_get_quorum (void); dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc); dds_return_t dds_durability_new_local_writer (dds_entity_t writer); dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer); -dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer); bool dds_durability_is_terminating (void); diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 3a66752f94..015ac13187 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -61,6 +61,69 @@ static void cleanup_server (void *n) static const ddsrt_avl_ctreedef_t server_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct server_t, node), offsetof (struct server_t, id), cmp_server, 0); +/* This represents a request for historical data. */ +struct pending_request_t { + ddsrt_avl_node_t node; /* represents a node in the tree of pending requests */ + ddsrt_fibheap_node_t fhnode; /* represents a node in the priority queue */ + dds_instance_handle_t ih; /* the instance handle that represents the reader */ + uint64_t seq; /* the sequence number of the request; this is used as the key */ + dds_entity_t reader; /* the reader that does the request */ + struct dds_rhc *rhc; /* reader rhc */ + dds_duration_t exptime; /* expiry time for this pending request */ +}; + +static int cmp_pending_request (const void *a, const void *b) +{ + uint64_t *s1 = (uint64_t *)a; + uint64_t *s2 = (uint64_t *)b; + + return (*s1 < *s2) ? -1 : ((*s1 > *s2) ? 1 : 0); +} + +static void cleanup_pending_request (void *n) +{ + struct pending_request_t *pr = (struct pending_request_t *)n; + ddsrt_free(pr); +} + +static int cmp_exp_time (const void *a, const void *b) +{ + struct pending_request_t *pr1 = (struct pending_request_t *)a; + struct pending_request_t *pr2 = (struct pending_request_t *)b; + + return (pr1->exptime < pr2->exptime) ? -1 : ((pr1->exptime > pr2->exptime) ? 1 : 0); +} + +static const ddsrt_avl_ctreedef_t pending_requests_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct pending_request_t, node), offsetof (struct pending_request_t, seq), cmp_pending_request, 0); + +static const ddsrt_fibheap_def_t pending_requests_fd = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct pending_request_t, fhnode), cmp_exp_time); + +/* Administration to keep track of the request readers of a ds + * that can act as a target to send requests for historical data to.. + * Based on this administration requests for historical data are published immediately, + * or pending until a ds is found that matches. */ + +struct matched_request_reader_t { + ddsrt_avl_node_t node; + dds_instance_handle_t ih; /* the instance handle of the matched request reader for my own request writer */ +}; + +static int cmp_matched_request_reader (const void *a, const void *b) +{ + dds_instance_handle_t *ih1 = (dds_instance_handle_t *)a; + dds_instance_handle_t *ih2 = (dds_instance_handle_t *)b; + + return (*ih1 < *ih2) ? -1 : ((*ih1 > *ih2) ? 1 : 0); +} + +static void cleanup_matched_request_reader (void *n) +{ + struct matched_request_reader_t *mrr = (struct matched_request_reader_t *)n; + ddsrt_free(mrr); +} + +static const ddsrt_avl_ctreedef_t matched_request_readers_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct matched_request_reader_t, node), offsetof (struct matched_request_reader_t, ih), cmp_matched_request_reader, 0); + struct com_t { dds_entity_t participant; /* durable client participant */ dds_entity_t status_subscriber; /* subscriber used to receive status messages */ @@ -93,7 +156,7 @@ struct com_t { struct dc_t { struct { DurableSupport_id_t id; /* the id of this client */ - char id_str[37]; /* string representation of the service id */ + char id_str[37]; /* string representation of the client id */ char *request_partition; /* partition to send requests too; by default same as */ uint32_t quorum; /*quorum of durable services needed to unblock durable writers */ char *ident; /* ds identification */ @@ -111,8 +174,12 @@ struct dc_t { ddsrt_avl_ctree_t servers; /* tree containing all discovered durable servers */ dds_listener_t *subinfo_listener; /* listener to detect remote containers */ dds_listener_t *quorum_listener; /* listener to check if a quorum is reached */ - ddsrt_avl_ctree_t quorum_entries; /* tree containing quora for all discovered data containers */ - ddsrt_avl_ctree_t handle_to_quorum_entries; /* tree that maps subscription handles to references to quorum entries */ + dds_listener_t *request_listener; /* listener to check if request reader is available */ + ddsrt_avl_ctree_t pending_requests; /* tree containing pending requests */ + ddsrt_fibheap_t pending_requests_fh; /* priority queue for pending requests, prioritized by expiry time */ + dds_instance_handle_t selected_request_reader_ih; /* instance handle to matched request reader, DDS_HANDLE_NIL if not available */ + ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on a ds that match with my ds writer */ + uint32_t nr_of_matched_dc_requests; /* indicates the number of matched dc_request readers for the dc_request writer of this client */ }; static struct dc_t dc = { 0 }; /* static durable client structure */ @@ -302,8 +369,8 @@ static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *e dds_builtintopic_participant_t *participant; dds_instance_handle_t ih; dds_return_t rc; - static void *samples[1]; - static dds_sample_info_t info[1]; + void *samples[1] = { NULL }; + dds_sample_info_t info[1]; void *userdata; size_t size = 0; char id_str[37]; @@ -342,10 +409,12 @@ static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *e } dds_free(userdata); } + (void)dds_return_loan (com->rd_participant, samples, rc); return result; err_lookup_instance: err_read_instance: + (void)dds_return_loan (com->rd_participant, samples, rc); err_qget_userdata: return false; } @@ -576,7 +645,10 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc status read condition [%s]\n", dds_strretcode(-com->rc_status)); goto err_rc_status; } - /* create dc_request writer */ + /* create dc_request writer + * The dc_request topic is a transient-local topic, which ensures that + * a late joining DS can still get a request provided it has not not + * expired. */ if (create_request_partition_expression(com, &request_partition) < 0) { DDS_ERROR("failed to create dc request partition\n"); goto err_request_partition; @@ -592,8 +664,9 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("Failed to create dc publisher for request topic [%s]\n", dds_strretcode(-com->request_publisher)); goto err_request_publisher; } - dds_qset_durability(tqos, DDS_DURABILITY_VOLATILE); - dds_qset_history(tqos, DDS_HISTORY_KEEP_ALL, DDS_LENGTH_UNLIMITED); + /* create dc_request writer */ + dds_qset_durability(tqos, DDS_DURABILITY_TRANSIENT_LOCAL); + dds_qset_history(tqos, DDS_HISTORY_KEEP_LAST, 1); if ((com->tp_request = dds_create_topic (com->participant, &DurableSupport_request_desc, "dc_request", tqos, NULL)) < 0) { DDS_ERROR("failed to create the dc request topic [%s]\n", dds_strretcode(-com->tp_request)); goto err_tp_request; @@ -606,6 +679,18 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to copy dc request topic qos [%s]\n", dds_strretcode(-ret)); goto err_copy_request_wqos; } + /* The writer data lifecycle of a dc_request writer has an + * autodispose policy. This makes it possible to cancel requests + * when the client disconnects from the DS. */ + dds_qset_writer_data_lifecycle(request_wqos, true); + /* if we attach the request_listener now to the request writer here, then it + * is that possible the function triggers before this com_new() function + * has been finished. Because the request listener callback requires + * the com to be initialized (in the dc_is_ds_endpoint() call) this would + * then lead to a crash. For that reason we cannot attach the request listener + * to wr_request here, but we have to do it after com has been initialized + * (in activate_request_listener()). To not miss out on any triggers, we need to + * call dds_get_matched_subscription_data() after com has been initialized */ if ((com->wr_request = dds_create_writer(com->request_publisher, com->tp_request, request_wqos, NULL)) < 0) { DDS_ERROR("failed to create dc request writer [%s]\n", dds_strretcode(-com->wr_request)); goto err_wr_request; @@ -762,15 +847,9 @@ static void dc_com_free (struct com_t *com) return; } -static uint64_t next_request_seq (struct dc_t *dc) +static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader, uint64_t seq) { - (dc->seq)++; - return dc->seq; -} - -static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader) -{ - /* check for publication_matched() on the dc_request writer tomake sure that the request arrives */ + /* check for publication_matched() on the dc_request writer to make sure that the request arrives */ /* create a request */ /* set the request on the pending liust */ /* send the request */ @@ -796,7 +875,7 @@ static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader } request = DurableSupport_request__alloc(); memcpy(request->requestid.client, dc.cfg.id, 16); - request->requestid.seq = next_request_seq(&dc); + request->requestid.seq = seq; request->partitions._length = plen; request->partitions._maximum = plen; request->partitions._buffer = dds_sequence_string_allocbuf(plen); @@ -805,12 +884,11 @@ static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader request->partitions._buffer[i] = ddsrt_strdup(partitions[i]); } request->timeout = DDS_SECS(5); - /* todo: administrate the request */ if ((ret = dds_write(com->wr_request, request)) < 0) { - DDS_ERROR("com_set_bead_write failed [%s]", dds_strretcode(-ret)); + DDS_ERROR("failed to publish dc_request [%s]", dds_strretcode(-ret)); goto err_request_write; } - DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "dc_request sent\n"); + DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "publish dc_request {\"client\":\"%s\", \"seq\":%" PRIu64 "}\n", dc.cfg.id_str, seq); err_request_write: dc_free_partitions(plen, partitions); dds_delete_qos(rqos); @@ -859,14 +937,18 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) { #define MAX_SAMPLES 100 - static void *samples[MAX_SAMPLES]; - static dds_sample_info_t info[MAX_SAMPLES]; + void *samples[MAX_SAMPLES] = { NULL }; + dds_sample_info_t info[MAX_SAMPLES]; int samplecount; int j; + /* dds_read/take allocates memory for the data if samples[0] is a null pointer. + * The memory must be released when done by returning the loan */ + samples[0]= NULL; samplecount = dds_take_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE); if (samplecount < 0) { DDS_ERROR("durable client failed to take ds_status [%s]", dds_strretcode(-samplecount)); + goto err_samplecount; } else { /* call the handler function to process the status sample */ for (j = 0; !dds_triggered(dc->com->ws) && j < samplecount; j++) { @@ -885,6 +967,8 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) } } } + (void)dds_return_loan (rd, samples, samplecount); +err_samplecount: return samplecount; #undef MAX_SAMPLES } @@ -913,13 +997,129 @@ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publicat dds_builtintopic_free_endpoint(ep); } else { /* the endpoint is not available any more. - * Check if the quorom has been lost*/ + * Check if the quorem has been lost */ dc_check_quorum_reached(dc, writer, false); } err_last_subscription_handle: return; } +/* publish a reader request + * The reader request is published as a transient-local topic which is + * keyed by the guid of this client and a monotonically increasing sequence number. + * Even though this is not recommended, this allows multiple requests from the + * same reader (because they have a different sequence number). + * + * For each outgoing request, a pending request entry will be created to administrate + * the outgoing requests. Pending requests can have a expiration. Expired pending + * requests will lead to removal of the pending request, and a dispose of the + * corresponding reader request to prevent that late joining + */ +static struct pending_request_t *dc_publish_reader_request (struct dc_t *dc, dds_entity_t reader, struct dds_rhc *rhc) +{ + struct pending_request_t *pr; + dds_instance_handle_t ih; + dds_return_t rc; + + /* verify if the reader still exists; if not, delete the request */ + if ((rc = dds_get_instance_handle(reader, &ih)) != DDS_RETCODE_OK) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "No need to publish dc_request, reader is not available\n"); + return NULL; + } + /* create a pending request entry and insert it in the table of pending requests */ + if ((pr = (struct pending_request_t *)ddsrt_malloc(sizeof(struct pending_request_t))) == NULL) { + DDS_ERROR("Failed to allocate a reader request\n"); + goto err_alloc_reader_request; + } + memset(pr, 0, sizeof(struct pending_request_t)); + pr->ih = ih; + pr->seq = ++(dc->seq); + pr->reader = reader; + pr->rhc = rhc; + ddsrt_avl_cinsert(&pending_requests_td, &dc->pending_requests, pr); + /* publish the request */ + if ((rc = dc_com_request_write(dc->com, reader, dc->seq)) != DDS_RETCODE_OK) { + DDS_ERROR("Failed to publish dc_request\n"); + goto err_publish_reader_request; + } + return pr; + +err_publish_reader_request: + ddsrt_avl_cdelete(&pending_requests_td, &dc->pending_requests, pr); + cleanup_pending_request(pr); + --(dc->seq); +err_alloc_reader_request: + return NULL; +} + +/* a dc_request reader endpoint on a DS has been found that matched with my dc_request writer */ +static struct matched_request_reader_t *dc_add_matched_request_reader (struct dc_t *dc, dds_builtintopic_endpoint_t *ep, dds_instance_handle_t ih) +{ + struct matched_request_reader_t *mrr; + uint32_t cnt; + char id_str[37]; + + assert(ep); + if ((mrr = ddsrt_avl_clookup (&matched_request_readers_td, &dc->matched_request_readers, &ih)) == NULL) { + mrr = (struct matched_request_reader_t *)ddsrt_malloc(sizeof(struct matched_request_reader_t)); + mrr->ih = ih; + ddsrt_avl_cinsert(&matched_request_readers_td, &dc->matched_request_readers, mrr); + cnt = (uint32_t)ddsrt_avl_ccount(&dc->matched_request_readers); + dc->nr_of_matched_dc_requests = cnt; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "matching dc_request reader \"%s\" discovered (ih: %" PRIx64 ") [%" PRIu32 "]\n", dc_stringify_id(ep->key.v, id_str), ih, cnt); + } + return mrr; +} + +/* a dc_request reader has been lost */ +static void dc_remove_matched_request_reader (struct dc_t *dc, dds_instance_handle_t ih) +{ + struct matched_request_reader_t *mrr; + ddsrt_avl_dpath_t dpath; + uint32_t cnt; + + if ((mrr = ddsrt_avl_clookup_dpath(&matched_request_readers_td, &dc->matched_request_readers, &ih, &dpath)) != NULL) { + ddsrt_avl_cdelete_dpath(&matched_request_readers_td, &dc->matched_request_readers, mrr, &dpath); + cleanup_matched_request_reader(mrr); + cnt = (uint32_t)ddsrt_avl_ccount(&dc->matched_request_readers); + dc->nr_of_matched_dc_requests = cnt; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "matching dc_request reader lost (ih: %" PRIx64 ") [%" PRIu32 "]\n", ih, cnt); + } +} + +/* called when the dc_request writer has been found or lost a matching dc_request reader. + * Due to synchronous triggering we see them all */ +static void default_request_writer_matched_cb (dds_entity_t writer, dds_publication_matched_status_t status, void *arg) +{ + struct dc_t *dc = (struct dc_t *)arg; + dds_instance_handle_t ih; + dds_builtintopic_endpoint_t *ep; + + /* A reader has matched (or lost) with a dc_request writer. */ + /* As long as there is at least one match with a dc_request + * reader located on a ds, we can publish safely publish + * requests. If there is no match with such dc_request reader, + * we have to postpone the publication of dc_request until such + * dc_request reader becomes available. */ + assert(writer); + if ((ih = status.last_subscription_handle) == DDS_HANDLE_NIL) { + DDS_ERROR("failed to receive valid last_subscription_handle\n"); + return; + } + if ((ep = dds_get_matched_subscription_data(writer, ih)) != NULL) { + if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { + /* A dc_request reader on a data container has matched with the dc_request writer. + * From now on it is allowed to publish requests. + * In case there are any pending requests, we can sent them now */ + dc_add_matched_request_reader(dc, ep, ih); + } + dds_builtintopic_free_endpoint(ep); + } else { + /* the dc_request endpoint is not available any more. */ + dc_remove_matched_request_reader(dc, ih); + } +} + static uint32_t recv_handler (void *a) { struct dc_t *dc = (struct dc_t *)a; @@ -945,6 +1145,70 @@ static uint32_t recv_handler (void *a) return 0; } +/* set the request listener to learn about the existence of matching request readers. + * Because matches may have occurred already before */ + +static dds_return_t activate_request_listener (struct dc_t *dc) +{ + dds_return_t rc, ret; + dds_guid_t wguid; + char id_str[37]; + size_t nrds = 128; + dds_instance_handle_t *rd_ihs; + int i; + dds_builtintopic_endpoint_t *ep; + bool selected = false; /* indicates if a dc_request reader is selected to accept our requests */ + + assert(dc); + assert(dc->com); + if ((rc = dds_get_guid(dc->com->wr_request, &wguid)) != DDS_RETCODE_OK) { + DDS_ERROR("failed to retrieve writer guid for request writer"); + goto err_get_guid; + } + if ((rc = dds_set_listener(dc->com->wr_request, dc->request_listener)) < 0) { + DDS_ERROR("Unable to set the request listener on writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); + goto err_set_listener; + } + /* matches for this listener may have occurred before the listener was attached. + * To get these matches, we need to call dds_get_matched_subscriptions(). + * We don't know the size of the array holding the matches beforehand, so + * we dynamically this list. */ + do { + nrds = nrds * 2; + rd_ihs = ddsrt_malloc(nrds * sizeof(dds_instance_handle_t)); + if ((ret = dds_get_matched_subscriptions(dc->com->wr_request, rd_ihs, nrds)) > (int32_t)nrds) { + /* allocated list is too small, use a bigger list */ + ddsrt_free(rd_ihs); + } + } while (ret > (int32_t)nrds); + /* The local host request reader only match requests with a ds on the same host. + * As long as there is at least one match, then we know there is a dc_request reader + * on the local node. If the dc_request reader belongs to a ds, then we have found + * a ds on the local node. */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "request listener activated, currently found %" PRIu32 " matching dc_request readers\n", (uint32_t)ret); + for (i=0; i < ret && !selected; i++) { + /* check if the matched reader belongs to a ds */ + if ((ep = dds_get_matched_subscription_data(dc->com->wr_request, rd_ihs[i])) != NULL) { + if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { + /* A dc_request reader on a DS has matched with the dc_request writer. + * From now on it is allowed to publish requests. + * In case there are any pending requests, we can sent them now */ + dc_add_matched_request_reader(dc, ep, rd_ihs[i]); + } + dds_builtintopic_free_endpoint(ep); + } else { + /* the dc_request endpoint is not available any more. */ + dc_remove_matched_request_reader(dc, rd_ihs[i]); + } + } + ddsrt_free(rd_ihs); + return rc; + +err_set_listener: +err_get_guid: + return DDS_RETCODE_ERROR; +} + dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_domaingv *gv) { dds_return_t rc; @@ -965,17 +1229,29 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom /* Note: dc.cfg.id will be set once we create the participant in dc_com_new() */ dc.cfg.quorum = DEFAULT_QOURUM; /* LH: currently hardcoded set to 1, should be made configurable in future */ dc.cfg.ident = ddsrt_strdup(DEFAULT_IDENT); + dc.selected_request_reader_ih = DDS_HANDLE_NIL; + dc.nr_of_matched_dc_requests = 0; ddsrt_avl_cinit(&server_td, &dc.servers); + ddsrt_avl_cinit(&pending_requests_td, &dc.pending_requests); + ddsrt_avl_cinit(&matched_request_readers_td, &dc.matched_request_readers); + ddsrt_fibheap_init(&pending_requests_fd, &dc.pending_requests_fh); /* create the quorum listener */ if ((dc.quorum_listener = dds_create_listener(&dc)) == NULL) { DDS_ERROR("failed to create quorum listener\n"); goto err_create_quorum_listener; } dds_lset_publication_matched(dc.quorum_listener, default_durable_writer_matched_cb); + /* create the request listener */ + if ((dc.request_listener = dds_create_listener(&dc)) == NULL) { + DDS_ERROR("failed to create request listener\n"); + goto err_create_request_listener; + } + dds_lset_publication_matched(dc.request_listener, default_request_writer_matched_cb); if ((dc.com = dc_com_new(&dc, domainid, gv))== NULL) { DDS_ERROR("failed to initialize the durable client infrastructure\n"); goto err_com_new; } + activate_request_listener(&dc); /* start a thread to process messages coming from a ds */ ddsrt_threadattr_init(&dc.recv_tattr); if ((rc = ddsrt_thread_create(&dc.recv_tid, "dc", &dc.recv_tattr, recv_handler, &dc)) != DDS_RETCODE_OK) { @@ -986,6 +1262,8 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom err_recv_thread: dc_com_free(dc.com); err_com_new: + dds_delete_listener(dc.request_listener); +err_create_request_listener: dds_delete_listener(dc.quorum_listener); err_create_quorum_listener: ddsrt_free(dc.cfg.ident); @@ -1018,7 +1296,11 @@ dds_return_t dds_durability_fini (void) if ((rc = ddsrt_thread_join(dc.recv_tid, NULL)) < 0) { DDS_ERROR("failed to join the dc recv thread [%s]", dds_strretcode(rc)); } + dds_delete_listener(dc.request_listener); + dds_delete_listener(dc.quorum_listener); dc_com_free(dc.com); + ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); + ddsrt_avl_cfree(&pending_requests_td, &dc.pending_requests, cleanup_pending_request); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); ddsrt_free(dc.cfg.ident); } @@ -1032,46 +1314,72 @@ bool dds_durability_is_terminating (void) dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc) { - /* create the administration to store transient data */ - /* create a durability reader that sucks and stores it in the store */ + dds_durability_kind_t dkind; + dds_qos_t *qos, *parqos; + dds_return_t rc = DDS_RETCODE_ERROR; - /* send a request */ - if (dc.com) { - // dc_send_cached_requests(); - dc_com_request_write(dc.com, reader); - } else { - /* todo: apparently a reader is created before com is initialized. - * cache the request until com becomes available */ - // dc_cache_request(reader, rhc); + /* check if the reader is a durable reader from a "real" user application, + * if so, send a request to obtain historical data */ + assert(reader); + qos = dds_create_qos(); + if ((rc = dds_get_qos(reader, qos)) < 0) { + DDS_ERROR("failed to get qos from reader [%s]\n", dds_strretcode(rc)); + goto err_get_qos; } + if (!dds_qget_durability(qos, &dkind)) { + DDS_ERROR("failed to retrieve durability qos\n"); + goto err_qget_durability; + } + if ((dkind == DDS_DURABILITY_TRANSIENT) || (dkind == DDS_DURABILITY_PERSISTENT)) { + dds_entity_t par; + void *userdata; + size_t size = 0; + + /* Creation of a durable reader must only lead to the publication + * of a dc_request when the reader is a "real" application reader. + * If the reader belongs to a participant that carries user data + * containing the IDENT, then the reader is a data container. + * We don't need to generate dc_requests for data containers */ + if ((par = dds_get_participant(reader)) < 0) { + DDS_ERROR("Unable to retrieve the participant of the reader [%s]\n", dds_strretcode(rc)); + goto err_get_participant; + } + if ((parqos = dds_create_qos()) == NULL) { + DDS_ERROR("Failed to allocate qos\n"); + goto err_alloc_parqos; + } + if ((rc = dds_get_qos(par, parqos)) < 0) { + DDS_ERROR("Failed to get topic qos [%s]", dds_strretcode(rc)); + goto err_get_parqos; + } + if (!dds_qget_userdata(parqos, &userdata, &size)) { + DDS_ERROR("Unable to retrieve the participant's user data for reader\n"); + goto err_qget_userdata; + } + if ((size != strlen(IDENT)) || (userdata == NULL) || (strcmp(userdata, IDENT) != 0)) { + /* the user data of the participant for this durable reader does + * not contain the ident, so the endoint is not from a remote DS. + * We can now publish a dc_request for this durable reader. The + * dc_request is published as a transient-local topic. This means + * that a late joining DS will receive the DS as long as the request + * is not yet disposed.*/ + (void)dc_publish_reader_request(&dc, reader, rhc); + } + dds_free(userdata); + dds_delete_qos(parqos); + } + dds_delete_qos(qos); + return rc; - (void)rhc; - (void)reader; - return DDS_RETCODE_OK;; -} - -/* This function checks if the writer has reached the quorum of matching durable containers - * - * It is NOT sufficient to verify if the quorum of durable services is reached. - * If a writer would unblock when the quorum of durable services is reached, then - * it is by no means certain that the durable writer has discovered the corresponding - * data containers of these durable services. Data that has is published before the - * data containers have been discovered by the writers, would not be delivered to - * the data containers. - * - * For this reason, the quorum must be calculated based on the number of discovered - * data containers for a writer. This also implies that if a writer has reached a quorum, - * some other writer may not have reached the quorum yet. - * - * return - * DDS_RETCODE_OK if quorum is reached - * DDS_PRECONDITION_NOT_MET otherwise - */ -dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer) -{ - /* temporarily disabled */ - (void)writer; - return DDS_RETCODE_OK; +err_qget_userdata: +err_get_parqos: + dds_delete_qos(parqos); +err_alloc_parqos: +err_get_participant: +err_qget_durability: +err_get_qos: + dds_delete_qos(qos); + return rc; } dds_return_t dds_durability_new_local_writer (dds_entity_t writer) @@ -1123,7 +1431,7 @@ dds_return_t dds_durability_new_local_writer (dds_entity_t writer) DDS_ERROR("Unable to set the quorum listener on writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); goto err_set_listener; } - dc_check_quorum_reached (&dc, writer, true); + dc_check_quorum_reached(&dc, writer, true); } dds_delete_qos(qos); return DDS_RETCODE_OK; @@ -1159,7 +1467,20 @@ static dds_return_t dds_durability_get_quorum_reached (dds_entity_t writer, bool return ret; } -/* wait for quorum reached, or timeout in case max_blocking_time is expired and quorum not yet reached */ +/* This function waits for a quorum of durable data containers to be available, + * or timeout in case max_blocking_time is expired and quorum not yet reached. + * + * If the quorum is not reached before the max_blocking_time() is expired, + * DDS_RETCODE_PRECONDITION + * + * The quorum is calculated based on the number of discovered and matched data containers + * for a writer. This also implies that if a writer has reached a quorum, + * some other writer may not have reached the quorum yet. + * + * return + * DDS_RETCODE_OK if quorum is reached + * DDS_PRECONDITION_NOT_MET otherwise + */ dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) { dds_return_t ret = DDS_RETCODE_ERROR; @@ -1178,7 +1499,7 @@ dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) * * LH: A better solution would be to wait on a condition variable, * and get notified once the quorum is reached (or the max_blocking_time - * times out) */ + * times out) */ timeout.v = DDS_TIME_INVALID; do { if ((ret = dds_durability_get_quorum_reached(writer, &quorum_reached, &timeout)) != DDS_RETCODE_OK) { From 4a97e034470456ee79d50d42566afc655a26d9aa Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 7 Nov 2023 12:21:29 +0100 Subject: [PATCH 019/207] Make dc_requests transient-local and autodispose, and add the ability dispose requests after a timeout expires Signed-off-by: TheFixer --- .../include/dds/durability/dds_durability.h | 3 - src/durability/src/dds_durability.c | 168 ++++++++++++++++-- 2 files changed, 154 insertions(+), 17 deletions(-) diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h index 0be8256392..83e9033478 100644 --- a/src/durability/include/dds/durability/dds_durability.h +++ b/src/durability/include/dds/durability/dds_durability.h @@ -17,9 +17,6 @@ #include "dds__types.h" #include "dds/ddsc/dds_rhc.h" -/* This is the user data that identifies a durable service */ -#define IDENT "durable_support" - #if defined (__cplusplus) extern "C" { #endif diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 015ac13187..94bcced310 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -67,9 +67,10 @@ struct pending_request_t { ddsrt_fibheap_node_t fhnode; /* represents a node in the priority queue */ dds_instance_handle_t ih; /* the instance handle that represents the reader */ uint64_t seq; /* the sequence number of the request; this is used as the key */ + dds_time_t birth_time; /* time this pending event was created */ dds_entity_t reader; /* the reader that does the request */ struct dds_rhc *rhc; /* reader rhc */ - dds_duration_t exptime; /* expiry time for this pending request */ + dds_time_t exp_time; /* Expire time for this pending request */ }; static int cmp_pending_request (const void *a, const void *b) @@ -91,7 +92,7 @@ static int cmp_exp_time (const void *a, const void *b) struct pending_request_t *pr1 = (struct pending_request_t *)a; struct pending_request_t *pr2 = (struct pending_request_t *)b; - return (pr1->exptime < pr2->exptime) ? -1 : ((pr1->exptime > pr2->exptime) ? 1 : 0); + return (pr1->exp_time < pr2->exp_time) ? -1 : ((pr1->exp_time > pr2->exp_time) ? 1 : 0); } static const ddsrt_avl_ctreedef_t pending_requests_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct pending_request_t, node), offsetof (struct pending_request_t, seq), cmp_pending_request, 0); @@ -140,6 +141,7 @@ struct com_t { dds_entity_t rd_participant; /* participant reader */ dds_entity_t rd_subinfo; /* DCPSSubscription reader */ dds_entity_t rc_subinfo; /* DCPSSubscription read condition */ + dds_entity_t pending_request_guard; /* trigger expiration of pending request */ dds_listener_t *status_listener; /* listener on status topic */ dds_entity_t ws; }; @@ -177,6 +179,8 @@ struct dc_t { dds_listener_t *request_listener; /* listener to check if request reader is available */ ddsrt_avl_ctree_t pending_requests; /* tree containing pending requests */ ddsrt_fibheap_t pending_requests_fh; /* priority queue for pending requests, prioritized by expiry time */ + ddsrt_mutex_t pending_request_mutex; /* pending request queue mutex */ + ddsrt_cond_t pending_request_cond; /* pending request condition */ dds_instance_handle_t selected_request_reader_ih; /* instance handle to matched request reader, DDS_HANDLE_NIL if not available */ ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on a ds that match with my ds writer */ uint32_t nr_of_matched_dc_requests; /* indicates the number of matched dc_request readers for the dc_request writer of this client */ @@ -371,7 +375,7 @@ static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *e dds_return_t rc; void *samples[1] = { NULL }; dds_sample_info_t info[1]; - void *userdata; + void *userdata = NULL; size_t size = 0; char id_str[37]; bool result = false; @@ -739,11 +743,24 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc subinfo read condition [%s]\n", dds_strretcode(-com->rc_subinfo)); goto err_rc_subinfo; } + /* create pending reuqest guard condition */ + if ((com->pending_request_guard = dds_create_guardcondition(com->participant)) < 0) { + DDS_ERROR("failed to create guard condition [%s]\n", dds_strretcode(-com->pending_request_guard)); + goto err_create_pending_request_guard_condition; + } + if ((ret = dds_set_guardcondition(com->pending_request_guard, false)) < 0) { + DDS_ERROR("failed to initialize guard condition [%s]\n", dds_strretcode(-ret)); + goto err_set_guard_condition; + } /* create waitset and attach read conditions */ if ((com->ws = dds_create_waitset(com->participant)) < 0) { DDS_ERROR("failed to create dc waitset [%s]\n", dds_strretcode(-com->ws)); goto err_waitset; } + if ((ret = dds_waitset_attach (com->ws, com->pending_request_guard, com->pending_request_guard)) < 0) { + DDS_ERROR("failed to attach pending request guard condition to waitset [%s]\n", dds_strretcode(-ret)); + goto err_attach_pending_request_guard; + } if ((ret = dds_waitset_attach (com->ws, com->rc_status, com->rd_status)) < 0) { DDS_ERROR("failed to attach dc status reader to waitset [%s]\n", dds_strretcode(-ret)); goto err_attach_rd_status; @@ -776,8 +793,13 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, err_attach_rd_response: dds_waitset_detach(com->ws, com->rc_status); err_attach_rd_status: + dds_waitset_detach(com->ws, com->pending_request_guard); +err_attach_pending_request_guard: dds_delete(com->ws); err_waitset: + dds_delete(com->pending_request_guard); +err_create_pending_request_guard_condition: +err_set_guard_condition: dds_delete(com->rc_subinfo); err_rc_subinfo: dds_delete(com->rd_subinfo); @@ -902,6 +924,11 @@ static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader return DDS_RETCODE_ERROR; } +static dds_return_t dc_com_request_dispose (struct com_t *com, dds_instance_handle_t ih) +{ + return dds_dispose_ih(com->wr_request, ih); +} + static void dc_server_lost (struct dc_t *dc, DurableSupport_status *status) { struct server_t *server; @@ -1004,6 +1031,31 @@ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publicat return; } +static void dc_add_pending_request (struct dc_t *dc, struct pending_request_t *pr) +{ + ddsrt_avl_ipath_t ipath; + dds_return_t ret; + + assert(pr); + ddsrt_mutex_lock(&dc->pending_request_mutex); + if ((ddsrt_avl_clookup_ipath(&pending_requests_td, &dc->pending_requests, &pr->seq, &ipath)) != NULL) { + /* there is already an outstanding reader request for this reader */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "There is already an outstanding reader request with seq %" PRIu64 "\n", pr->seq); + ddsrt_mutex_unlock(&dc->pending_request_mutex); + return; + } + /* pending request not yet available, add it to tree of pending request */ + ddsrt_avl_cinsert(&pending_requests_td, &dc->pending_requests, pr); + ddsrt_fibheap_insert(&pending_requests_fd, &dc->pending_requests_fh, pr); + if (pr == ddsrt_fibheap_min(&pending_requests_fd, &dc->pending_requests_fh)) { + /* trigger the main loop in the recv_handler to recalculate the timeout */ + if ((ret = dds_set_guardcondition(dc->com->pending_request_guard, true)) < 0) { + DDS_ERROR("failed to set pending request guard to true [%s]", dds_strretcode(ret)); + } + } + ddsrt_mutex_unlock(&dc->pending_request_mutex); +} + /* publish a reader request * The reader request is published as a transient-local topic which is * keyed by the guid of this client and a monotonically increasing sequence number. @@ -1020,6 +1072,7 @@ static struct pending_request_t *dc_publish_reader_request (struct dc_t *dc, dds struct pending_request_t *pr; dds_instance_handle_t ih; dds_return_t rc; + dds_time_t now = dds_time(); /* verify if the reader still exists; if not, delete the request */ if ((rc = dds_get_instance_handle(reader, &ih)) != DDS_RETCODE_OK) { @@ -1032,14 +1085,27 @@ static struct pending_request_t *dc_publish_reader_request (struct dc_t *dc, dds goto err_alloc_reader_request; } memset(pr, 0, sizeof(struct pending_request_t)); - pr->ih = ih; - pr->seq = ++(dc->seq); + pr->birth_time = now; + pr->ih = ih; /* handle that corresponds to the reader for which this request is done; key for the pending_request tree */ + pr->seq = ++(dc->seq); /* sequence number; key for the fibheap tree */ pr->reader = reader; pr->rhc = rhc; - ddsrt_avl_cinsert(&pending_requests_td, &dc->pending_requests, pr); + /* LH: We currently never dispose a request to a DS on the same hos + * (which is the only mode we currently support for now). In this way + * a disconnect with the DS will lead to a dispose of the request + * on the DS (by virtue of the autodispose property). A reconnect with + * the DS will lead to the request being received again. + * Once we allow sending requests to (multiple) remote DSs, we need to + * implement a mechanism to detect a disconnect with the DS, and + * perhaps choose to another DS to send a request. + * We also need to cancel requests to DSs that have not responded yet in + * case we received the required data from one of the DSs */ + pr->exp_time = DDS_NEVER; + /* add the pending request */ + dc_add_pending_request(dc, pr); /* publish the request */ if ((rc = dc_com_request_write(dc->com, reader, dc->seq)) != DDS_RETCODE_OK) { - DDS_ERROR("Failed to publish dc_request\n"); + DDS_ERROR("Failed to publish dc_request #%" PRIu64 "\n", dc->seq); goto err_publish_reader_request; } return pr; @@ -1047,11 +1113,35 @@ static struct pending_request_t *dc_publish_reader_request (struct dc_t *dc, dds err_publish_reader_request: ddsrt_avl_cdelete(&pending_requests_td, &dc->pending_requests, pr); cleanup_pending_request(pr); - --(dc->seq); err_alloc_reader_request: return NULL; } +/* dispose the request with key 'seq' */ +static void dc_dispose_reader_request (struct dc_t *dc, uint64_t seq) +{ + dds_return_t rc; + dds_instance_handle_t ih; + DurableSupport_request request; + + /* create a dummy request containing the key fields to retrieve the instance handle */ + memcpy(request.requestid.client, dc->cfg.id, 16); + request.requestid.seq = seq; + if ((ih = dds_lookup_instance(dc->com->wr_request, &request)) == DDS_HANDLE_NIL) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dc_request #%" PRIu64 " not available, nothing to dispose\n", seq); + return; + } + if ((rc = dc_com_request_dispose(dc->com, ih)) != DDS_RETCODE_OK) { + DDS_ERROR("Failed to dispose dc_request #%" PRIu64 " [%s]\n", seq, dds_strretcode(-rc)); + goto err_dispose_reader_request; + } + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dispose dc_request {\"client\":\"%s\", \"seq\":%" PRIu64 "}\n", dc->cfg.id_str, seq); + return; + +err_dispose_reader_request: + return; +} + /* a dc_request reader endpoint on a DS has been found that matched with my dc_request writer */ static struct matched_request_reader_t *dc_add_matched_request_reader (struct dc_t *dc, dds_builtintopic_endpoint_t *ep, dds_instance_handle_t ih) { @@ -1120,12 +1210,48 @@ static void default_request_writer_matched_cb (dds_entity_t writer, dds_publicat } } +/* handle expired pending request and determine the next timeout */ +static void dc_process_pending_request_guard (struct dc_t *dc, dds_time_t *timeout) +{ + dds_return_t ret; + struct pending_request_t *pr; + dds_time_t now = dds_time(); + + ddsrt_mutex_lock(&dc->pending_request_mutex); + do { + pr = ddsrt_fibheap_min(&pending_requests_fd, &dc->pending_requests_fh); + if ((pr == NULL) || (now < pr->exp_time)) { + /* there is no pending request, or the first pending request is not yet expired */ + break; + } + /* The head is expired. Remove the pending request from the priority queue + * and dispose it to prevent that a DS reacts to an expired request */ + if ((pr = ddsrt_fibheap_extract_min(&pending_requests_fd, &dc->pending_requests_fh)) != NULL) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "process pending request %" PRIu64 "\n", pr->seq); + dc_dispose_reader_request(dc, pr->seq); + cleanup_pending_request(pr); + } + } while (true); + /* recalculate the remaining timeout */ + *timeout = (pr == NULL) ? DDS_NEVER : pr->exp_time; + if ((ret = dds_set_guardcondition(dc->com->pending_request_guard, false)) < 0) { + DDS_ERROR("failed to set pending request guard to false [%s]", dds_strretcode(ret)); + } + if (*timeout != DDS_NEVER) { + dds_duration_t tnext = *timeout - now; + int64_t sec = (int64_t)(tnext / DDS_NSECS_IN_SEC); + uint32_t usec = (uint32_t)((tnext % DDS_NSECS_IN_SEC) / DDS_NSECS_IN_USEC); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "next pending request timeout at %" PRId64 ".%06" PRIu32 "s\n", sec, usec); + } + ddsrt_mutex_unlock(&dc->pending_request_mutex); +} + static uint32_t recv_handler (void *a) { struct dc_t *dc = (struct dc_t *)a; - dds_duration_t timeout = DDS_INFINITY; - dds_attach_t wsresults[1]; - size_t wsresultsize = sizeof(wsresults)/sizeof(wsresults[0]); + dds_time_t timeout = DDS_NEVER; + dds_attach_t wsresults[2]; + size_t wsresultsize = sizeof(wsresults) / sizeof(wsresults[0]); int n, j; DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "start durable client thread\n"); @@ -1137,8 +1263,13 @@ static uint32_t recv_handler (void *a) for (j=0; j < n && (size_t)j < wsresultsize; j++) { if (wsresults[j] == dc->com->rd_status) { dc_process_status(dc->com->rd_status, dc); + } else if (wsresults[j] == dc->com->pending_request_guard) { + dc_process_pending_request_guard(dc, &timeout); } } + } else { + /* timeout */ + dc_process_pending_request_guard(dc, &timeout); } } DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "stop durable client thread\n"); @@ -1232,9 +1363,11 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom dc.selected_request_reader_ih = DDS_HANDLE_NIL; dc.nr_of_matched_dc_requests = 0; ddsrt_avl_cinit(&server_td, &dc.servers); - ddsrt_avl_cinit(&pending_requests_td, &dc.pending_requests); ddsrt_avl_cinit(&matched_request_readers_td, &dc.matched_request_readers); + ddsrt_avl_cinit(&pending_requests_td, &dc.pending_requests); ddsrt_fibheap_init(&pending_requests_fd, &dc.pending_requests_fh); + ddsrt_mutex_init(&dc.pending_request_mutex); + ddsrt_cond_init(&dc.pending_request_cond); /* create the quorum listener */ if ((dc.quorum_listener = dds_create_listener(&dc)) == NULL) { DDS_ERROR("failed to create quorum listener\n"); @@ -1266,6 +1399,11 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom err_create_request_listener: dds_delete_listener(dc.quorum_listener); err_create_quorum_listener: + ddsrt_cond_destroy(&dc.pending_request_cond); + ddsrt_mutex_destroy(&dc.pending_request_mutex); + ddsrt_avl_cfree(&pending_requests_td, &dc.pending_requests, cleanup_pending_request); + ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); + ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); ddsrt_free(dc.cfg.ident); return DDS_RETCODE_ERROR; } @@ -1299,6 +1437,8 @@ dds_return_t dds_durability_fini (void) dds_delete_listener(dc.request_listener); dds_delete_listener(dc.quorum_listener); dc_com_free(dc.com); + ddsrt_cond_destroy(&dc.pending_request_cond); + ddsrt_mutex_destroy(&dc.pending_request_mutex); ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); ddsrt_avl_cfree(&pending_requests_td, &dc.pending_requests, cleanup_pending_request); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); @@ -1356,9 +1496,9 @@ dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rh DDS_ERROR("Unable to retrieve the participant's user data for reader\n"); goto err_qget_userdata; } - if ((size != strlen(IDENT)) || (userdata == NULL) || (strcmp(userdata, IDENT) != 0)) { + if ((size != strlen(dc.cfg.ident)) || (userdata == NULL) || (strcmp(userdata, dc.cfg.ident) != 0)) { /* the user data of the participant for this durable reader does - * not contain the ident, so the endoint is not from a remote DS. + * not contain the ident, so the endpoint is not from a remote DS. * We can now publish a dc_request for this durable reader. The * dc_request is published as a transient-local topic. This means * that a late joining DS will receive the DS as long as the request From 341c95fb006941423a64ef910aa53d0a9db92ebc Mon Sep 17 00:00:00 2001 From: TheFixer Date: Mon, 13 Nov 2023 10:30:33 +0100 Subject: [PATCH 020/207] Add additional check on the length of topic names in dc_requests Signed-off-by: TheFixer --- src/durability/src/dds_durability.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 94bcced310..4d96d4aab4 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -869,6 +869,8 @@ static void dc_com_free (struct com_t *com) return; } +#define MAX_TOPIC_NAME_SIZE 255 + static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader, uint64_t seq) { /* check for publication_matched() on the dc_request writer to make sure that the request arrives */ @@ -882,6 +884,8 @@ static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader dds_return_t ret = DDS_RETCODE_OK; uint32_t plen, i; char **partitions; + dds_entity_t topic; + char tpname[MAX_TOPIC_NAME_SIZE]; if ((rqos = dds_create_qos()) == NULL) { DDS_ERROR("Unable to create reader qos for dc_request"); @@ -895,6 +899,17 @@ static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader DDS_ERROR("Failed to retrieve partition qos for dc_request"); goto err_qget_partition; } + if ((topic = dds_get_topic(reader)) < 0) { + DDS_ERROR("Failed to get topic for reader [%s]", dds_strretcode(topic)); + goto err_get_topic; + } + if ((ret = dds_get_name(topic, tpname, sizeof(tpname))) < 0) { + DDS_ERROR("Failed to get topic name from reader [%s]", dds_strretcode(ret)); + goto err_get_name; + } else if (ret > MAX_TOPIC_NAME_SIZE) { + DDS_ERROR("topic name '%s...', name too long [%s]", tpname, dds_strretcode(ret)); + goto err_get_name_size; + } request = DurableSupport_request__alloc(); memcpy(request->requestid.client, dc.cfg.id, 16); request->requestid.seq = seq; @@ -905,12 +920,17 @@ static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader for (i=0; i < plen; i++) { request->partitions._buffer[i] = ddsrt_strdup(partitions[i]); } + request->tpname = ddsrt_strdup(tpname); request->timeout = DDS_SECS(5); if ((ret = dds_write(com->wr_request, request)) < 0) { DDS_ERROR("failed to publish dc_request [%s]", dds_strretcode(-ret)); goto err_request_write; } DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "publish dc_request {\"client\":\"%s\", \"seq\":%" PRIu64 "}\n", dc.cfg.id_str, seq); + +err_get_topic: +err_get_name: +err_get_name_size: err_request_write: dc_free_partitions(plen, partitions); dds_delete_qos(rqos); @@ -1099,7 +1119,7 @@ static struct pending_request_t *dc_publish_reader_request (struct dc_t *dc, dds * implement a mechanism to detect a disconnect with the DS, and * perhaps choose to another DS to send a request. * We also need to cancel requests to DSs that have not responded yet in - * case we received the required data from one of the DSs */ + * case we received the required data from one of the DSs */ pr->exp_time = DDS_NEVER; /* add the pending request */ dc_add_pending_request(dc, pr); From e792bf6ba70c1b0d048f70b7e8e422d2a59000ec Mon Sep 17 00:00:00 2001 From: TheFixer Date: Wed, 15 Nov 2023 11:25:22 +0100 Subject: [PATCH 021/207] Rebase the expose-seqnum-via-sampleinfo on current master Signed-off-by: TheFixer --- docs/manual/config/config_file_reference.rst | 4 ++-- docs/manual/options.md | 4 ++-- etc/cyclonedds.rnc | 4 ++-- etc/cyclonedds.xsd | 4 ++-- src/core/ddsi/defconfig.c | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index 639f6c9896..251f0e5f01 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -2645,8 +2645,8 @@ The default value is: ``none`` .. generated from ddsi_config.h[570f67bd3080674a4bad53d9580a8bb7ad1e6e4d] generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] - generated from ddsi__cfgelems.h[d4d0b8c7cf61f0a1cfa4b62e02458cf7b8962536] - generated from ddsi_config.c[efeae198a5e12ca8977a655216470564b5c44b64] + generated from ddsi__cfgelems.h[de6d6357eef2d532b2450cec9732702107d2a03c] + generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] diff --git a/docs/manual/options.md b/docs/manual/options.md index 1e326d0186..b0fc932d1b 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -1849,8 +1849,8 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: `none` - - + + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index d313715aa7..aa08354fe2 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -1285,8 +1285,8 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
    } # generated from ddsi_config.h[570f67bd3080674a4bad53d9580a8bb7ad1e6e4d] # generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] -# generated from ddsi__cfgelems.h[d4d0b8c7cf61f0a1cfa4b62e02458cf7b8962536] -# generated from ddsi_config.c[efeae198a5e12ca8977a655216470564b5c44b64] +# generated from ddsi__cfgelems.h[de6d6357eef2d532b2450cec9732702107d2a03c] +# generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] # generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] # generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] # generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index 62d391da87..f99660f865 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -1941,8 +1941,8 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - - + + diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index 814d0d5ef5..b8e93bb381 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -101,8 +101,8 @@ void ddsi_config_init_default (struct ddsi_config *cfg) } /* generated from ddsi_config.h[570f67bd3080674a4bad53d9580a8bb7ad1e6e4d] */ /* generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] */ -/* generated from ddsi__cfgelems.h[d4d0b8c7cf61f0a1cfa4b62e02458cf7b8962536] */ -/* generated from ddsi_config.c[efeae198a5e12ca8977a655216470564b5c44b64] */ +/* generated from ddsi__cfgelems.h[de6d6357eef2d532b2450cec9732702107d2a03c] */ +/* generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] */ /* generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] */ /* generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] */ /* generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] */ From b829bc6a9317cea5f5b74510cccd537a2c745ca1 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 17 Nov 2023 16:32:28 +0100 Subject: [PATCH 022/207] Implement receiving dc_response from a DS Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 78 +++++++ src/durability/src/dds_durability.c | 172 +++++++++++++- src/durability/src/durablesupport.c | 217 ++++++++++++++++++ 3 files changed, 462 insertions(+), 5 deletions(-) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index 1318821ee9..8497b3e663 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -254,6 +254,11 @@ typedef int64_t DurableSupport_duration_t; #define DurableSupport_duration_t__alloc() \ ((DurableSupport_duration_t*) dds_alloc (sizeof (DurableSupport_duration_t))); +typedef uint16_t DurableSupport_responsetype_t; + +#define DurableSupport_responsetype_t__alloc() \ +((DurableSupport_responsetype_t*) dds_alloc (sizeof (DurableSupport_responsetype_t))); + typedef struct DurableSupport_request_id_t { DurableSupport_id_t client; @@ -301,6 +306,79 @@ extern const dds_topic_descriptor_t DurableSupport_request_desc; #define DurableSupport_request_free(d,o) \ dds_sample_free ((d), &DurableSupport_request_desc, (o)) +#define DurableSupport_RESPONSETYPE_SET 1 +#define DurableSupport_RESPONSETYPE_DATA 2 +#ifndef DDS_SEQUENCE_DURABLESUPPORT_REQUEST_ID_T_DEFINED +#define DDS_SEQUENCE_DURABLESUPPORT_REQUEST_ID_T_DEFINED +typedef struct dds_sequence_DurableSupport_request_id_t +{ + uint32_t _maximum; + uint32_t _length; + struct DurableSupport_request_id_t *_buffer; + bool _release; +} dds_sequence_DurableSupport_request_id_t; + +#define dds_sequence_DurableSupport_request_id_t__alloc() \ +((dds_sequence_DurableSupport_request_id_t*) dds_alloc (sizeof (dds_sequence_DurableSupport_request_id_t))); + +#define dds_sequence_DurableSupport_request_id_t_allocbuf(l) \ +((struct DurableSupport_request_id_t *) dds_alloc ((l) * sizeof (struct DurableSupport_request_id_t))) +#endif /* DDS_SEQUENCE_DURABLESUPPORT_REQUEST_ID_T_DEFINED */ + +typedef struct DurableSupport_response_set_t +{ + char * partition; + char * tpname; + uint32_t flags; + dds_sequence_DurableSupport_request_id_t requestids; +} DurableSupport_response_set_t; + +#ifndef DDS_SEQUENCE_OCTET_DEFINED +#define DDS_SEQUENCE_OCTET_DEFINED +typedef struct dds_sequence_octet +{ + uint32_t _maximum; + uint32_t _length; + uint8_t *_buffer; + bool _release; +} dds_sequence_octet; + +#define dds_sequence_octet__alloc() \ +((dds_sequence_octet*) dds_alloc (sizeof (dds_sequence_octet))); + +#define dds_sequence_octet_allocbuf(l) \ +((uint8_t *) dds_alloc ((l) * sizeof (uint8_t))) +#endif /* DDS_SEQUENCE_OCTET_DEFINED */ + +typedef struct DurableSupport_response_data_t +{ + dds_sequence_octet blob; +} DurableSupport_response_data_t; + +typedef struct DurableSupport_response_content +{ + DurableSupport_responsetype_t _d; + union + { + struct DurableSupport_response_set_t set; + struct DurableSupport_response_data_t data; + } _u; +} DurableSupport_response_content; + +typedef struct DurableSupport_response +{ + DurableSupport_id_t id; + struct DurableSupport_response_content body; +} DurableSupport_response; + +extern const dds_topic_descriptor_t DurableSupport_response_desc; + +#define DurableSupport_response__alloc() \ +((DurableSupport_response*) dds_alloc (sizeof (DurableSupport_response))); + +#define DurableSupport_response_free(d,o) \ +dds_sample_free ((d), &DurableSupport_response_desc, (o)) + #ifdef __cplusplus } #endif diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 4d96d4aab4..5bd93dddd2 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -29,6 +29,12 @@ #define TRACE(...) DDS_CLOG (DDS_LC_DUR, &domaingv->logconfig, __VA_ARGS__) +/************* start of common functions ****************/ +/* LH: + * The following functions are duplicated from their equivalents used by the ds + * In future we might want to create a common library that is used both by ds and dc. + */ + static char *dc_stringify_id(const DurableSupport_id_t id, char *buf) { assert(buf); @@ -38,6 +44,119 @@ static char *dc_stringify_id(const DurableSupport_id_t id, char *buf) return buf; } +static char *dc_responsetype_image (DurableSupport_responsetype_t type) +{ + switch (type) { + case DurableSupport_RESPONSETYPE_SET: + return "set"; + case DurableSupport_RESPONSETYPE_DATA: + return "data"; + default: + return "?"; + } +} + +static char *dc_blob_image (dds_sequence_octet blob) +{ + char *buf; + uint32_t len; + uint32_t n; + uint32_t i; + +#define BLOB_IMAGE_SIZE 24 + len = (blob._length < BLOB_IMAGE_SIZE) ? blob._length : BLOB_IMAGE_SIZE; + n = len*2+1; + buf = ddsrt_malloc(n); + if (len < BLOB_IMAGE_SIZE) { + for (i=0; i < len; i++) { + sprintf(buf+i*2, "%02x", (char)blob._buffer[i]); + } + } else { + for (i=0; i < 11; i++) { + sprintf(buf+i*2, "%02x", (char)blob._buffer[i]); + } + strcpy(buf+22, "..."); + for (i=0; i < 11; i++) { + sprintf(buf+25+i*2, "%02x", (char)blob._buffer[len-11+i]); + } + } + buf[2*len] = '\0'; +#undef BLOB_IMAGE_SIZE + return buf; +} + +static int dc_stringify_response (char *buf, size_t n, const DurableSupport_response *response) +{ + size_t i = 0, j = 0; + int l; + char *str; + char id_str[37]; + + if (buf == NULL) { + goto err; + } + if (response == NULL) { + buf[0] = '\0'; + return 0; + } + if ((l = snprintf(buf+i, n-i, "{\"id\":\"%s\", \"type\":\"%s\", \"content\":{", dc_stringify_id(response->id, id_str), dc_responsetype_image(response->body._d))) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + switch (response->body._d) { + case DurableSupport_RESPONSETYPE_SET : + if ((l = snprintf(buf+i, n-i, "\"partition\":\"%s\", \"tpname\":\"%s\", \"flags\":\"0x%04" PRIx32 "\", \"requestids\":[", response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.flags)) < 0) { + goto err; + } + i += (size_t)l; + for (j=0; j < response->body._u.set.requestids._length; j++) { + DurableSupport_request_id_t requestid = response->body._u.set.requestids._buffer[j]; + if ((l = snprintf(buf+i, n-(size_t)i, "%s{\"client\":\"%s\", \"seq\":%" PRIu64 "}", (j==0) ? "" : ",", dc_stringify_id(requestid.client, id_str), requestid.seq)) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + } + if (i < n) { + buf[i++] = ']'; + } + break; + case DurableSupport_RESPONSETYPE_DATA : + str = dc_blob_image(response->body._u.data.blob); + if ((l = snprintf(buf+i, n-i, "\"blob\":\"%s\"", str)) < 0) { + ddsrt_free(str); + goto err; + } + ddsrt_free(str); + i += (size_t)l; + break; + default: + goto err; + } + if (i < n) { + buf[i++] = '}'; + } + if (i < n) { + buf[i++] = '}'; + } +trunc: + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_response failed, type: %" PRIu16 ", buf: %s\n", response->body._d, !buf ? "NULL" : buf); + return -1; +} + +/****** end of common functions *******/ + struct server_t { ddsrt_avl_node_t node; DurableSupport_id_t id; /* id key */ @@ -709,7 +828,9 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc response subscriber [%s]\n", dds_strretcode(-com->response_subscriber)); goto err_response_subscriber; } - if ((com->tp_response = dds_create_topic (com->participant, &DurableSupport_bead_desc, "dc_response", tqos, NULL)) < 0) { + dds_qset_durability(tqos, DDS_DURABILITY_VOLATILE); + dds_qset_history(tqos, DDS_HISTORY_KEEP_ALL, DDS_LENGTH_UNLIMITED); + if ((com->tp_response = dds_create_topic (com->participant, &DurableSupport_response_desc, "dc_response", tqos, NULL)) < 0) { DDS_ERROR("failed to create dc response topic [%s]\n", dds_strretcode(-com->tp_response)); goto err_tp_response; } @@ -921,7 +1042,8 @@ static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader request->partitions._buffer[i] = ddsrt_strdup(partitions[i]); } request->tpname = ddsrt_strdup(tpname); - request->timeout = DDS_SECS(5); +// request->timeout = DDS_SECS(5); + request->timeout = DDS_INFINITY; if ((ret = dds_write(com->wr_request, request)) < 0) { DDS_ERROR("failed to publish dc_request [%s]", dds_strretcode(-ret)); goto err_request_write; @@ -1020,6 +1142,44 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } +static int dc_process_response (dds_entity_t rd, struct dc_t *dc) +{ +#define MAX_SAMPLES 100 + + void *samples[MAX_SAMPLES]; + dds_sample_info_t info[MAX_SAMPLES]; + int samplecount; + int j; + + /* dds_read/take allocates memory for the data if samples[0] is a null pointer. + * The memory must be released when done by returning the loan */ + samples[0] = NULL; + samplecount = dds_take_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE); + if (samplecount < 0) { + DDS_ERROR("failed to take dc_response [%s]", dds_strretcode(-samplecount)); + goto err_samplecount; + } else { + /* process the response + * we ignore invalid samples and only process valid responses */ + for (j = 0; !dds_triggered(dc->com->ws) && j < samplecount; j++) { + DurableSupport_response *response = (DurableSupport_response *)samples[j]; + char str[1024] = { 0 }; /* max string representation size */ + int l; + if (info[j].valid_data && ((l = dc_stringify_response(str, sizeof(str), response)) > 0)) { + size_t len = (size_t)l; + + /* LH: TODO: add statistics for responses */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dc_response %s%s\n", str, (len >= sizeof(str)) ? "..(trunc)" : ""); + } + } + } + (void)dds_return_loan (rd, samples, samplecount); +err_samplecount: + return samplecount; + +#undef MAX_SAMPLES +} + /* called when there is a match for a durable writer */ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publication_matched_status_t status, void *arg) { @@ -1110,14 +1270,14 @@ static struct pending_request_t *dc_publish_reader_request (struct dc_t *dc, dds pr->seq = ++(dc->seq); /* sequence number; key for the fibheap tree */ pr->reader = reader; pr->rhc = rhc; - /* LH: We currently never dispose a request to a DS on the same hos + /* LH: We currently never explicitly dispose a request to a DS on the same host * (which is the only mode we currently support for now). In this way * a disconnect with the DS will lead to a dispose of the request * on the DS (by virtue of the autodispose property). A reconnect with * the DS will lead to the request being received again. * Once we allow sending requests to (multiple) remote DSs, we need to * implement a mechanism to detect a disconnect with the DS, and - * perhaps choose to another DS to send a request. + * perhaps choose another DS to send a request to. * We also need to cancel requests to DSs that have not responded yet in * case we received the required data from one of the DSs */ pr->exp_time = DDS_NEVER; @@ -1270,7 +1430,7 @@ static uint32_t recv_handler (void *a) { struct dc_t *dc = (struct dc_t *)a; dds_time_t timeout = DDS_NEVER; - dds_attach_t wsresults[2]; + dds_attach_t wsresults[3]; size_t wsresultsize = sizeof(wsresults) / sizeof(wsresults[0]); int n, j; @@ -1283,6 +1443,8 @@ static uint32_t recv_handler (void *a) for (j=0; j < n && (size_t)j < wsresultsize; j++) { if (wsresults[j] == dc->com->rd_status) { dc_process_status(dc->com->rd_status, dc); + } else if (wsresults[j] == dc->com->rd_response) { + dc_process_response(dc->com->rd_response, dc); } else if (wsresults[j] == dc->com->pending_request_guard) { dc_process_pending_request_guard(dc, &timeout); } diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index 4a19d54e8f..019dc51c7b 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -798,3 +798,220 @@ const dds_topic_descriptor_t DurableSupport_request_desc = .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request } }; +static const uint32_t DurableSupport_response_ops [] = +{ + /* response */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_response, id), 16u, + DDS_OP_ADR | DDS_OP_TYPE_EXT, offsetof (DurableSupport_response, body), (3u << 16u) + 4u /* response_content */, + DDS_OP_RTS, + + /* response_content */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_response_content, _d), 2u, (12u << 16u) + 4u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 9 /* response_set_t */, 1, offsetof (DurableSupport_response_content, _u.set), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 24 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, + DDS_OP_RTS, + + /* response_set_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, partition), + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, tpname), + DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_response_set_t, flags), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_response_set_t, requestids), sizeof (DurableSupport_request_id_t), (4u << 16u) + 5u /* request_id_t */, + DDS_OP_RTS, + + /* request_id_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), + DDS_OP_RTS, + + /* response_data_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_response_data_t, blob), + DDS_OP_RTS, + + /* key: id */ + DDS_OP_KOF | 1, 1u /* order: 0 */ +}; + +static const dds_key_descriptor_t DurableSupport_response_keys[1] = +{ + { "id", 45, 0 } +}; + +/* Type Information: + [MINIMAL 930d49afed28329dc1db60ef7617] (#deps: 6) + - [MINIMAL 43f53a2be35b432cc735e9431a89] + - [MINIMAL 6bc43f8b4741bc316540a0ef7b88] + - [MINIMAL 80455e796dd3437163cb532089da] + - [MINIMAL 82d72a61dfdf9b101310caab1550] + - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] + - [MINIMAL a580b28d8a19d4a49d2794aae844] + [COMPLETE 75c71ab3f8db547e64f5b5212bc9] (#deps: 6) + - [COMPLETE aca4d5a256d39713924333e85c6d] + - [COMPLETE 699d1f1db9ab7829fc4aa3be1028] + - [COMPLETE eec1bad6badde73f40ef199fedcc] + - [COMPLETE cb1a215003014659ba61115bccb5] + - [COMPLETE 852fffc913b7ee54aadae7a1859a] + - [COMPLETE 008875599776c39ce0c1fe897846] +*/ +#define TYPE_INFO_CDR_DurableSupport_response (const unsigned char []){ \ + 0x80, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x93, 0x0d, 0x49, 0xaf, 0xed, 0x28, 0x32, 0x9d, 0xc1, 0xdb, 0x60, \ + 0xef, 0x76, 0x17, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, 0x41, 0xbc, 0x31, 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0x00, \ + 0x7c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ + 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x82, 0xd7, 0x2a, 0x61, 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, 0x15, 0x50, 0x00, \ + 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ + 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ + 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x75, 0xc7, 0x1a, 0xb3, 0xf8, 0xdb, 0x54, 0x7e, 0x64, 0xf5, 0xb5, \ + 0x21, 0x2b, 0xc9, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x69, 0x9d, 0x1f, 0x1d, 0xb9, 0xab, 0x78, 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0x00, \ + 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, \ + 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xcb, 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, 0x5b, 0xcc, 0xb5, 0x00, \ + 0xbd, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ + 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ + 0x57, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_response 388u +#define TYPE_MAP_CDR_DurableSupport_response (const unsigned char []){ \ + 0x58, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0x93, 0x0d, 0x49, 0xaf, 0xed, 0x28, 0x32, \ + 0x9d, 0xc1, 0xdb, 0x60, 0xef, 0x76, 0x17, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, \ + 0x41, 0xbc, 0x31, 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ + 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, \ + 0x41, 0xbc, 0x31, 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ + 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ + 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ + 0x54, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf1, 0x82, 0xd7, 0x2a, 0x61, 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, 0x15, \ + 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ + 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ + 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ + 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x82, 0xd7, 0x2a, 0x61, \ + 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, 0x15, 0x50, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x7e, 0x75, 0xc0, 0xed, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, \ + 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, \ + 0x01, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, \ + 0x22, 0xa4, 0x7c, 0x2c, 0x0f, 0x37, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, \ + 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, \ + 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, \ + 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0xc3, 0x03, 0x00, 0x00, \ + 0x07, 0x00, 0x00, 0x00, 0xf2, 0x75, 0xc7, 0x1a, 0xb3, 0xf8, 0xdb, 0x54, 0x7e, 0x64, 0xf5, 0xb5, \ + 0x21, 0x2b, 0xc9, 0x00, 0x83, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ + 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x69, \ + 0x9d, 0x1f, 0x1d, 0xb9, 0xab, 0x78, 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, \ + 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x69, 0x9d, 0x1f, \ + 0x1d, 0xb9, 0xab, 0x78, 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0x00, 0xb3, 0x00, 0x00, 0x00, \ + 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, \ + 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xcb, \ + 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, 0x5b, 0xcc, 0xb5, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x00, \ + 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, \ + 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, \ + 0xed, 0xcc, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, \ + 0x00, 0xf2, 0xcb, 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, 0x5b, 0xcc, 0xb5, \ + 0xb9, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, \ + 0x5f, 0x74, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, \ + 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x64, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, \ + 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x7a, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x02, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ + 0x46, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, \ + 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, \ + 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0x75, 0xc7, 0x1a, \ + 0xb3, 0xf8, 0xdb, 0x54, 0x7e, 0x64, 0xf5, 0xb5, 0x21, 0x2b, 0xc9, 0xf1, 0x93, 0x0d, 0x49, 0xaf, \ + 0xed, 0x28, 0x32, 0x9d, 0xc1, 0xdb, 0x60, 0xef, 0x76, 0x17, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, \ + 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x69, 0x9d, 0x1f, 0x1d, 0xb9, 0xab, 0x78, \ + 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, 0x41, 0xbc, 0x31, \ + 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ + 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, \ + 0x53, 0x20, 0x89, 0xda, 0xf2, 0xcb, 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, \ + 0x5b, 0xcc, 0xb5, 0xf1, 0x82, 0xd7, 0x2a, 0x61, 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, \ + 0x15, 0x50, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, \ + 0x9a, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, \ + 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0xf1, \ + 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_response 1790u +const dds_topic_descriptor_t DurableSupport_response_desc = +{ + .m_size = sizeof (DurableSupport_response), + .m_align = dds_alignof (DurableSupport_response), + .m_flagset = DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 1u, + .m_typename = "DurableSupport::response", + .m_keys = DurableSupport_response_keys, + .m_nops = 22, + .m_ops = DurableSupport_response_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_response, .sz = TYPE_INFO_CDR_SZ_DurableSupport_response }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_response, .sz = TYPE_MAP_CDR_SZ_DurableSupport_response } +}; + From c057bfdbf745cfd3f2706fab1aae2bb0f3f0aac2 Mon Sep 17 00:00:00 2001 From: Michel van den Hoek Date: Tue, 21 Nov 2023 13:24:00 +0100 Subject: [PATCH 023/207] expose symbols when building with durable support, fix goto labels Signed-off-by: Michel van den Hoek --- src/core/CMakeLists.txt | 2 +- src/durability/src/dds_durability.c | 21 +++++++++------------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 6fb6ea19e9..681deac517 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -13,7 +13,7 @@ include (GenerateExportHeader) add_library(ddsc) -if(BUILD_TESTING) +if(BUILD_TESTING OR ENABLE_DURABILITY) set_property(TARGET ddsc PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS TRUE) else() set_property(TARGET ddsc PROPERTY C_VISIBILITY_PRESET hidden) diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 5bd93dddd2..2544344ee2 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -492,12 +492,13 @@ static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *e dds_builtintopic_participant_t *participant; dds_instance_handle_t ih; dds_return_t rc; - void *samples[1] = { NULL }; + void *samples[1]; dds_sample_info_t info[1]; void *userdata = NULL; size_t size = 0; char id_str[37]; bool result = false; + samples[0] = NULL; assert(ep); /* by convention, if the ident == NULL then return true */ @@ -532,13 +533,13 @@ static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *e } dds_free(userdata); } - (void)dds_return_loan (com->rd_participant, samples, rc); + (void)dds_return_loan(com->rd_participant, samples, rc); return result; -err_lookup_instance: -err_read_instance: - (void)dds_return_loan (com->rd_participant, samples, rc); err_qget_userdata: + (void)dds_return_loan(com->rd_participant, samples, rc); +err_read_instance: +err_lookup_instance: return false; } @@ -1106,7 +1107,7 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) { #define MAX_SAMPLES 100 - void *samples[MAX_SAMPLES] = { NULL }; + void *samples[MAX_SAMPLES]; dds_sample_info_t info[MAX_SAMPLES]; int samplecount; int j; @@ -1117,7 +1118,6 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) samplecount = dds_take_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE); if (samplecount < 0) { DDS_ERROR("durable client failed to take ds_status [%s]", dds_strretcode(-samplecount)); - goto err_samplecount; } else { /* call the handler function to process the status sample */ for (j = 0; !dds_triggered(dc->com->ws) && j < samplecount; j++) { @@ -1135,9 +1135,8 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) dc_server_discovered(dc, status); } } + (void)dds_return_loan(rd, samples, samplecount); } - (void)dds_return_loan (rd, samples, samplecount); -err_samplecount: return samplecount; #undef MAX_SAMPLES } @@ -1157,7 +1156,6 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) samplecount = dds_take_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE); if (samplecount < 0) { DDS_ERROR("failed to take dc_response [%s]", dds_strretcode(-samplecount)); - goto err_samplecount; } else { /* process the response * we ignore invalid samples and only process valid responses */ @@ -1172,9 +1170,8 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dc_response %s%s\n", str, (len >= sizeof(str)) ? "..(trunc)" : ""); } } + (void)dds_return_loan(rd, samples, samplecount); } - (void)dds_return_loan (rd, samples, samplecount); -err_samplecount: return samplecount; #undef MAX_SAMPLES From 7fef7797843b939a3ef9254152708ec7f7aa3f14 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Wed, 6 Dec 2023 14:00:37 +0100 Subject: [PATCH 024/207] Refactor administration of requests; requests are now organised per set (i.e., proxy set) Signed-off-by: TheFixer --- src/durability/src/dds_durability.c | 466 +++++++++++++++++++--------- 1 file changed, 313 insertions(+), 153 deletions(-) diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 2544344ee2..718274cab1 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -26,6 +26,11 @@ #define DEFAULT_QOURUM 1 #define DEFAULT_IDENT "durable_support" +/* maximum supported topic name size + * Topic names larger than this size are not supported */ +#define MAX_TOPIC_NAME_SIZE 255 + +#define DC_UNUSED_ARG(x) ((void)x) #define TRACE(...) DDS_CLOG (DDS_LC_DUR, &domaingv->logconfig, __VA_ARGS__) @@ -180,24 +185,110 @@ static void cleanup_server (void *n) static const ddsrt_avl_ctreedef_t server_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct server_t, node), offsetof (struct server_t, id), cmp_server, 0); -/* This represents a request for historical data. */ +struct proxy_set_reader_key_t { + dds_guid_t guid; /* guid of the reader */ +}; + +static int cmp_proxy_set_reader (const void *a, const void *b) +{ + struct proxy_set_reader_key_t *k1 = (struct proxy_set_reader_key_t *)a; + struct proxy_set_reader_key_t *k2 = (struct proxy_set_reader_key_t *)b; + + return memcmp(k1->guid.v, k2->guid.v, 16); +} + +struct proxy_set_reader_t { + ddsrt_avl_node_t node; + struct proxy_set_reader_key_t key; + struct dds_rhc *rhc; +}; + +static void cleanup_proxy_set_reader (void *n) +{ + struct proxy_set_reader_t *proxy_set_reader = (struct proxy_set_reader_t *)n; + + ddsrt_free(proxy_set_reader); +} + +static const ddsrt_avl_ctreedef_t proxy_set_reader_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct proxy_set_reader_t, node), offsetof (struct proxy_set_reader_t, key), cmp_proxy_set_reader, 0); + +struct proxy_set_key_t { + char *partition; /* partition name */ + char *tpname; /* topic name */ + /* todo: typeid */ +}; + +struct proxy_set_t { + ddsrt_avl_node_t node; /* represents a node in the tree of pending requests */ + struct proxy_set_key_t key; /* key of a proxy set */ + ddsrt_avl_ctree_t readers; /* the tree of readers and their rhc that have an interest in this proxy set */ + uint64_t seq; /* the sequence number of the outstanding request for this proxy set, 0 if no outstanding request */ +}; + +static int cmp_proxy_set (const void *a, const void *b) +{ + struct proxy_set_key_t *k1 = (struct proxy_set_key_t *)a; + struct proxy_set_key_t *k2 = (struct proxy_set_key_t *)b; + int cmp; + + /* compare partition */ + if ((cmp = strcmp(k1->partition, k2->partition)) < 0) { + return -1; + } else if (cmp > 0) { + return 1; + } + /* compare topic */ + if ((cmp = strcmp(k1->tpname, k2->tpname)) < 0) { + return -1; + } else if (cmp > 0) { + return 1; + } + return 0; +} + +static void cleanup_proxy_set (void *n) +{ + struct proxy_set_t *proxy_set = (struct proxy_set_t *)n; + + ddsrt_avl_cfree(&proxy_set_reader_td, &proxy_set->readers, cleanup_proxy_set_reader); + ddsrt_free(proxy_set->key.partition); + ddsrt_free(proxy_set->key.tpname); + ddsrt_free(proxy_set); +} + +static const ddsrt_avl_ctreedef_t proxy_set_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct proxy_set_t, node), offsetof (struct proxy_set_t, key), cmp_proxy_set, 0); + +struct pending_request_key_t { + uint64_t seq; /* the sequence number of the request */ +}; + +/* This represents a request for data for a proxy set. + * Such request will lead to the publication of a transient-local + * autodisposed request topic to a DS. Requests are keyed by a monotonically + * increasing sequence number. + * Requests can expire when no answer is received within the specified + * expiration time. In this case the request will be disposed to prevent + * that a DS reacts to an already expired request. + * + * LH: to check: is it really necessary to allow expiration of requests? + * If a request is transient-local, autodisposed then there is no need + * to expire a request. Only if you want to request data from a different + * ds we should dispose the current requests, create another request reader + * that connects to another ds, and republish the requests. */ struct pending_request_t { ddsrt_avl_node_t node; /* represents a node in the tree of pending requests */ ddsrt_fibheap_node_t fhnode; /* represents a node in the priority queue */ - dds_instance_handle_t ih; /* the instance handle that represents the reader */ - uint64_t seq; /* the sequence number of the request; this is used as the key */ - dds_time_t birth_time; /* time this pending event was created */ - dds_entity_t reader; /* the reader that does the request */ - struct dds_rhc *rhc; /* reader rhc */ - dds_time_t exp_time; /* Expire time for this pending request */ + struct pending_request_key_t key; /* sequence number of the request */ + struct proxy_set_t *proxy_set; /* the proxy set associated with the request */ + dds_time_t exp_time; /* request expiration time */ }; static int cmp_pending_request (const void *a, const void *b) { - uint64_t *s1 = (uint64_t *)a; - uint64_t *s2 = (uint64_t *)b; + struct pending_request_key_t *k1 = (struct pending_request_key_t *)a; + struct pending_request_key_t *k2 = (struct pending_request_key_t *)b; - return (*s1 < *s2) ? -1 : ((*s1 > *s2) ? 1 : 0); + return (k1->seq < k2->seq) ? -1 : ((k1->seq > k2->seq) ? 1 : 0); } static void cleanup_pending_request (void *n) @@ -214,7 +305,7 @@ static int cmp_exp_time (const void *a, const void *b) return (pr1->exp_time < pr2->exp_time) ? -1 : ((pr1->exp_time > pr2->exp_time) ? 1 : 0); } -static const ddsrt_avl_ctreedef_t pending_requests_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct pending_request_t, node), offsetof (struct pending_request_t, seq), cmp_pending_request, 0); +static const ddsrt_avl_ctreedef_t pending_requests_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct pending_request_t, node), offsetof (struct pending_request_t, key), cmp_pending_request, 0); static const ddsrt_fibheap_def_t pending_requests_fd = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct pending_request_t, fhnode), cmp_exp_time); @@ -301,7 +392,8 @@ struct dc_t { ddsrt_mutex_t pending_request_mutex; /* pending request queue mutex */ ddsrt_cond_t pending_request_cond; /* pending request condition */ dds_instance_handle_t selected_request_reader_ih; /* instance handle to matched request reader, DDS_HANDLE_NIL if not available */ - ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on a ds that match with my ds writer */ + ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on a ds that match with my request writer */ + ddsrt_avl_ctree_t proxy_sets; /* tree containing the sets for which data has to be provided by a ds */ uint32_t nr_of_matched_dc_requests; /* indicates the number of matched dc_request readers for the dc_request writer of this client */ }; @@ -993,78 +1085,30 @@ static void dc_com_free (struct com_t *com) #define MAX_TOPIC_NAME_SIZE 255 -static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader, uint64_t seq) +static dds_return_t dc_com_request_write (struct com_t *com, const char *partition, const char *tpname, uint64_t seq) { - /* check for publication_matched() on the dc_request writer to make sure that the request arrives */ - /* create a request */ - /* set the request on the pending liust */ - /* send the request */ - /* note: we allow doing a request for volatile readers */ DurableSupport_request *request; - dds_qos_t *rqos; dds_return_t ret = DDS_RETCODE_OK; - uint32_t plen, i; - char **partitions; - dds_entity_t topic; - char tpname[MAX_TOPIC_NAME_SIZE]; - if ((rqos = dds_create_qos()) == NULL) { - DDS_ERROR("Unable to create reader qos for dc_request"); - goto err_alloc_rqos; - } - if ((ret = dds_get_qos(reader, rqos)) != DDS_RETCODE_OK) { - DDS_ERROR("Unable to get reader qos for dc_request"); - goto err_get_qos; - } - if (!dds_qget_partition(rqos, &plen, &partitions)) { - DDS_ERROR("Failed to retrieve partition qos for dc_request"); - goto err_qget_partition; - } - if ((topic = dds_get_topic(reader)) < 0) { - DDS_ERROR("Failed to get topic for reader [%s]", dds_strretcode(topic)); - goto err_get_topic; - } - if ((ret = dds_get_name(topic, tpname, sizeof(tpname))) < 0) { - DDS_ERROR("Failed to get topic name from reader [%s]", dds_strretcode(ret)); - goto err_get_name; - } else if (ret > MAX_TOPIC_NAME_SIZE) { - DDS_ERROR("topic name '%s...', name too long [%s]", tpname, dds_strretcode(ret)); - goto err_get_name_size; - } request = DurableSupport_request__alloc(); memcpy(request->requestid.client, dc.cfg.id, 16); request->requestid.seq = seq; - request->partitions._length = plen; - request->partitions._maximum = plen; - request->partitions._buffer = dds_sequence_string_allocbuf(plen); + request->partitions._length = 1; + request->partitions._maximum = 1; + request->partitions._buffer = dds_sequence_string_allocbuf(1); request->partitions._release = true; - for (i=0; i < plen; i++) { - request->partitions._buffer[i] = ddsrt_strdup(partitions[i]); - } + request->partitions._buffer[0] = ddsrt_strdup(partition); request->tpname = ddsrt_strdup(tpname); -// request->timeout = DDS_SECS(5); request->timeout = DDS_INFINITY; if ((ret = dds_write(com->wr_request, request)) < 0) { DDS_ERROR("failed to publish dc_request [%s]", dds_strretcode(-ret)); goto err_request_write; } DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "publish dc_request {\"client\":\"%s\", \"seq\":%" PRIu64 "}\n", dc.cfg.id_str, seq); - -err_get_topic: -err_get_name: -err_get_name_size: err_request_write: - dc_free_partitions(plen, partitions); - dds_delete_qos(rqos); DurableSupport_request_free(request, DDS_FREE_ALL); return ret; - -err_qget_partition: -err_get_qos: - dds_delete_qos(rqos); -err_alloc_rqos: - return DDS_RETCODE_ERROR; } static dds_return_t dc_com_request_dispose (struct com_t *com, dds_instance_handle_t ih) @@ -1177,54 +1221,63 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } -/* called when there is a match for a durable writer */ -static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publication_matched_status_t status, void *arg) +static struct proxy_set_t *dc_create_proxy_set (struct dc_t *dc, const char *partition, const char *tpname) { - struct dc_t *dc = (struct dc_t *)arg; - dds_instance_handle_t ih; - dds_builtintopic_endpoint_t *ep; + struct proxy_set_t *proxy_set = NULL; - /* a reader has matched with a durable writer. */ - /* check if the reader is a data container. - * If so, this might affect the quorum */ - assert(writer); - if ((ih = status.last_subscription_handle) == DDS_HANDLE_NIL) { - DDS_ERROR("failed to receive valid last_subscription_handle\n"); - goto err_last_subscription_handle; - } - if ((ep = dds_get_matched_subscription_data(writer, ih)) != NULL) { - if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { - /* A data container has matched with this writer. - * Check if the quorum is met. */ - dc_check_quorum_reached(dc, writer, true); - } - dds_builtintopic_free_endpoint(ep); - } else { - /* the endpoint is not available any more. - * Check if the quorem has been lost */ - dc_check_quorum_reached(dc, writer, false); + assert(partition); + assert(tpname); + proxy_set = (struct proxy_set_t *)ddsrt_malloc(sizeof(struct proxy_set_t)); + proxy_set->key.partition = ddsrt_strdup(partition); + proxy_set->key.tpname = ddsrt_strdup(tpname); + proxy_set->seq = 0; /* no pending request yet */ + ddsrt_avl_cinit(&proxy_set_reader_td, &proxy_set->readers); + ddsrt_avl_cinsert(&proxy_set_td, &dc->proxy_sets, proxy_set); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "proxy set '%s.%s' created\n", proxy_set->key.partition, proxy_set->key.tpname); + return proxy_set; +} + +static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, bool autocreate) +{ + struct proxy_set_key_t key; + struct proxy_set_t *proxy_set; + + assert(partition); + assert(tpname); + key.partition = ddsrt_strdup(partition); + key.tpname = ddsrt_strdup(tpname); + if (((proxy_set = ddsrt_avl_clookup (&proxy_set_td, &dc->proxy_sets, &key)) == NULL) && autocreate) { + proxy_set = dc_create_proxy_set(dc, partition, tpname); } -err_last_subscription_handle: - return; + ddsrt_free(key.partition); + ddsrt_free(key.tpname); + return proxy_set; } -static void dc_add_pending_request (struct dc_t *dc, struct pending_request_t *pr) +/* */ +static void dc_register_pending_request (struct dc_t *dc, struct proxy_set_t *proxy_set, const uint64_t seq) { + struct pending_request_t *pr; ddsrt_avl_ipath_t ipath; dds_return_t ret; - assert(pr); + assert(seq > 0); ddsrt_mutex_lock(&dc->pending_request_mutex); - if ((ddsrt_avl_clookup_ipath(&pending_requests_td, &dc->pending_requests, &pr->seq, &ipath)) != NULL) { - /* there is already an outstanding reader request for this reader */ - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "There is already an outstanding reader request with seq %" PRIu64 "\n", pr->seq); + if ((pr = ddsrt_avl_clookup_ipath(&pending_requests_td, &dc->pending_requests, &seq, &ipath)) != NULL) { + /* there is already an outstanding request with this sequence number */ + assert(pr->proxy_set == proxy_set); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "There is already an outstanding request with seq %" PRIu64 "\n", seq); ddsrt_mutex_unlock(&dc->pending_request_mutex); return; } + pr = (struct pending_request_t *)ddsrt_malloc(sizeof(struct pending_request_t)); + pr->key.seq = seq; + pr->proxy_set = proxy_set; + pr->exp_time = DDS_NEVER; /* pending request not yet available, add it to tree of pending request */ ddsrt_avl_cinsert(&pending_requests_td, &dc->pending_requests, pr); ddsrt_fibheap_insert(&pending_requests_fd, &dc->pending_requests_fh, pr); - if (pr == ddsrt_fibheap_min(&pending_requests_fd, &dc->pending_requests_fh)) { + if ((pr->exp_time != DDS_NEVER) && (pr == ddsrt_fibheap_min(&pending_requests_fd, &dc->pending_requests_fh))) { /* trigger the main loop in the recv_handler to recalculate the timeout */ if ((ret = dds_set_guardcondition(dc->com->pending_request_guard, true)) < 0) { DDS_ERROR("failed to set pending request guard to true [%s]", dds_strretcode(ret)); @@ -1233,65 +1286,169 @@ static void dc_add_pending_request (struct dc_t *dc, struct pending_request_t *p ddsrt_mutex_unlock(&dc->pending_request_mutex); } -/* publish a reader request - * The reader request is published as a transient-local topic which is - * keyed by the guid of this client and a monotonically increasing sequence number. - * Even though this is not recommended, this allows multiple requests from the - * same reader (because they have a different sequence number). - * - * For each outgoing request, a pending request entry will be created to administrate - * the outgoing requests. Pending requests can have a expiration. Expired pending - * requests will lead to removal of the pending request, and a dispose of the - * corresponding reader request to prevent that late joining - */ -static struct pending_request_t *dc_publish_reader_request (struct dc_t *dc, dds_entity_t reader, struct dds_rhc *rhc) +/* publish a request for a specific data set + * The request is published as a transient-local topic which is + * keyed by the guid of this client and a monotonically increasing + * sequence number. This allows multiple requests from the same client + * (because they have a different sequence number). */ +static int dc_request_data_for_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, const uint64_t seq) { - struct pending_request_t *pr; - dds_instance_handle_t ih; dds_return_t rc; - dds_time_t now = dds_time(); + assert(proxy_set); + assert(seq > 0); + assert(proxy_set->seq == seq); + /* register the request identified by seq with the proxy set + * We do this BEFORE we send the request, so that we are sure + * that when we receive the response the we can lookup the + * proxy set associated with this request */ + dc_register_pending_request(dc, proxy_set, seq); + if ((rc = dc_com_request_write(dc->com, proxy_set->key.partition, proxy_set->key.tpname, seq)) != DDS_RETCODE_OK) { + DDS_ERROR("Failed to publish dc_request #%" PRIu64 "\n", dc->seq); + } + return (rc == DDS_RETCODE_OK) ? 0 : -1; +} + +/* add the reader tree of readers for this proxy set */ +static void dc_register_reader_to_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, dds_guid_t guid, struct dds_rhc *rhc) +{ + struct proxy_set_reader_t *proxy_set_rd; + struct proxy_set_reader_key_t key; + char id_str[37]; + + key.guid = guid; + if ((proxy_set_rd = ddsrt_avl_clookup (&proxy_set_reader_td, &proxy_set->readers, &key)) == NULL) { + proxy_set_rd = (struct proxy_set_reader_t *)ddsrt_malloc(sizeof(struct proxy_set_reader_t)); + proxy_set_rd->key.guid = guid; + proxy_set_rd->rhc = rhc; + ddsrt_avl_cinsert(&proxy_set_reader_td, &proxy_set->readers, proxy_set_rd); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "reader \"%s\" added to proxy set '%s.%s'\n", dc_stringify_id(guid.v, id_str), proxy_set->key.partition, proxy_set->key.tpname); + } + assert(proxy_set_rd->rhc == rhc); +} + +static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reader, struct dds_rhc *rhc) +{ + dds_entity_t topic; + dds_return_t rc; + char tpname[MAX_TOPIC_NAME_SIZE]; + dds_qos_t *rqos; + uint32_t plen, i; + char **partitions; + struct proxy_set_t *proxy_set = NULL; + dds_instance_handle_t ih; + dds_guid_t guid; + char id_str[37]; + + /* LH: perhaps the qos should be added as parameter, since the caller already has the qos */ /* verify if the reader still exists; if not, delete the request */ if ((rc = dds_get_instance_handle(reader, &ih)) != DDS_RETCODE_OK) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "No need to publish dc_request, reader is not available\n"); - return NULL; - } - /* create a pending request entry and insert it in the table of pending requests */ - if ((pr = (struct pending_request_t *)ddsrt_malloc(sizeof(struct pending_request_t))) == NULL) { - DDS_ERROR("Failed to allocate a reader request\n"); - goto err_alloc_reader_request; - } - memset(pr, 0, sizeof(struct pending_request_t)); - pr->birth_time = now; - pr->ih = ih; /* handle that corresponds to the reader for which this request is done; key for the pending_request tree */ - pr->seq = ++(dc->seq); /* sequence number; key for the fibheap tree */ - pr->reader = reader; - pr->rhc = rhc; - /* LH: We currently never explicitly dispose a request to a DS on the same host - * (which is the only mode we currently support for now). In this way - * a disconnect with the DS will lead to a dispose of the request - * on the DS (by virtue of the autodispose property). A reconnect with - * the DS will lead to the request being received again. - * Once we allow sending requests to (multiple) remote DSs, we need to - * implement a mechanism to detect a disconnect with the DS, and - * perhaps choose another DS to send a request to. - * We also need to cancel requests to DSs that have not responded yet in - * case we received the required data from one of the DSs */ - pr->exp_time = DDS_NEVER; - /* add the pending request */ - dc_add_pending_request(dc, pr); - /* publish the request */ - if ((rc = dc_com_request_write(dc->com, reader, dc->seq)) != DDS_RETCODE_OK) { - DDS_ERROR("Failed to publish dc_request #%" PRIu64 "\n", dc->seq); - goto err_publish_reader_request; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "No need to create a proxy set, reader is not available [%s]\n", dds_strretcode(-rc)); + return; + } + /* get reader guid */ + if ((rc = dds_get_guid(reader, &guid)) < DDS_RETCODE_OK) { + DDS_ERROR("Unable to retrieve the guid of the reader [%s]\n", dds_strretcode(-rc)); + goto err_get_guid; + } + (void)dc_stringify_id(guid.v, id_str); + /* get topic name */ + if ((topic = dds_get_topic(reader)) < 0) { + DDS_ERROR("Unable to get topic from reader [%s]\n", dds_strretcode(-topic)); + goto err_get_topic; + } + if ((rc = dds_get_name(topic, tpname, sizeof(tpname))) < 0) { + DDS_ERROR("Failed to get topic name [%s]\n", dds_strretcode(-rc)); + goto err_get_name; + } else if (rc > MAX_TOPIC_NAME_SIZE) { + DDS_ERROR("Name for topic '%s...', name too long\n", tpname); + goto err_get_name_size; + } + /* get partitions of the reader */ + if ((rqos = dds_create_qos()) == NULL) { + DDS_ERROR("Failed to allocate reader qos\n"); + goto err_alloc_rqos; + } + if ((rc = dds_get_qos(reader, rqos)) < 0) { + DDS_ERROR("Failed to get topic qos [%s]\n", dds_strretcode(rc)); + goto err_get_qos; + } + if (!dds_qget_partition(rqos, &plen, &partitions)) { + DDS_ERROR("failed to get partitions from qos\n"); + goto err_qget_partition; + } + assert(plen > 0); + /* for each partition create a proxy set if it does not exist yet + * and request data for the proxy set (if not done so already) */ + for (i=0; i < plen; i++) { + proxy_set = dc_get_proxy_set(dc, partitions[i], tpname, true); + assert(proxy_set); + /* Add the reader and rhc to this proxy set. + * We do this BEFORE we send the request, so that we are sure + * that when we receive the response (possibly immediately after + * sending the request) the reader and rhc are present */ + dc_register_reader_to_proxy_set(dc, proxy_set, guid, rhc); + if (proxy_set->seq == 0) { + /* There is no pending request associated with this proxy set, + * so let's create a new pending request for this proxy set */ + proxy_set->seq = ++(dc->seq); + if ((dc_request_data_for_proxy_set(dc, proxy_set, proxy_set->seq)) < 0) { + /* We failed to request data for this proxy set. + * We could do several things now, e.g., 1) try again until we succeed, + * 2) notify the application that no historical data could be retrieved, + * or 3) commit suicide because we cannot guarantee eventual consistency. + * For now, I choose for the latter. After all, it is expected that sending + * a request should never fail. */ + abort(); + } + } /* else there is already an outstanding pending request for this + * proxy set. In that case there is no need to republish the request, + * we can just piggyback on the current outstanding request */ } - return pr; + dc_free_partitions(plen, partitions); + dds_delete_qos(rqos); + return; -err_publish_reader_request: - ddsrt_avl_cdelete(&pending_requests_td, &dc->pending_requests, pr); - cleanup_pending_request(pr); -err_alloc_reader_request: - return NULL; +err_qget_partition: +err_get_qos: + dds_delete_qos(rqos); +err_alloc_rqos: +err_get_name_size: +err_get_name: +err_get_topic: +err_get_guid: + return; +} + +/* called when there is a match for a durable writer */ +static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publication_matched_status_t status, void *arg) +{ + struct dc_t *dc = (struct dc_t *)arg; + dds_instance_handle_t ih; + dds_builtintopic_endpoint_t *ep; + + /* a reader has matched with a durable writer. */ + /* check if the reader is a data container. + * If so, this might affect the quorum */ + assert(writer); + if ((ih = status.last_subscription_handle) == DDS_HANDLE_NIL) { + DDS_ERROR("failed to receive valid last_subscription_handle\n"); + goto err_last_subscription_handle; + } + if ((ep = dds_get_matched_subscription_data(writer, ih)) != NULL) { + if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { + /* A data container has matched with this writer. + * Check if the quorum is met. */ + dc_check_quorum_reached(dc, writer, true); + } + dds_builtintopic_free_endpoint(ep); + } else { + /* the endpoint is not available any more. + * check if the quorum has been lost */ + dc_check_quorum_reached(dc, writer, false); + } +err_last_subscription_handle: + return; } /* dispose the request with key 'seq' */ @@ -1404,8 +1561,8 @@ static void dc_process_pending_request_guard (struct dc_t *dc, dds_time_t *timeo /* The head is expired. Remove the pending request from the priority queue * and dispose it to prevent that a DS reacts to an expired request */ if ((pr = ddsrt_fibheap_extract_min(&pending_requests_fd, &dc->pending_requests_fh)) != NULL) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "process pending request %" PRIu64 "\n", pr->seq); - dc_dispose_reader_request(dc, pr->seq); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "process pending request %" PRIu64 "\n", pr->key.seq); + dc_dispose_reader_request(dc, pr->key.seq); cleanup_pending_request(pr); } } while (true); @@ -1545,6 +1702,7 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom ddsrt_avl_cinit(&matched_request_readers_td, &dc.matched_request_readers); ddsrt_avl_cinit(&pending_requests_td, &dc.pending_requests); ddsrt_fibheap_init(&pending_requests_fd, &dc.pending_requests_fh); + ddsrt_avl_cinit(&proxy_set_td, &dc.proxy_sets); ddsrt_mutex_init(&dc.pending_request_mutex); ddsrt_cond_init(&dc.pending_request_cond); /* create the quorum listener */ @@ -1580,6 +1738,7 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom err_create_quorum_listener: ddsrt_cond_destroy(&dc.pending_request_cond); ddsrt_mutex_destroy(&dc.pending_request_mutex); + ddsrt_avl_cfree(&proxy_set_td, &dc.proxy_sets, cleanup_proxy_set); ddsrt_avl_cfree(&pending_requests_td, &dc.pending_requests, cleanup_pending_request); ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); @@ -1618,6 +1777,7 @@ dds_return_t dds_durability_fini (void) dc_com_free(dc.com); ddsrt_cond_destroy(&dc.pending_request_cond); ddsrt_mutex_destroy(&dc.pending_request_mutex); + ddsrt_avl_cfree(&proxy_set_td, &dc.proxy_sets, cleanup_proxy_set); ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); ddsrt_avl_cfree(&pending_requests_td, &dc.pending_requests, cleanup_pending_request); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); @@ -1681,8 +1841,8 @@ dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rh * We can now publish a dc_request for this durable reader. The * dc_request is published as a transient-local topic. This means * that a late joining DS will receive the DS as long as the request - * is not yet disposed.*/ - (void)dc_publish_reader_request(&dc, reader, rhc); + * is not yet disposed. */ + dc_create_proxy_sets_for_reader(&dc, reader, rhc); } dds_free(userdata); dds_delete_qos(parqos); From fa6d5bf82f4bc29d3f937270c4237ac8c982cc26 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Mon, 11 Dec 2023 11:50:47 +0100 Subject: [PATCH 025/207] Add ability to receive responses from a ds Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 53 +- src/durability/src/dds_durability.c | 190 +++---- src/durability/src/durablesupport.c | 474 +++++++----------- 3 files changed, 256 insertions(+), 461 deletions(-) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index 8497b3e663..a101834c00 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -259,41 +259,10 @@ typedef uint16_t DurableSupport_responsetype_t; #define DurableSupport_responsetype_t__alloc() \ ((DurableSupport_responsetype_t*) dds_alloc (sizeof (DurableSupport_responsetype_t))); -typedef struct DurableSupport_request_id_t -{ - DurableSupport_id_t client; - uint64_t seq; -} DurableSupport_request_id_t; - -extern const dds_topic_descriptor_t DurableSupport_request_id_t_desc; - -#define DurableSupport_request_id_t__alloc() \ -((DurableSupport_request_id_t*) dds_alloc (sizeof (DurableSupport_request_id_t))); - -#define DurableSupport_request_id_t_free(d,o) \ -dds_sample_free ((d), &DurableSupport_request_id_t_desc, (o)) - -#ifndef DDS_SEQUENCE_STRING_DEFINED -#define DDS_SEQUENCE_STRING_DEFINED -typedef struct dds_sequence_string -{ - uint32_t _maximum; - uint32_t _length; - char **_buffer; - bool _release; -} dds_sequence_string; - -#define dds_sequence_string__alloc() \ -((dds_sequence_string*) dds_alloc (sizeof (dds_sequence_string))); - -#define dds_sequence_string_allocbuf(l) \ -((char **) dds_alloc ((l) * sizeof (char*))) -#endif /* DDS_SEQUENCE_STRING_DEFINED */ - typedef struct DurableSupport_request { - struct DurableSupport_request_id_t requestid; - dds_sequence_string partitions; + DurableSupport_id_t client; + char * partition; char * tpname; DurableSupport_duration_t timeout; } DurableSupport_request; @@ -308,29 +277,11 @@ dds_sample_free ((d), &DurableSupport_request_desc, (o)) #define DurableSupport_RESPONSETYPE_SET 1 #define DurableSupport_RESPONSETYPE_DATA 2 -#ifndef DDS_SEQUENCE_DURABLESUPPORT_REQUEST_ID_T_DEFINED -#define DDS_SEQUENCE_DURABLESUPPORT_REQUEST_ID_T_DEFINED -typedef struct dds_sequence_DurableSupport_request_id_t -{ - uint32_t _maximum; - uint32_t _length; - struct DurableSupport_request_id_t *_buffer; - bool _release; -} dds_sequence_DurableSupport_request_id_t; - -#define dds_sequence_DurableSupport_request_id_t__alloc() \ -((dds_sequence_DurableSupport_request_id_t*) dds_alloc (sizeof (dds_sequence_DurableSupport_request_id_t))); - -#define dds_sequence_DurableSupport_request_id_t_allocbuf(l) \ -((struct DurableSupport_request_id_t *) dds_alloc ((l) * sizeof (struct DurableSupport_request_id_t))) -#endif /* DDS_SEQUENCE_DURABLESUPPORT_REQUEST_ID_T_DEFINED */ - typedef struct DurableSupport_response_set_t { char * partition; char * tpname; uint32_t flags; - dds_sequence_DurableSupport_request_id_t requestids; } DurableSupport_response_set_t; #ifndef DDS_SEQUENCE_OCTET_DEFINED diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 718274cab1..7da86940d3 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -90,9 +90,54 @@ static char *dc_blob_image (dds_sequence_octet blob) return buf; } +static int dc_stringify_request (char *buf, size_t n, const DurableSupport_request *request, bool valid_data) +{ + size_t i = 0; + int l; + char id_str[37]; + int64_t sec; + uint32_t msec; + + if (buf == NULL) { + goto err; + } + if (request == NULL) { + buf[0] = '\0'; + return 0; + } + if (valid_data) { + /* also print non-key fields */ + if (request->timeout == DDS_INFINITY) { + if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"timeout\":\"never\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname)) < 0) { + goto err; + } + } else { + sec = (int64_t)(request->timeout / DDS_NSECS_IN_SEC); + msec = (uint32_t)((request->timeout % DDS_NSECS_IN_SEC) / DDS_NSECS_IN_MSEC); + if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"timeout\":%" PRId64 ".%03" PRIu32 "}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, sec, msec)) < 0) { + goto err; + } + } + } else { + /* only print key fields */ + if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname)) < 0) { + goto err; + } + } + i += (size_t)l; + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_request failed"); + return -1; +} + static int dc_stringify_response (char *buf, size_t n, const DurableSupport_response *response) { - size_t i = 0, j = 0; + size_t i = 0; int l; char *str; char id_str[37]; @@ -113,23 +158,10 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp } switch (response->body._d) { case DurableSupport_RESPONSETYPE_SET : - if ((l = snprintf(buf+i, n-i, "\"partition\":\"%s\", \"tpname\":\"%s\", \"flags\":\"0x%04" PRIx32 "\", \"requestids\":[", response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.flags)) < 0) { + if ((l = snprintf(buf+i, n-i, "\"partition\":\"%s\", \"tpname\":\"%s\", \"flags\":\"0x%04" PRIx32 "\"", response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.flags)) < 0) { goto err; } i += (size_t)l; - for (j=0; j < response->body._u.set.requestids._length; j++) { - DurableSupport_request_id_t requestid = response->body._u.set.requestids._buffer[j]; - if ((l = snprintf(buf+i, n-(size_t)i, "%s{\"client\":\"%s\", \"seq\":%" PRIu64 "}", (j==0) ? "" : ",", dc_stringify_id(requestid.client, id_str), requestid.seq)) < 0) { - goto err; - } - i += (size_t)l; - if (i >= n) { - goto trunc; - } - } - if (i < n) { - buf[i++] = ']'; - } break; case DurableSupport_RESPONSETYPE_DATA : str = dc_blob_image(response->body._u.data.blob); @@ -1085,27 +1117,28 @@ static void dc_com_free (struct com_t *com) #define MAX_TOPIC_NAME_SIZE 255 -static dds_return_t dc_com_request_write (struct com_t *com, const char *partition, const char *tpname, uint64_t seq) +static dds_return_t dc_com_request_write (struct com_t *com, const char *partition, const char *tpname) { /* note: we allow doing a request for volatile readers */ DurableSupport_request *request; dds_return_t ret = DDS_RETCODE_OK; + char str[1024]; + int l; + size_t len; request = DurableSupport_request__alloc(); - memcpy(request->requestid.client, dc.cfg.id, 16); - request->requestid.seq = seq; - request->partitions._length = 1; - request->partitions._maximum = 1; - request->partitions._buffer = dds_sequence_string_allocbuf(1); - request->partitions._release = true; - request->partitions._buffer[0] = ddsrt_strdup(partition); + memcpy(request->client, dc.cfg.id, 16); + request->partition = ddsrt_strdup(partition); request->tpname = ddsrt_strdup(tpname); request->timeout = DDS_INFINITY; + l = dc_stringify_request(str, sizeof(str), request, true); + assert(l > 0); + len = (size_t)l; if ((ret = dds_write(com->wr_request, request)) < 0) { - DDS_ERROR("failed to publish dc_request [%s]", dds_strretcode(-ret)); + DDS_ERROR("failed to publish dc_request %s%s [%s]", str, (len >= sizeof(str)) ? "..(trunc)" : "", dds_strretcode(-ret)); goto err_request_write; } - DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "publish dc_request {\"client\":\"%s\", \"seq\":%" PRIu64 "}\n", dc.cfg.id_str, seq); + DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "publish dc_request %s%s\n", str, (len >= sizeof(str)) ? "..(trunc)" : ""); err_request_write: DurableSupport_request_free(request, DDS_FREE_ALL); return ret; @@ -1198,6 +1231,7 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) * The memory must be released when done by returning the loan */ samples[0] = NULL; samplecount = dds_take_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE); + if (samplecount < 0) { DDS_ERROR("failed to take dc_response [%s]", dds_strretcode(-samplecount)); } else { @@ -1254,61 +1288,6 @@ static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partit return proxy_set; } -/* */ -static void dc_register_pending_request (struct dc_t *dc, struct proxy_set_t *proxy_set, const uint64_t seq) -{ - struct pending_request_t *pr; - ddsrt_avl_ipath_t ipath; - dds_return_t ret; - - assert(seq > 0); - ddsrt_mutex_lock(&dc->pending_request_mutex); - if ((pr = ddsrt_avl_clookup_ipath(&pending_requests_td, &dc->pending_requests, &seq, &ipath)) != NULL) { - /* there is already an outstanding request with this sequence number */ - assert(pr->proxy_set == proxy_set); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "There is already an outstanding request with seq %" PRIu64 "\n", seq); - ddsrt_mutex_unlock(&dc->pending_request_mutex); - return; - } - pr = (struct pending_request_t *)ddsrt_malloc(sizeof(struct pending_request_t)); - pr->key.seq = seq; - pr->proxy_set = proxy_set; - pr->exp_time = DDS_NEVER; - /* pending request not yet available, add it to tree of pending request */ - ddsrt_avl_cinsert(&pending_requests_td, &dc->pending_requests, pr); - ddsrt_fibheap_insert(&pending_requests_fd, &dc->pending_requests_fh, pr); - if ((pr->exp_time != DDS_NEVER) && (pr == ddsrt_fibheap_min(&pending_requests_fd, &dc->pending_requests_fh))) { - /* trigger the main loop in the recv_handler to recalculate the timeout */ - if ((ret = dds_set_guardcondition(dc->com->pending_request_guard, true)) < 0) { - DDS_ERROR("failed to set pending request guard to true [%s]", dds_strretcode(ret)); - } - } - ddsrt_mutex_unlock(&dc->pending_request_mutex); -} - -/* publish a request for a specific data set - * The request is published as a transient-local topic which is - * keyed by the guid of this client and a monotonically increasing - * sequence number. This allows multiple requests from the same client - * (because they have a different sequence number). */ -static int dc_request_data_for_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, const uint64_t seq) -{ - dds_return_t rc; - - assert(proxy_set); - assert(seq > 0); - assert(proxy_set->seq == seq); - /* register the request identified by seq with the proxy set - * We do this BEFORE we send the request, so that we are sure - * that when we receive the response the we can lookup the - * proxy set associated with this request */ - dc_register_pending_request(dc, proxy_set, seq); - if ((rc = dc_com_request_write(dc->com, proxy_set->key.partition, proxy_set->key.tpname, seq)) != DDS_RETCODE_OK) { - DDS_ERROR("Failed to publish dc_request #%" PRIu64 "\n", dc->seq); - } - return (rc == DDS_RETCODE_OK) ? 0 : -1; -} - /* add the reader tree of readers for this proxy set */ static void dc_register_reader_to_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, dds_guid_t guid, struct dds_rhc *rhc) { @@ -1388,22 +1367,17 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade * that when we receive the response (possibly immediately after * sending the request) the reader and rhc are present */ dc_register_reader_to_proxy_set(dc, proxy_set, guid, rhc); - if (proxy_set->seq == 0) { - /* There is no pending request associated with this proxy set, - * so let's create a new pending request for this proxy set */ - proxy_set->seq = ++(dc->seq); - if ((dc_request_data_for_proxy_set(dc, proxy_set, proxy_set->seq)) < 0) { - /* We failed to request data for this proxy set. - * We could do several things now, e.g., 1) try again until we succeed, - * 2) notify the application that no historical data could be retrieved, - * or 3) commit suicide because we cannot guarantee eventual consistency. - * For now, I choose for the latter. After all, it is expected that sending - * a request should never fail. */ - abort(); - } - } /* else there is already an outstanding pending request for this - * proxy set. In that case there is no need to republish the request, - * we can just piggyback on the current outstanding request */ + /* send a request for this proxy set */ + if ((rc = dc_com_request_write(dc->com, proxy_set->key.partition, proxy_set->key.tpname)) != DDS_RETCODE_OK) { + DDS_ERROR("Failed to publish dc_request for proxy set %s.%s\n", proxy_set->key.partition, proxy_set->key.tpname); + /* We failed to request data for this proxy set. + * We could do several things now, e.g., 1) try again until we succeed, + * 2) notify the application that no historical data could be retrieved, + * or 3) commit suicide because we cannot guarantee eventual consistency. + * For now, I choose for the latter. After all, it is expected that sending + * a request should never fails. */ + abort(); + } } dc_free_partitions(plen, partitions); dds_delete_qos(rqos); @@ -1451,28 +1425,30 @@ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publicat return; } -/* dispose the request with key 'seq' */ -static void dc_dispose_reader_request (struct dc_t *dc, uint64_t seq) +/* dispose the request for the proxy set */ +static void dc_dispose_reader_request (struct dc_t *dc, struct proxy_set_t *proxy_set) { dds_return_t rc; dds_instance_handle_t ih; DurableSupport_request request; /* create a dummy request containing the key fields to retrieve the instance handle */ - memcpy(request.requestid.client, dc->cfg.id, 16); - request.requestid.seq = seq; + memcpy(request.client, dc->cfg.id, 16); + request.partition = ddsrt_strdup(proxy_set->key.partition); + request.tpname = ddsrt_strdup(proxy_set->key.tpname); if ((ih = dds_lookup_instance(dc->com->wr_request, &request)) == DDS_HANDLE_NIL) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dc_request #%" PRIu64 " not available, nothing to dispose\n", seq); - return; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dc_request for proxy set %s.%s not found, unable to dispose\n", request.partition, request.tpname); + goto err_dispose_reader_request; } if ((rc = dc_com_request_dispose(dc->com, ih)) != DDS_RETCODE_OK) { - DDS_ERROR("Failed to dispose dc_request #%" PRIu64 " [%s]\n", seq, dds_strretcode(-rc)); + DDS_ERROR("failed to dispose dc_request for proxy set %s.%s [%s]\n", request.partition, request.tpname, dds_strretcode(-rc)); goto err_dispose_reader_request; } - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dispose dc_request {\"client\":\"%s\", \"seq\":%" PRIu64 "}\n", dc->cfg.id_str, seq); - return; - + /* LH: todo: use dc_stringify_request, but only print the keys */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dispose dc_request {\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\"}\n", dc->cfg.id_str, request.partition, request.tpname); err_dispose_reader_request: + ddsrt_free(request.partition); + ddsrt_free(request.tpname); return; } @@ -1562,7 +1538,7 @@ static void dc_process_pending_request_guard (struct dc_t *dc, dds_time_t *timeo * and dispose it to prevent that a DS reacts to an expired request */ if ((pr = ddsrt_fibheap_extract_min(&pending_requests_fd, &dc->pending_requests_fh)) != NULL) { DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "process pending request %" PRIu64 "\n", pr->key.seq); - dc_dispose_reader_request(dc, pr->key.seq); + dc_dispose_reader_request(dc, pr->proxy_set); cleanup_pending_request(pr); } } while (true); diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index 019dc51c7b..c15192752f 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -586,212 +586,113 @@ const dds_topic_descriptor_t DurableSupport_bead_desc = .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_bead, .sz = TYPE_MAP_CDR_SZ_DurableSupport_bead } }; -static const uint32_t DurableSupport_request_id_t_ops [] = -{ - /* request_id_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), - DDS_OP_RTS -}; - -/* Type Information: - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] (#deps: 1) - - [MINIMAL 43f53a2be35b432cc735e9431a89] - [COMPLETE 852fffc913b7ee54aadae7a1859a] (#deps: 1) - - [COMPLETE aca4d5a256d39713924333e85c6d] -*/ -#define TYPE_INFO_CDR_DurableSupport_request_id_t (const unsigned char []){ \ - 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, \ - 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, \ - 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x40, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_request_id_t 148u -#define TYPE_MAP_CDR_DurableSupport_request_id_t (const unsigned char []){ \ - 0x8a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ - 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ - 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, \ - 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, \ - 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ - 0xe4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ - 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ - 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ - 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0xf1, \ - 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_request_id_t 444u -const dds_topic_descriptor_t DurableSupport_request_id_t_desc = -{ - .m_size = sizeof (DurableSupport_request_id_t), - .m_align = dds_alignof (DurableSupport_request_id_t), - .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 0u, - .m_typename = "DurableSupport::request_id_t", - .m_keys = NULL, - .m_nops = 4, - .m_ops = DurableSupport_request_id_t_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request_id_t, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request_id_t }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request_id_t, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request_id_t } -}; - static const uint32_t DurableSupport_request_ops [] = { /* request */ DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_EXT, offsetof (DurableSupport_request, requestid), (3u << 16u) + 10u /* request_id_t */, - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STR, offsetof (DurableSupport_request, partitions), - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, client), 16u, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, partition), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), DDS_OP_ADR | DDS_OP_TYPE_8BY | DDS_OP_FLAG_SGN, offsetof (DurableSupport_request, timeout), DDS_OP_RTS, - - /* request_id_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), - DDS_OP_RTS, - /* key: requestid.client */ - DDS_OP_KOF | 2, 1u /* order: 0 */, 1u /* order: 0 */, + /* key: client */ + DDS_OP_KOF | 1, 1u /* order: 0 */, + + /* key: partition */ + DDS_OP_KOF | 1, 4u /* order: 1 */, - /* key: requestid.seq */ - DDS_OP_KOF | 2, 1u /* order: 0 */, 4u /* order: 1 */ + /* key: tpname */ + DDS_OP_KOF | 1, 6u /* order: 2 */ }; -static const dds_key_descriptor_t DurableSupport_request_keys[2] = +static const dds_key_descriptor_t DurableSupport_request_keys[3] = { - { "requestid.client", 18, 0 }, - { "requestid.seq", 21, 1 } + { "client", 11, 0 }, + { "partition", 13, 1 }, + { "tpname", 15, 2 } }; /* Type Information: - [MINIMAL 20fb854c344bb02af8430115a676] (#deps: 3) - - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] + [MINIMAL 3f4b9832b556de33be4c31963879] (#deps: 2) - [MINIMAL 43f53a2be35b432cc735e9431a89] - [MINIMAL 84ce9c3d894c1483f859c00d5927] - [COMPLETE 2de91793545eff71a07b9e15f413] (#deps: 3) - - [COMPLETE 852fffc913b7ee54aadae7a1859a] + [COMPLETE 2992c8ff086f0c3d6eb4041c2b94] (#deps: 2) - [COMPLETE aca4d5a256d39713924333e85c6d] - [COMPLETE 023df3bd21223779cd1936cef928] */ #define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ - 0xf0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x20, 0xfb, 0x85, 0x4c, 0x34, 0x4b, 0xb0, 0x2a, 0xf8, 0x43, 0x01, \ - 0x15, 0xa6, 0x76, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ - 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, \ - 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x2d, 0xe9, 0x17, \ - 0x93, 0x54, 0x5e, 0xff, 0x71, 0xa0, 0x7b, 0x9e, 0x15, 0xf4, 0x13, 0x00, 0xce, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, \ - 0x7e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0xc0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x3f, 0x4b, 0x98, 0x32, 0xb5, 0x56, 0xde, 0x33, 0xbe, 0x4c, 0x31, \ + 0x96, 0x38, 0x79, 0x00, 0x75, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, \ + 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x29, 0x92, 0xc8, 0xff, 0x08, 0x6f, 0x0c, 0x3d, 0x6e, 0xb4, 0x04, \ + 0x1c, 0x2b, 0x94, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ 0x39, 0x00, 0x00, 0x00\ } -#define TYPE_INFO_CDR_SZ_DurableSupport_request 244u +#define TYPE_INFO_CDR_SZ_DurableSupport_request 196u #define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ - 0x3b, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf1, 0x20, 0xfb, 0x85, 0x4c, 0x34, 0x4b, 0xb0, \ - 0x2a, 0xf8, 0x43, 0x01, 0x15, 0xa6, 0x76, 0x00, 0x79, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, \ - 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x3c, 0xb0, 0x21, 0x74, 0x00, 0x00, 0x00, \ - 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, \ - 0x00, 0xae, 0xa4, 0x67, 0xe1, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, \ - 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, \ - 0x0f, 0xd5, 0x22, 0xa4, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, \ - 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, \ - 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ + 0xdb, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0x3f, 0x4b, 0x98, 0x32, 0xb5, 0x56, 0xde, \ + 0x33, 0xbe, 0x4c, 0x31, 0x96, 0x38, 0x79, 0x00, 0x71, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ + 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ + 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ - 0x0d, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf2, 0x2d, 0xe9, 0x17, 0x93, 0x54, 0x5e, 0xff, \ - 0x71, 0xa0, 0x7b, 0x9e, 0x15, 0xf4, 0x13, 0x00, 0xca, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x71, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0x29, 0x92, 0xc8, 0xff, 0x08, 0x6f, 0x0c, \ + 0x3d, 0x6e, 0xb4, 0x04, 0x1c, 0x2b, 0x94, 0x00, 0xbe, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, \ - 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x69, 0x64, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, \ - 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, \ - 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, \ - 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ - 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ - 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, \ - 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x75, 0x72, 0x61, \ - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf2, 0x2d, 0xe9, 0x17, \ - 0x93, 0x54, 0x5e, 0xff, 0x71, 0xa0, 0x7b, 0x9e, 0x15, 0xf4, 0x13, 0xf1, 0x20, 0xfb, 0x85, 0x4c, \ - 0x34, 0x4b, 0xb0, 0x2a, 0xf8, 0x43, 0x01, 0x15, 0xa6, 0x76, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, \ - 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, \ - 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ - 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, \ - 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, \ - 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, \ - 0xc0, 0x0d, 0x59, 0x27\ + 0x65, 0x73, 0x74, 0x00, 0x92, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, \ + 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, \ + 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, \ + 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x26, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, \ + 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, \ + 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x02, 0x3d, 0xf3, \ + 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x35, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0xf2, 0x29, 0x92, 0xc8, 0xff, 0x08, 0x6f, 0x0c, 0x3d, 0x6e, 0xb4, 0x04, 0x1c, 0x2b, 0x94, 0xf1, \ + 0x3f, 0x4b, 0x98, 0x32, 0xb5, 0x56, 0xde, 0x33, 0xbe, 0x4c, 0x31, 0x96, 0x38, 0x79, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, 0x3d, 0xf3, \ + 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, 0x9c, 0x3d, \ + 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_request 980u +#define TYPE_MAP_CDR_SZ_DurableSupport_request 698u const dds_topic_descriptor_t DurableSupport_request_desc = { .m_size = sizeof (DurableSupport_request), .m_align = dds_alignof (DurableSupport_request), .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 2u, + .m_nkeys = 3u, .m_typename = "DurableSupport::request", .m_keys = DurableSupport_request_keys, - .m_nops = 10, + .m_nops = 6, .m_ops = DurableSupport_request_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request }, @@ -810,7 +711,7 @@ static const uint32_t DurableSupport_response_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_response_content, _d), 2u, (12u << 16u) + 4u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 9 /* response_set_t */, 1, offsetof (DurableSupport_response_content, _u.set), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 24 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 13 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, DDS_OP_RTS, /* response_set_t */ @@ -818,13 +719,6 @@ static const uint32_t DurableSupport_response_ops [] = DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, partition), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, tpname), DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_response_set_t, flags), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_response_set_t, requestids), sizeof (DurableSupport_request_id_t), (4u << 16u) + 5u /* request_id_t */, - DDS_OP_RTS, - - /* request_id_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), DDS_OP_RTS, /* response_data_t */ @@ -838,168 +732,142 @@ static const uint32_t DurableSupport_response_ops [] = static const dds_key_descriptor_t DurableSupport_response_keys[1] = { - { "id", 45, 0 } + { "id", 34, 0 } }; /* Type Information: - [MINIMAL 930d49afed28329dc1db60ef7617] (#deps: 6) + [MINIMAL cf1872b677b74fe96238ec83b9a2] (#deps: 5) - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 6bc43f8b4741bc316540a0ef7b88] + - [MINIMAL 8691a7e3485bf0cdaeaf8f18ae96] - [MINIMAL 80455e796dd3437163cb532089da] - - [MINIMAL 82d72a61dfdf9b101310caab1550] - - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] + - [MINIMAL 93ae2a1819f89109310333cdd898] - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE 75c71ab3f8db547e64f5b5212bc9] (#deps: 6) + [COMPLETE 41db4720b87e5b250e570da55eff] (#deps: 5) - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE 699d1f1db9ab7829fc4aa3be1028] + - [COMPLETE f9cb4201664aea89e45563ec138a] - [COMPLETE eec1bad6badde73f40ef199fedcc] - - [COMPLETE cb1a215003014659ba61115bccb5] - - [COMPLETE 852fffc913b7ee54aadae7a1859a] + - [COMPLETE df8d519cc0ad7b43f266d2a4d8e9] - [COMPLETE 008875599776c39ce0c1fe897846] */ #define TYPE_INFO_CDR_DurableSupport_response (const unsigned char []){ \ - 0x80, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x93, 0x0d, 0x49, 0xaf, 0xed, 0x28, 0x32, 0x9d, 0xc1, 0xdb, 0x60, \ - 0xef, 0x76, 0x17, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x50, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xa0, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0xcf, 0x18, 0x72, 0xb6, 0x77, 0xb7, 0x4f, 0xe9, 0x62, 0x38, 0xec, \ + 0x83, 0xb9, 0xa2, 0x00, 0x55, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, 0x41, 0xbc, 0x31, 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0x00, \ + 0xf1, 0x86, 0x91, 0xa7, 0xe3, 0x48, 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0x00, \ 0x7c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x82, 0xd7, 0x2a, 0x61, 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, 0x15, 0x50, 0x00, \ - 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ - 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ - 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x75, 0xc7, 0x1a, 0xb3, 0xf8, 0xdb, 0x54, 0x7e, 0x64, 0xf5, 0xb5, \ - 0x21, 0x2b, 0xc9, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ - 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x69, 0x9d, 0x1f, 0x1d, 0xb9, 0xab, 0x78, 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0x00, \ - 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, \ - 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xcb, 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, 0x5b, 0xcc, 0xb5, 0x00, \ - 0xbd, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ - 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x93, 0xae, 0x2a, 0x18, 0x19, 0xf8, 0x91, 0x09, 0x31, 0x03, 0x33, 0xcd, 0xd8, 0x98, 0x00, \ + 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, \ + 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0xa0, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x41, 0xdb, 0x47, \ + 0x20, 0xb8, 0x7e, 0x5b, 0x25, 0x0e, 0x57, 0x0d, 0xa5, 0x5e, 0xff, 0x00, 0x87, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ + 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xf9, 0xcb, 0x42, 0x01, 0x66, 0x4a, 0xea, \ + 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, 0x8a, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, \ + 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, \ + 0x43, 0xf2, 0x66, 0xd2, 0xa4, 0xd8, 0xe9, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ 0x57, 0x00, 0x00, 0x00\ } -#define TYPE_INFO_CDR_SZ_DurableSupport_response 388u +#define TYPE_INFO_CDR_SZ_DurableSupport_response 340u #define TYPE_MAP_CDR_DurableSupport_response (const unsigned char []){ \ - 0x58, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0x93, 0x0d, 0x49, 0xaf, 0xed, 0x28, 0x32, \ - 0x9d, 0xc1, 0xdb, 0x60, 0xef, 0x76, 0x17, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0xdc, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xf1, 0xcf, 0x18, 0x72, 0xb6, 0x77, 0xb7, 0x4f, \ + 0xe9, 0x62, 0x38, 0xec, 0x83, 0xb9, 0xa2, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, \ - 0x41, 0xbc, 0x31, 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x86, 0x91, 0xa7, 0xe3, 0x48, \ + 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, \ - 0x41, 0xbc, 0x31, 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x86, 0x91, 0xa7, 0xe3, 0x48, \ + 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ 0x54, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x82, 0xd7, 0x2a, 0x61, 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, 0x15, \ - 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ + 0x01, 0x00, 0xf1, 0x93, 0xae, 0x2a, 0x18, 0x19, 0xf8, 0x91, 0x09, 0x31, 0x03, 0x33, 0xcd, 0xd8, \ + 0x98, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x82, 0xd7, 0x2a, 0x61, \ - 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, 0x15, 0x50, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x93, 0xae, 0x2a, 0x18, \ + 0x19, 0xf8, 0x91, 0x09, 0x31, 0x03, 0x33, 0xcd, 0xd8, 0x98, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ 0x7e, 0x75, 0xc0, 0xed, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, \ - 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, \ - 0x01, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, \ - 0x22, 0xa4, 0x7c, 0x2c, 0x0f, 0x37, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, \ - 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ - 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, \ - 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, \ - 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0xc3, 0x03, 0x00, 0x00, \ - 0x07, 0x00, 0x00, 0x00, 0xf2, 0x75, 0xc7, 0x1a, 0xb3, 0xf8, 0xdb, 0x54, 0x7e, 0x64, 0xf5, 0xb5, \ - 0x21, 0x2b, 0xc9, 0x00, 0x83, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ - 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x69, \ - 0x9d, 0x1f, 0x1d, 0xb9, 0xab, 0x78, 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, \ - 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x69, 0x9d, 0x1f, \ - 0x1d, 0xb9, 0xab, 0x78, 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0x00, 0xb3, 0x00, 0x00, 0x00, \ - 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, \ - 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xcb, \ - 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, 0x5b, 0xcc, 0xb5, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x00, \ - 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, \ - 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, \ - 0xed, 0xcc, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, \ + 0x58, 0x68, 0xd6, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, \ + 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, \ + 0x03, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xf2, 0x41, 0xdb, 0x47, 0x20, 0xb8, 0x7e, 0x5b, \ + 0x25, 0x0e, 0x57, 0x0d, 0xa5, 0x5e, 0xff, 0x00, 0x83, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, \ + 0x6f, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xf9, 0xcb, 0x42, 0x01, 0x66, 0x4a, 0xea, 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, \ + 0x8a, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, \ + 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, \ + 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ + 0xf2, 0xf9, 0xcb, 0x42, 0x01, 0x66, 0x4a, 0xea, 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, 0x8a, 0x00, \ + 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, \ + 0x74, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0xee, \ + 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x00, \ + 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, 0x43, 0xf2, 0x66, 0xd2, 0xa4, 0xd8, \ + 0xe9, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, \ + 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, \ + 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, \ + 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, 0x43, 0xf2, 0x66, \ + 0xd2, 0xa4, 0xd8, 0xe9, 0x88, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x27, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, \ - 0x00, 0xf2, 0xcb, 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, 0x5b, 0xcc, 0xb5, \ - 0xb9, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, \ - 0x5f, 0x74, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, \ - 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x64, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, \ - 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x7a, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x02, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ - 0x46, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, \ - 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, \ - 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0x75, 0xc7, 0x1a, \ - 0xb3, 0xf8, 0xdb, 0x54, 0x7e, 0x64, 0xf5, 0xb5, 0x21, 0x2b, 0xc9, 0xf1, 0x93, 0x0d, 0x49, 0xaf, \ - 0xed, 0x28, 0x32, 0x9d, 0xc1, 0xdb, 0x60, 0xef, 0x76, 0x17, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, \ - 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x69, 0x9d, 0x1f, 0x1d, 0xb9, 0xab, 0x78, \ - 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, 0x41, 0xbc, 0x31, \ - 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ - 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, \ - 0x53, 0x20, 0x89, 0xda, 0xf2, 0xcb, 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, \ - 0x5b, 0xcc, 0xb5, 0xf1, 0x82, 0xd7, 0x2a, 0x61, 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, \ - 0x15, 0x50, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, \ - 0x9a, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, \ - 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0xf1, \ - 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ + 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, \ + 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, \ + 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ + 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ + 0x53, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x20, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, \ + 0x61, 0x5f, 0x74, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, \ + 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, \ + 0xf2, 0x41, 0xdb, 0x47, 0x20, 0xb8, 0x7e, 0x5b, 0x25, 0x0e, 0x57, 0x0d, 0xa5, 0x5e, 0xff, 0xf1, \ + 0xcf, 0x18, 0x72, 0xb6, 0x77, 0xb7, 0x4f, 0xe9, 0x62, 0x38, 0xec, 0x83, 0xb9, 0xa2, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0xf9, 0xcb, 0x42, \ + 0x01, 0x66, 0x4a, 0xea, 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, 0x8a, 0xf1, 0x86, 0x91, 0xa7, 0xe3, \ + 0x48, 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, \ + 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, \ + 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, \ + 0x43, 0xf2, 0x66, 0xd2, 0xa4, 0xd8, 0xe9, 0xf1, 0x93, 0xae, 0x2a, 0x18, 0x19, 0xf8, 0x91, 0x09, \ + 0x31, 0x03, 0x33, 0xcd, 0xd8, 0x98, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, \ + 0xc1, 0xfe, 0x89, 0x78, 0x46, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, \ + 0x94, 0xaa, 0xe8, 0x44\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_response 1790u +#define TYPE_MAP_CDR_SZ_DurableSupport_response 1444u const dds_topic_descriptor_t DurableSupport_response_desc = { .m_size = sizeof (DurableSupport_response), @@ -1008,7 +876,7 @@ const dds_topic_descriptor_t DurableSupport_response_desc = .m_nkeys = 1u, .m_typename = "DurableSupport::response", .m_keys = DurableSupport_response_keys, - .m_nops = 22, + .m_nops = 17, .m_ops = DurableSupport_response_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_response, .sz = TYPE_INFO_CDR_SZ_DurableSupport_response }, From f525e95f457d6cc17d6d803a0bef62479561eb46 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Thu, 14 Dec 2023 21:10:19 +0100 Subject: [PATCH 026/207] Deliver data beads per data set to a dc, and allow delivery of data beads to a dc to be aborted Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 6 + src/durability/src/dds_durability.c | 308 +++++++++++++++--- src/durability/src/durablesupport.c | 217 ++++++------ 3 files changed, 395 insertions(+), 136 deletions(-) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index a101834c00..a430da24e1 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -259,6 +259,11 @@ typedef uint16_t DurableSupport_responsetype_t; #define DurableSupport_responsetype_t__alloc() \ ((DurableSupport_responsetype_t*) dds_alloc (sizeof (DurableSupport_responsetype_t))); +typedef uint64_t DurableSupport_delivery_id_t; + +#define DurableSupport_delivery_id_t__alloc() \ +((DurableSupport_delivery_id_t*) dds_alloc (sizeof (DurableSupport_delivery_id_t))); + typedef struct DurableSupport_request { DurableSupport_id_t client; @@ -279,6 +284,7 @@ dds_sample_free ((d), &DurableSupport_request_desc, (o)) #define DurableSupport_RESPONSETYPE_DATA 2 typedef struct DurableSupport_response_set_t { + DurableSupport_delivery_id_t delivery_id; char * partition; char * tpname; uint32_t flags; diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 7da86940d3..5cfad75937 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -32,6 +32,10 @@ #define DC_UNUSED_ARG(x) ((void)x) +#define DC_FLAG_SET_NOT_FOUND (((uint32_t)0x01) << 10) +#define DC_FLAG_SET_BEGIN (((uint32_t)0x01) << 11) +#define DC_FLAG_SET_END (((uint32_t)0x01) << 12) + #define TRACE(...) DDS_CLOG (DDS_LC_DUR, &domaingv->logconfig, __VA_ARGS__) /************* start of common functions ****************/ @@ -158,7 +162,7 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp } switch (response->body._d) { case DurableSupport_RESPONSETYPE_SET : - if ((l = snprintf(buf+i, n-i, "\"partition\":\"%s\", \"tpname\":\"%s\", \"flags\":\"0x%04" PRIx32 "\"", response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.flags)) < 0) { + if ((l = snprintf(buf+i, n-i, "\"delivery_id\":%" PRIu64 ",\"partition\":\"%s\", \"tpname\":\"%s\", \"flags\":\"0x%04" PRIx32 "\"", response->body._u.set.delivery_id, response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.flags)) < 0) { goto err; } i += (size_t)l; @@ -341,6 +345,27 @@ static const ddsrt_avl_ctreedef_t pending_requests_td = DDSRT_AVL_CTREEDEF_INITI static const ddsrt_fibheap_def_t pending_requests_fd = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct pending_request_t, fhnode), cmp_exp_time); + +struct delivery_ctx_t { + ddsrt_avl_node_t node; + DurableSupport_id_t id; /* id of the ds; key of the delivery context */ + uint64_t delivery_id; /* the id of the delivery by this ds; this is a monotonic increased sequence number */ + struct proxy_set_t *proxy_set; /* current proxy_set for which responses are being received, NULL if not known */ +}; + +static int delivery_ctx_cmp (const void *a, const void *b) +{ + return memcmp(a, b, 16); +} + +static void cleanup_delivery_ctx (void *n) +{ + struct delivery_ctx *delivery_ctx = (struct delivery_ctx *)n; + ddsrt_free(delivery_ctx); +} + +static const ddsrt_avl_ctreedef_t delivery_ctx_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct delivery_ctx_t, node), offsetof (struct delivery_ctx_t, id), delivery_ctx_cmp, 0); + /* Administration to keep track of the request readers of a ds * that can act as a target to send requests for historical data to.. * Based on this administration requests for historical data are published immediately, @@ -427,6 +452,8 @@ struct dc_t { ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on a ds that match with my request writer */ ddsrt_avl_ctree_t proxy_sets; /* tree containing the sets for which data has to be provided by a ds */ uint32_t nr_of_matched_dc_requests; /* indicates the number of matched dc_request readers for the dc_request writer of this client */ + struct delivery_ctx_t *delivery_ctx; /* reference to current delivery context, NULL if none */ + ddsrt_avl_ctree_t delivery_ctxs; /* table of delivery contexts, keyed by ds id */ }; static struct dc_t dc = { 0 }; /* static durable client structure */ @@ -1218,6 +1245,232 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } +static struct proxy_set_t *dc_create_proxy_set (struct dc_t *dc, const char *partition, const char *tpname) +{ + struct proxy_set_t *proxy_set = NULL; + + assert(partition); + assert(tpname); + proxy_set = (struct proxy_set_t *)ddsrt_malloc(sizeof(struct proxy_set_t)); + proxy_set->key.partition = ddsrt_strdup(partition); + proxy_set->key.tpname = ddsrt_strdup(tpname); + proxy_set->seq = 0; /* no pending request yet */ + ddsrt_avl_cinit(&proxy_set_reader_td, &proxy_set->readers); + ddsrt_avl_cinsert(&proxy_set_td, &dc->proxy_sets, proxy_set); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "proxy set '%s.%s' created\n", proxy_set->key.partition, proxy_set->key.tpname); + return proxy_set; +} + +static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, bool autocreate) +{ + struct proxy_set_key_t key; + struct proxy_set_t *proxy_set; + + assert(partition); + assert(tpname); + key.partition = ddsrt_strdup(partition); + key.tpname = ddsrt_strdup(tpname); + if (((proxy_set = ddsrt_avl_clookup (&proxy_set_td, &dc->proxy_sets, &key)) == NULL) && autocreate) { + proxy_set = dc_create_proxy_set(dc, partition, tpname); + } + ddsrt_free(key.partition); + ddsrt_free(key.tpname); + return proxy_set; +} + +/* lookup the delivery context for the ds identified by id + * if not found and autocreate=true, then create the delivery context */ +static struct delivery_ctx_t *dc_get_delivery_ctx (struct dc_t *dc, DurableSupport_id_t id, bool autocreate) +{ + struct delivery_ctx_t *delivery_ctx = NULL; + + if ((dc->delivery_ctx != NULL) && (memcmp(dc->delivery_ctx->id,id,16) == 0)) { + delivery_ctx = dc->delivery_ctx; + } else if (((delivery_ctx = ddsrt_avl_clookup (&delivery_ctx_td, &dc->delivery_ctxs, id)) == NULL) && autocreate) { + delivery_ctx = ddsrt_malloc(sizeof(struct delivery_ctx_t)); + memcpy(delivery_ctx->id,id,16); + delivery_ctx->delivery_id = 0; + delivery_ctx->proxy_set = NULL; + ddsrt_avl_cinsert(&delivery_ctx_td, &dc->delivery_ctxs, delivery_ctx); + } + return delivery_ctx; +} + +/* Remove the current delivery */ +static void dc_remove_current_delivery (struct dc_t *dc) +{ + struct delivery_ctx_t *delivery_ctx; + ddsrt_avl_dpath_t dpath; + + if (dc->delivery_ctx) { + + if ((delivery_ctx = ddsrt_avl_clookup_dpath(&delivery_ctx_td, &dc->delivery_ctxs, dc->delivery_ctx->id, &dpath)) != NULL) { + assert(dc->delivery_ctx == delivery_ctx); + /* remove the delivery ctx from the tree */ + ddsrt_avl_cdelete_dpath(&delivery_ctx_td, &dc->delivery_ctxs, delivery_ctx, &dpath); + cleanup_delivery_ctx(delivery_ctx); + } + /* reset the current delivery ctx */ + dc->delivery_ctx = NULL; + } +} + +/* Abort the current delivery (i.e., dc->delivery_ctx) */ +static void dc_abort_current_delivery (struct dc_t *dc) +{ + char id_str[37]; + + assert(dc->delivery_ctx); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "aborting delivery %" PRIu64 " from ds \"%s\"\n", + dc->delivery_ctx->delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str)); + /* todo: reschedule the proxy set */ + + /* remove the current delivery ctx */ + dc_remove_current_delivery(dc); +} + +/* open the delivery context for the ds identified by id */ +static void dc_open_delivery (struct dc_t *dc, DurableSupport_response *response) +{ + char id_str[37]; + uint64_t delivery_id; + + assert(response); + assert(response->body._u.set.flags & DC_FLAG_SET_BEGIN); + delivery_id = response->body._u.set.delivery_id; + /* now create the new delivery context */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, true)) == NULL) { + DDS_ERROR("unable to create an delivery context for ds \"%s\" and delivery id %" PRIu64 "\n", dc_stringify_id(response->id, id_str), delivery_id); + abort(); + } + /* set the delivery_id and proxy set for this delivery context */ + dc->delivery_ctx->delivery_id = delivery_id; + if ((dc->delivery_ctx->proxy_set = dc_get_proxy_set(dc, response->body._u.set.partition, response->body._u.set.tpname, false)) == NULL) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "no proxy set for \"%s.%s\" found, ignore delivery\n", response->body._u.set.partition, response->body._u.set.tpname); + /* abort this delivery context */ + dc_abort_current_delivery(dc); + return; + } + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s\" opened\n", + delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str), dc->delivery_ctx->proxy_set->key.partition, dc->delivery_ctx->proxy_set->key.tpname); +} + +/* close the current delivery context for the ds identified by id */ +static void dc_close_delivery (struct dc_t *dc, DurableSupport_id_t id, DurableSupport_response_set_t *response_set) +{ + char id_str[37]; + + DC_UNUSED_ARG(response_set); + DC_UNUSED_ARG(id); + assert(response_set); + assert(response_set->flags & DC_FLAG_SET_END); + assert(memcmp(dc->delivery_ctx->id,id,16) == 0); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s\" closed\n", + dc->delivery_ctx->delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str), dc->delivery_ctx->proxy_set->key.partition, dc->delivery_ctx->proxy_set->key.tpname); + /* todo: mark the proxy set as complete */ + + /* remove current delivery ctx */ + dc_remove_current_delivery(dc); +} + +static void dc_process_set_response_begin(struct dc_t *dc, DurableSupport_response *response) +{ + assert(response); + assert(response->body._d == DurableSupport_RESPONSETYPE_SET); + /* A response set begin is received. If there already exists an open delivery + * context for this ds which has not been ended correctly, then this + * previous delivery has failed and needs to be aborted. */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, false)) != NULL) { + assert(memcmp(dc->delivery_ctx->id, response->id, 16) == 0); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "current open delivery %" PRIu64 " has missed an end\n", dc->delivery_ctx->delivery_id); + /* abort the currently open delivery */ + dc_abort_current_delivery(dc); + } + assert(dc->delivery_ctx == NULL); + /* open the new delivery */ + dc_open_delivery(dc, response); +} + +static void dc_process_set_response_end (struct dc_t *dc, DurableSupport_response *response) +{ + char id_str[37]; + + /* A response set end is received. Lookup the existing delivery context for this ds */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, false)) != NULL) { + assert(memcmp(dc->delivery_ctx->id, response->id, 16) == 0); + /* verify that this response set end belongs the currently opened delivery. + * by comparing the delivery_id. If they do not match, then this response + * set end does not belong to the currently opened set. This means that + * delivery of the currently opened set has failed and needs to be aborted. */ + if (dc->delivery_ctx->delivery_id != response->body._u.set.delivery_id) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "current open delivery %" PRIu64 " does not belong to end delivery %" PRIu64 "\n", + dc->delivery_ctx->delivery_id, response->body._u.set.delivery_id); + /* abort the currently open delivery */ + dc_abort_current_delivery(dc); + } else { + /* the end belongs to the correct begin; we have received all data for the set + * and can properly close the delivery */ + dc_close_delivery(dc, response->id, &response->body._u.set); + } + } else { + /* an end was received without a begin; no need to abort */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "end delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s\" received, but no corresponding open delivery found\n", + response->body._u.set.delivery_id, dc_stringify_id(response->id, id_str), response->body._u.set.partition, response->body._u.set.tpname); + } +} + +static void dc_process_set_response_not_found(struct dc_t *dc, DurableSupport_response *response) +{ + /* the set indicated in the response does not exist at the ds. + * This can for example happen when a transient reader has been created, + * but no transient writer exists. In such cases we can mark the reader + * as complete. + */ + DC_UNUSED_ARG(dc); + DC_UNUSED_ARG(response); +} + +static void dc_process_set_response (struct dc_t *dc, DurableSupport_response *response) +{ + assert(response->body._d == DurableSupport_RESPONSETYPE_SET); + if (response->body._u.set.flags & DC_FLAG_SET_BEGIN) { + dc_process_set_response_begin(dc, response); + } else if (response->body._u.set.flags & DC_FLAG_SET_END) { + dc_process_set_response_end(dc, response); + } else if (response->body._u.set.flags & DC_FLAG_SET_NOT_FOUND) { + dc_process_set_response_not_found(dc, response); + } else { + DDS_ERROR("invalid response set flag 0x%04" PRIx32, response->body._u.set.flags); + } +} + +static void dc_process_data_response (struct dc_t *dc, DurableSupport_response *response) +{ + struct proxy_set_t *proxy_set = NULL; + + /* TODO: + * A DS also has a response reader (by virtue of the CycloneDDS instance it runs). + * Currently, a DS therefore also receives responses that it sends itself. + * Because they is no proxy set the data is not injected, but I still like + * to have that a ds never receives responses. */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, false)) == NULL) { + /* There is no delivery context for this data, which means that this node + * did not request data for this set. If we do receive data, then we + * can safely ignore it. */ + return; + } + if ((proxy_set = dc->delivery_ctx->proxy_set) == NULL) { + /* There is no proxy set for this data, which means that this node + * did not request data for this set. If we do receive data, then we + * can safely ignore it. */ + return; + } + /* A response_set begin has been received. Because data delivery is reliable, + * we are sure that we missed no responses, so the data response that we received + * must belong to the proxy set. */ +// printf("LH *** inject data from proxy set \"%s.%s\"\n", proxy_set->key.partition, proxy_set->key.tpname); +} + static int dc_process_response (dds_entity_t rd, struct dc_t *dc) { #define MAX_SAMPLES 100 @@ -1246,6 +1499,17 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) /* LH: TODO: add statistics for responses */ DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dc_response %s%s\n", str, (len >= sizeof(str)) ? "..(trunc)" : ""); + /* deliver the received response to the readers belonging to the proxy set */ + switch (response->body._d) { + case DurableSupport_RESPONSETYPE_SET: + dc_process_set_response(dc, response); + break; + case DurableSupport_RESPONSETYPE_DATA: + dc_process_data_response(dc, response); + break; + default : + DDS_ERROR("invalid response type %" PRIu16, response->body._d); + } } } (void)dds_return_loan(rd, samples, samplecount); @@ -1255,39 +1519,6 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } -static struct proxy_set_t *dc_create_proxy_set (struct dc_t *dc, const char *partition, const char *tpname) -{ - struct proxy_set_t *proxy_set = NULL; - - assert(partition); - assert(tpname); - proxy_set = (struct proxy_set_t *)ddsrt_malloc(sizeof(struct proxy_set_t)); - proxy_set->key.partition = ddsrt_strdup(partition); - proxy_set->key.tpname = ddsrt_strdup(tpname); - proxy_set->seq = 0; /* no pending request yet */ - ddsrt_avl_cinit(&proxy_set_reader_td, &proxy_set->readers); - ddsrt_avl_cinsert(&proxy_set_td, &dc->proxy_sets, proxy_set); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "proxy set '%s.%s' created\n", proxy_set->key.partition, proxy_set->key.tpname); - return proxy_set; -} - -static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, bool autocreate) -{ - struct proxy_set_key_t key; - struct proxy_set_t *proxy_set; - - assert(partition); - assert(tpname); - key.partition = ddsrt_strdup(partition); - key.tpname = ddsrt_strdup(tpname); - if (((proxy_set = ddsrt_avl_clookup (&proxy_set_td, &dc->proxy_sets, &key)) == NULL) && autocreate) { - proxy_set = dc_create_proxy_set(dc, partition, tpname); - } - ddsrt_free(key.partition); - ddsrt_free(key.tpname); - return proxy_set; -} - /* add the reader tree of readers for this proxy set */ static void dc_register_reader_to_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, dds_guid_t guid, struct dds_rhc *rhc) { @@ -1589,8 +1820,8 @@ static uint32_t recv_handler (void *a) } /* set the request listener to learn about the existence of matching request readers. - * Because matches may have occurred already before */ - + * This purpose of this function is acquire matched subscriptions for late joining + * request writers. */ static dds_return_t activate_request_listener (struct dc_t *dc) { dds_return_t rc, ret; @@ -1674,6 +1905,8 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom dc.cfg.ident = ddsrt_strdup(DEFAULT_IDENT); dc.selected_request_reader_ih = DDS_HANDLE_NIL; dc.nr_of_matched_dc_requests = 0; + dc.delivery_ctx = NULL; /* initially no current open delivery context */ + ddsrt_avl_cinit(&delivery_ctx_td, &dc.delivery_ctxs); ddsrt_avl_cinit(&server_td, &dc.servers); ddsrt_avl_cinit(&matched_request_readers_td, &dc.matched_request_readers); ddsrt_avl_cinit(&pending_requests_td, &dc.pending_requests); @@ -1738,7 +1971,7 @@ dds_return_t dds_durability_fini (void) return DDS_RETCODE_OK; } if (dc.com) { - /* indicate the the durable client is teminating */ + /* indicate the the durable client is terminating */ ddsrt_atomic_st32 (&dc.termflag, 1); /* force the dc thread to terminate */ if ((rc = dds_waitset_set_trigger(dc.com->ws, true)) < 0) { @@ -1751,6 +1984,7 @@ dds_return_t dds_durability_fini (void) dds_delete_listener(dc.request_listener); dds_delete_listener(dc.quorum_listener); dc_com_free(dc.com); + ddsrt_avl_cfree(&delivery_ctx_td, &dc.delivery_ctxs, cleanup_delivery_ctx); ddsrt_cond_destroy(&dc.pending_request_cond); ddsrt_mutex_destroy(&dc.pending_request_mutex); ddsrt_avl_cfree(&proxy_set_td, &dc.proxy_sets, cleanup_proxy_set); diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index c15192752f..e59f18b323 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -711,11 +711,12 @@ static const uint32_t DurableSupport_response_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_response_content, _d), 2u, (12u << 16u) + 4u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 9 /* response_set_t */, 1, offsetof (DurableSupport_response_content, _u.set), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 13 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 15 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, DDS_OP_RTS, /* response_set_t */ DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_response_set_t, delivery_id), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, partition), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, tpname), DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_response_set_t, flags), @@ -732,142 +733,161 @@ static const uint32_t DurableSupport_response_ops [] = static const dds_key_descriptor_t DurableSupport_response_keys[1] = { - { "id", 34, 0 } + { "id", 36, 0 } }; /* Type Information: - [MINIMAL cf1872b677b74fe96238ec83b9a2] (#deps: 5) + [MINIMAL 730b9fd245b7a2458badcdadd452] (#deps: 6) - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 8691a7e3485bf0cdaeaf8f18ae96] + - [MINIMAL b2788efd3d9c71afbf128dd8d568] - [MINIMAL 80455e796dd3437163cb532089da] - - [MINIMAL 93ae2a1819f89109310333cdd898] + - [MINIMAL 26fb4226a2ccc89e6a040bf4add4] + - [MINIMAL d8398b259af5a04792e296996c27] - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE 41db4720b87e5b250e570da55eff] (#deps: 5) + [COMPLETE 11d82f7f8e658cff91d8836b578f] (#deps: 6) - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE f9cb4201664aea89e45563ec138a] + - [COMPLETE b6edd532689bbbb0dee0ee93c7ae] - [COMPLETE eec1bad6badde73f40ef199fedcc] - - [COMPLETE df8d519cc0ad7b43f266d2a4d8e9] + - [COMPLETE 6c90b4bf595ec04bb56d1fd6e2b5] + - [COMPLETE 7b005a124ff7bda9c39eb4003556] - [COMPLETE 008875599776c39ce0c1fe897846] */ #define TYPE_INFO_CDR_DurableSupport_response (const unsigned char []){ \ - 0x50, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xa0, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0xcf, 0x18, 0x72, 0xb6, 0x77, 0xb7, 0x4f, 0xe9, 0x62, 0x38, 0xec, \ - 0x83, 0xb9, 0xa2, 0x00, 0x55, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x80, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x73, 0x0b, 0x9f, 0xd2, 0x45, 0xb7, 0xa2, 0x45, 0x8b, 0xad, 0xcd, \ + 0xad, 0xd4, 0x52, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x86, 0x91, 0xa7, 0xe3, 0x48, 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0x00, \ + 0xf1, 0xb2, 0x78, 0x8e, 0xfd, 0x3d, 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0x00, \ 0x7c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x93, 0xae, 0x2a, 0x18, 0x19, 0xf8, 0x91, 0x09, 0x31, 0x03, 0x33, 0xcd, 0xd8, 0x98, 0x00, \ - 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, \ - 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0xa0, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x41, 0xdb, 0x47, \ - 0x20, 0xb8, 0x7e, 0x5b, 0x25, 0x0e, 0x57, 0x0d, 0xa5, 0x5e, 0xff, 0x00, 0x87, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xf9, 0xcb, 0x42, 0x01, 0x66, 0x4a, 0xea, \ - 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, 0x8a, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, \ - 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, \ - 0x43, 0xf2, 0x66, 0xd2, 0xa4, 0xd8, 0xe9, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x26, 0xfb, 0x42, 0x26, 0xa2, 0xcc, 0xc8, 0x9e, 0x6a, 0x04, 0x0b, 0xf4, 0xad, 0xd4, 0x00, \ + 0x67, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ + 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ + 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x11, 0xd8, 0x2f, 0x7f, 0x8e, 0x65, 0x8c, 0xff, 0x91, 0xd8, 0x83, \ + 0x6b, 0x57, 0x8f, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xb6, 0xed, 0xd5, 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, 0xe0, 0xee, 0x93, 0xc7, 0xae, 0x00, \ + 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, \ + 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, 0xc0, 0x4b, 0xb5, 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0x00, \ + 0xbc, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, \ + 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ 0x57, 0x00, 0x00, 0x00\ } -#define TYPE_INFO_CDR_SZ_DurableSupport_response 340u +#define TYPE_INFO_CDR_SZ_DurableSupport_response 388u #define TYPE_MAP_CDR_DurableSupport_response (const unsigned char []){ \ - 0xdc, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xf1, 0xcf, 0x18, 0x72, 0xb6, 0x77, 0xb7, 0x4f, \ - 0xe9, 0x62, 0x38, 0xec, 0x83, 0xb9, 0xa2, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x20, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0x73, 0x0b, 0x9f, 0xd2, 0x45, 0xb7, 0xa2, \ + 0x45, 0x8b, 0xad, 0xcd, 0xad, 0xd4, 0x52, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x86, 0x91, 0xa7, 0xe3, 0x48, \ - 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xb2, 0x78, 0x8e, 0xfd, 0x3d, \ + 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x86, 0x91, 0xa7, 0xe3, 0x48, \ - 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0xb2, 0x78, 0x8e, 0xfd, 0x3d, \ + 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ 0x54, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x93, 0xae, 0x2a, 0x18, 0x19, 0xf8, 0x91, 0x09, 0x31, 0x03, 0x33, 0xcd, 0xd8, \ - 0x98, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ + 0x01, 0x00, 0xf1, 0x26, 0xfb, 0x42, 0x26, 0xa2, 0xcc, 0xc8, 0x9e, 0x6a, 0x04, 0x0b, 0xf4, 0xad, \ + 0xd4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x93, 0xae, 0x2a, 0x18, \ - 0x19, 0xf8, 0x91, 0x09, 0x31, 0x03, 0x33, 0xcd, 0xd8, 0x98, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x7e, 0x75, 0xc0, 0xed, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, \ - 0x58, 0x68, 0xd6, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, \ - 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, \ - 0x03, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xf2, 0x41, 0xdb, 0x47, 0x20, 0xb8, 0x7e, 0x5b, \ - 0x25, 0x0e, 0x57, 0x0d, 0xa5, 0x5e, 0xff, 0x00, 0x83, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, \ - 0x6f, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xf9, 0xcb, 0x42, 0x01, 0x66, 0x4a, 0xea, 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, \ - 0x8a, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, \ - 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, \ - 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ - 0xf2, 0xf9, 0xcb, 0x42, 0x01, 0x66, 0x4a, 0xea, 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, 0x8a, 0x00, \ - 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, \ - 0x74, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0xee, \ - 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x00, \ - 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, 0x43, 0xf2, 0x66, 0xd2, 0xa4, 0xd8, \ - 0xe9, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, \ - 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, \ - 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x26, 0xfb, 0x42, 0x26, \ + 0xa2, 0xcc, 0xc8, 0x9e, 0x6a, 0x04, 0x0b, 0xf4, 0xad, 0xd4, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ + 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x7c, 0x4b, 0x99, \ + 0xfe, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x7e, 0x75, 0xc0, 0xed, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, \ + 0x58, 0x68, 0xd6, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ + 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, \ + 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \ + 0xee, 0x26, 0x90, 0x8b, 0x7f, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0x11, 0xd8, 0x2f, \ + 0x7f, 0x8e, 0x65, 0x8c, 0xff, 0x91, 0xd8, 0x83, 0x6b, 0x57, 0x8f, 0x00, 0x83, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xb6, 0xed, 0xd5, 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, \ + 0xe0, 0xee, 0x93, 0xc7, 0xae, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, \ + 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, \ + 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x10, 0x02, 0x00, 0x00, 0xf2, 0xb6, 0xed, 0xd5, 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, 0xe0, 0xee, \ + 0x93, 0xc7, 0xae, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ + 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, \ + 0x11, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, \ + 0xcc, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, 0xc0, 0x4b, 0xb5, \ + 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, \ + 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, \ + 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, \ + 0xc0, 0x4b, 0xb5, 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0xb8, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, \ - 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, 0x43, 0xf2, 0x66, \ - 0xd2, 0xa4, 0xd8, 0xe9, 0x88, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x27, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ - 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, \ - 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, \ - 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ - 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ + 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x7b, \ + 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, \ + 0x73, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, \ + 0x00, 0x35, 0x56, 0x00, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, \ + 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, \ + 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, \ 0x53, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x20, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, \ 0x61, 0x5f, 0x74, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, \ - 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, \ - 0xf2, 0x41, 0xdb, 0x47, 0x20, 0xb8, 0x7e, 0x5b, 0x25, 0x0e, 0x57, 0x0d, 0xa5, 0x5e, 0xff, 0xf1, \ - 0xcf, 0x18, 0x72, 0xb6, 0x77, 0xb7, 0x4f, 0xe9, 0x62, 0x38, 0xec, 0x83, 0xb9, 0xa2, 0xf2, 0xac, \ + 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0xf2, 0x11, 0xd8, 0x2f, 0x7f, 0x8e, 0x65, 0x8c, 0xff, 0x91, 0xd8, 0x83, 0x6b, 0x57, 0x8f, 0xf1, \ + 0x73, 0x0b, 0x9f, 0xd2, 0x45, 0xb7, 0xa2, 0x45, 0x8b, 0xad, 0xcd, 0xad, 0xd4, 0x52, 0xf2, 0xac, \ 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0xf9, 0xcb, 0x42, \ - 0x01, 0x66, 0x4a, 0xea, 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, 0x8a, 0xf1, 0x86, 0x91, 0xa7, 0xe3, \ - 0x48, 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0xb6, 0xed, 0xd5, \ + 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, 0xe0, 0xee, 0x93, 0xc7, 0xae, 0xf1, 0xb2, 0x78, 0x8e, 0xfd, \ + 0x3d, 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, \ 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, \ - 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, \ - 0x43, 0xf2, 0x66, 0xd2, 0xa4, 0xd8, 0xe9, 0xf1, 0x93, 0xae, 0x2a, 0x18, 0x19, 0xf8, 0x91, 0x09, \ - 0x31, 0x03, 0x33, 0xcd, 0xd8, 0x98, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, \ - 0xc1, 0xfe, 0x89, 0x78, 0x46, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, \ - 0x94, 0xaa, 0xe8, 0x44\ + 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, 0xc0, \ + 0x4b, 0xb5, 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0xf1, 0x26, 0xfb, 0x42, 0x26, 0xa2, 0xcc, 0xc8, 0x9e, \ + 0x6a, 0x04, 0x0b, 0xf4, 0xad, 0xd4, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, \ + 0x9e, 0xb4, 0x00, 0x35, 0x56, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, \ + 0x96, 0x99, 0x6c, 0x27, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, \ + 0x89, 0x78, 0x46, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, \ + 0xe8, 0x44\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_response 1444u +#define TYPE_MAP_CDR_SZ_DurableSupport_response 1666u const dds_topic_descriptor_t DurableSupport_response_desc = { .m_size = sizeof (DurableSupport_response), @@ -876,10 +896,9 @@ const dds_topic_descriptor_t DurableSupport_response_desc = .m_nkeys = 1u, .m_typename = "DurableSupport::response", .m_keys = DurableSupport_response_keys, - .m_nops = 17, + .m_nops = 18, .m_ops = DurableSupport_response_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_response, .sz = TYPE_INFO_CDR_SZ_DurableSupport_response }, .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_response, .sz = TYPE_MAP_CDR_SZ_DurableSupport_response } }; - From 9411e0c94f328381809452ac9675e9557f4ac619 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Wed, 20 Dec 2023 09:16:02 +0100 Subject: [PATCH 027/207] Data delivery to local readers Signed-off-by: TheFixer --- src/durability/src/dds_durability.c | 107 +++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 3 deletions(-) diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 5cfad75937..1dc1617c18 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -22,6 +22,7 @@ #include "dds__writer.h" #include "dds/ddsi/ddsi_endpoint.h" #include "dds/ddsrt/avl.h" +#include "dds/ddsi/ddsi_serdata.h" #define DEFAULT_QOURUM 1 #define DEFAULT_IDENT "durable_support" @@ -236,6 +237,7 @@ static int cmp_proxy_set_reader (const void *a, const void *b) struct proxy_set_reader_t { ddsrt_avl_node_t node; struct proxy_set_reader_key_t key; + dds_entity_t reader; struct dds_rhc *rhc; }; @@ -1444,9 +1446,57 @@ static void dc_process_set_response (struct dc_t *dc, DurableSupport_response *r } } +#if 0 +int dc_deliver_blob () +{ +} +#endif + +/* todo: this function is hared between ds and client */ +static enum ddsi_serdata_kind get_serdata_kind (uint8_t kind) +{ + enum ddsi_serdata_kind result = SDK_EMPTY; + + if (kind == 0) { + result = SDK_EMPTY; + } else if (kind == 1) { + result = SDK_KEY; + } else if (kind == 2) { + result = SDK_DATA; + } else { + DDS_ERROR("Invalid serdata kind %d", kind); + abort(); + } + return result; +} + +/* These are the offsets used in the data responses. + * TODO: These definitions should actually be shared between the ds and the client. + */ +#define RESPONSE_HEADER_OFFSET_WT 8 +#define RESPONSE_HEADER_OFFSET_SEQNUM 16 +#define RESPONSE_HEADER_OFFSET_WRITER_GUID 24 +#define RESPONSE_HEADER_OFFSET_SERDATA_KIND 40 +#define RESPONSE_HEADER_OFFSET_SERDATA 41 + + static void dc_process_data_response (struct dc_t *dc, DurableSupport_response *response) { struct proxy_set_t *proxy_set = NULL; + ddsrt_avl_citer_t it; + const struct ddsi_sertype *sertype; + struct ddsi_serdata *serdata; + uint32_t response_size, serdata_size;; + uint32_t serdata_offset; + ddsrt_iovec_t data_out; + int64_t wt; + uint64_t seqnum; + enum ddsi_serdata_kind serdata_kind; + dds_guid_t wguid; + dds_return_t ret = DDS_RETCODE_OK; + bool autodispose; + struct proxy_set_reader_t *proxy_set_rd; + char id_str[37]; /* TODO: * A DS also has a response reader (by virtue of the CycloneDDS instance it runs). @@ -1468,7 +1518,57 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * /* A response_set begin has been received. Because data delivery is reliable, * we are sure that we missed no responses, so the data response that we received * must belong to the proxy set. */ -// printf("LH *** inject data from proxy set \"%s.%s\"\n", proxy_set->key.partition, proxy_set->key.tpname); + response_size = response->body._u.data.blob._length; + serdata_offset = ddsrt_fromBE4u(*((uint32_t *)response->body._u.data.blob._buffer)); + wt = ddsrt_fromBE8(*((int64_t *)(response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_WT))); + seqnum = ddsrt_fromBE8u(*((uint64_t *)(response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_SEQNUM))); + memcpy(&wguid.v, response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_WRITER_GUID, 16); + serdata_kind = get_serdata_kind(*((uint8_t *)response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_SERDATA_KIND)); + /* We could now potentially figure out if the response that has been received + * contains fields that we cannot interpret. We can find that out by comparing + * the received response_offset with my own RESPONSE_HEADER_OFFSET_SERDATA. + * If serdata_offset > RESPONSE_HEADER_OFFSET_SERDATA then this is an indication + * that the ds has more fields than this client can interpret. */ + /* get the serdata */ + serdata_size = response_size - serdata_offset; + data_out.iov_len = serdata_size; + data_out.iov_base = response->body._u.data.blob._buffer + serdata_offset; + /* now deliver the data to the local readers that have an interest in the data */ + for (proxy_set_rd = ddsrt_avl_citer_first (&proxy_set_reader_td, &proxy_set->readers, &it); proxy_set_rd; proxy_set_rd = ddsrt_avl_citer_next (&it)) { + dds_entity_t reader = proxy_set_rd->reader; + /* in order to insert the data in the rhc of the reader we first + * need to resolve the type of the reader */ + if ((ret = dds_get_entity_sertype (reader, &sertype)) < 0) { + /* We failed to get the sertype. If it happens I do not consider + * this my problem, it is a problem in CycloneDDS. + * For now I silently ignore the data. After all, I cannot + * deliver the data to this reader! */ + continue; + } + /* get the serdata */ + if ((serdata = ddsi_serdata_from_ser_iov (sertype, serdata_kind, 1, &data_out, serdata_size)) == NULL) { + /* Failed to get the serdata. If it happens I do not consider + * this my problem, it is a problem in CycloneDDS. The only thing + * I can do is to handle this case. For now I silently ignore the data. + */ + goto err_serdata; + } + serdata->sequence_number = seqnum; + serdata->timestamp.v = wt; + memcpy(&serdata->writer_guid, &wguid, 16); + autodispose = false; /* TODO: we have to retrieve the autodispose setting of the writer! */ + if ((ret = dds_reader_store_historical_serdata(reader, wguid, autodispose, serdata)) != DDS_RETCODE_OK) { + DDS_ERROR("Failed to deliver historical data to reader \"%s\" [%s]\n", dc_stringify_id(proxy_set_rd->key.guid.v, id_str), dds_strretcode(ret)); + goto err_store_historical_serdata; + } + ddsi_serdata_to_ser_unref(serdata, &data_out); + } + return; + +err_store_historical_serdata: + ddsi_serdata_to_ser_unref(serdata, &data_out); +err_serdata: + return; } static int dc_process_response (dds_entity_t rd, struct dc_t *dc) @@ -1520,7 +1620,7 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) } /* add the reader tree of readers for this proxy set */ -static void dc_register_reader_to_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, dds_guid_t guid, struct dds_rhc *rhc) +static void dc_register_reader_to_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, dds_guid_t guid, dds_entity_t reader, struct dds_rhc *rhc) { struct proxy_set_reader_t *proxy_set_rd; struct proxy_set_reader_key_t key; @@ -1530,6 +1630,7 @@ static void dc_register_reader_to_proxy_set (struct dc_t *dc, struct proxy_set_t if ((proxy_set_rd = ddsrt_avl_clookup (&proxy_set_reader_td, &proxy_set->readers, &key)) == NULL) { proxy_set_rd = (struct proxy_set_reader_t *)ddsrt_malloc(sizeof(struct proxy_set_reader_t)); proxy_set_rd->key.guid = guid; + proxy_set_rd->reader = reader; proxy_set_rd->rhc = rhc; ddsrt_avl_cinsert(&proxy_set_reader_td, &proxy_set->readers, proxy_set_rd); DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "reader \"%s\" added to proxy set '%s.%s'\n", dc_stringify_id(guid.v, id_str), proxy_set->key.partition, proxy_set->key.tpname); @@ -1597,7 +1698,7 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade * We do this BEFORE we send the request, so that we are sure * that when we receive the response (possibly immediately after * sending the request) the reader and rhc are present */ - dc_register_reader_to_proxy_set(dc, proxy_set, guid, rhc); + dc_register_reader_to_proxy_set(dc, proxy_set, guid, reader, rhc); /* send a request for this proxy set */ if ((rc = dc_com_request_write(dc->com, proxy_set->key.partition, proxy_set->key.tpname)) != DDS_RETCODE_OK) { DDS_ERROR("Failed to publish dc_request for proxy set %s.%s\n", proxy_set->key.partition, proxy_set->key.tpname); From 760656dd03b41b0c11e6c5b5f418d64a0a611efc Mon Sep 17 00:00:00 2001 From: TheFixer Date: Sat, 30 Dec 2023 21:59:03 +0100 Subject: [PATCH 028/207] Encode the writer's autodispose setting in response beads Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 6 + src/durability/src/dds_durability.c | 15 +- src/durability/src/durablesupport.c | 372 ++++++++++-------- 3 files changed, 214 insertions(+), 179 deletions(-) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index a430da24e1..837ca56dfc 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -177,6 +177,11 @@ typedef struct DurableSupport_set_t dds_sequence_DurableSupport_id_t addressees; } DurableSupport_set_t; +typedef struct DurableSupport_writer_properties_t +{ + bool autodispose; +} DurableSupport_writer_properties_t; + #ifndef DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED #define DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED typedef struct dds_sequence_DurableSupport_range @@ -197,6 +202,7 @@ typedef struct dds_sequence_DurableSupport_range typedef struct DurableSupport_writer_t { DurableSupport_id_t id; + struct DurableSupport_writer_properties_t properties; uint32_t flags; dds_sequence_DurableSupport_range ranges; } DurableSupport_writer_t; diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 1dc1617c18..d79aba4ad6 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -1473,11 +1473,12 @@ static enum ddsi_serdata_kind get_serdata_kind (uint8_t kind) /* These are the offsets used in the data responses. * TODO: These definitions should actually be shared between the ds and the client. */ -#define RESPONSE_HEADER_OFFSET_WT 8 -#define RESPONSE_HEADER_OFFSET_SEQNUM 16 -#define RESPONSE_HEADER_OFFSET_WRITER_GUID 24 -#define RESPONSE_HEADER_OFFSET_SERDATA_KIND 40 -#define RESPONSE_HEADER_OFFSET_SERDATA 41 +#define RESPONSE_HEADER_OFFSET_WT 8 +#define RESPONSE_HEADER_OFFSET_SEQNUM 16 +#define RESPONSE_HEADER_OFFSET_WRITER_GUID 24 +#define RESPONSE_HEADER_OFFSET_SERDATA_KIND 40 +#define RESPONSE_HEADER_OFFSET_SERDATA_AUTODISPOSE 41 +#define RESPONSE_HEADER_OFFSET_SERDATA 42 static void dc_process_data_response (struct dc_t *dc, DurableSupport_response *response) @@ -1494,7 +1495,7 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * enum ddsi_serdata_kind serdata_kind; dds_guid_t wguid; dds_return_t ret = DDS_RETCODE_OK; - bool autodispose; + bool autodispose = 0; struct proxy_set_reader_t *proxy_set_rd; char id_str[37]; @@ -1523,6 +1524,7 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * wt = ddsrt_fromBE8(*((int64_t *)(response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_WT))); seqnum = ddsrt_fromBE8u(*((uint64_t *)(response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_SEQNUM))); memcpy(&wguid.v, response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_WRITER_GUID, 16); + autodispose = *((uint8_t *)response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_SERDATA_AUTODISPOSE); serdata_kind = get_serdata_kind(*((uint8_t *)response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_SERDATA_KIND)); /* We could now potentially figure out if the response that has been received * contains fields that we cannot interpret. We can find that out by comparing @@ -1556,7 +1558,6 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * serdata->sequence_number = seqnum; serdata->timestamp.v = wt; memcpy(&serdata->writer_guid, &wguid, 16); - autodispose = false; /* TODO: we have to retrieve the autodispose setting of the writer! */ if ((ret = dds_reader_store_historical_serdata(reader, wguid, autodispose, serdata)) != DDS_RETCODE_OK) { DDS_ERROR("Failed to deliver historical data to reader \"%s\" [%s]\n", dc_stringify_id(proxy_set_rd->key.guid.v, id_str), dds_strretcode(ret)); goto err_store_historical_serdata; diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index e59f18b323..4b91e5a5cc 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -286,7 +286,7 @@ static const uint32_t DurableSupport_bead_ops [] = DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 17 /* session_t */, 1, offsetof (DurableSupport_content, _u.session), 0u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 19 /* set_t */, 2, offsetof (DurableSupport_content, _u.set), 0u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 31 /* writer_t */, 3, offsetof (DurableSupport_content, _u.writer), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 44 /* data_t */, 4, offsetof (DurableSupport_content, _u.data), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 51 /* data_t */, 4, offsetof (DurableSupport_content, _u.data), 0u, DDS_OP_RTS, /* session_t */ @@ -308,8 +308,14 @@ static const uint32_t DurableSupport_bead_ops [] = /* writer_t */ DDS_OP_DLC, DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_writer_t, id), 16u, + DDS_OP_ADR | DDS_OP_TYPE_EXT, offsetof (DurableSupport_writer_t, properties), (3u << 16u) + 10u /* writer_properties_t */, DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_writer_t, flags), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_writer_t, ranges), sizeof (DurableSupport_range), (4u << 16u) + 5u /* range */, + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_writer_t, ranges), sizeof (DurableSupport_range), (4u << 16u) + 9u /* range */, + DDS_OP_RTS, + + /* writer_properties_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_BLN, offsetof (DurableSupport_writer_properties_t, autodispose), DDS_OP_RTS, /* range */ @@ -329,82 +335,87 @@ static const uint32_t DurableSupport_bead_ops [] = static const dds_key_descriptor_t DurableSupport_bead_keys[1] = { - { "id", 73, 0 } + { "id", 80, 0 } }; /* Type Information: - [MINIMAL 1915eb63b1ad4283c95c42298512] (#deps: 9) + [MINIMAL ec4a62f36aef58a53c25ca352c96] (#deps: 10) - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 219813f96895eb7a5bddfe02219f] + - [MINIMAL 8081d593c0e4df1bcd51ee4ff1ef] - [MINIMAL 80455e796dd3437163cb532089da] - [MINIMAL 7fe2256248fb0dc7c6a9b6c616fb] - [MINIMAL d8398b259af5a04792e296996c27] - [MINIMAL 0d686e35dcd446cd843b793a485c] - - [MINIMAL 2f19a070996d925b553ac288a028] + - [MINIMAL 889fb89d6714387ca74c9aa42719] + - [MINIMAL 7d1dfbcf78261b30f20d1dadb067] - [MINIMAL ef038b7b19448c9ce27fa1c268cd] - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE a89c569f6d508f3372a8c6407126] (#deps: 10) + [COMPLETE 17238b8e235b286c8fdcbeb41197] (#deps: 11) - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE 28eef02baeaad008f0cda9febf47] + - [COMPLETE 1b1b74c5e6971d9d84029a5e04d3] - [COMPLETE 105e7fa73d9700c1960716873c88] - [COMPLETE 5de973c540260a829429a905efcd] - [COMPLETE 838f13c80cfd7a0061fb91f88e49] - [COMPLETE 9c5d42ec81585355d169823828eb] - [COMPLETE dd9a1bfb3c68ff5066e4b763a939] - - [COMPLETE 1b62cfe76a5bdbc5e39d9f6d3975] + - [COMPLETE e6c4e5bb805c08c1d9e923e071ea] + - [COMPLETE 7a239210b1658deca81e1474b300] - [COMPLETE d8d43c2295c185a21b9591a7126c] - [COMPLETE a092964f6f76e3d643846ba36f9b] */ #define TYPE_INFO_CDR_DurableSupport_bead (const unsigned char []){ \ - 0x28, 0x02, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x00, 0x01, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x19, 0x15, 0xeb, 0x63, 0xb1, 0xad, 0x42, 0x83, 0xc9, 0x5c, 0x42, \ - 0x29, 0x85, 0x12, 0x00, 0x55, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, \ - 0x09, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x58, 0x02, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x18, 0x01, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0xec, 0x4a, 0x62, 0xf3, 0x6a, 0xef, 0x58, 0xa5, 0x3c, 0x25, 0xca, \ + 0x35, 0x2c, 0x96, 0x00, 0x55, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, \ + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x21, 0x98, 0x13, 0xf9, 0x68, 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0x00, \ + 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, 0xf1, 0xef, 0x00, \ 0xcc, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0x00, \ 0x55, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, \ - 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, \ - 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, 0x28, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, \ - 0x37, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, \ - 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0x18, 0x01, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa8, 0x9c, 0x56, \ - 0x9f, 0x6d, 0x50, 0x8f, 0x33, 0x72, 0xa8, 0xc6, 0x40, 0x71, 0x26, 0x00, 0x83, 0x00, 0x00, 0x00, \ - 0x0a, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x28, 0xee, 0xf0, 0x2b, 0xae, 0xaa, 0xd0, \ - 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, 0x47, 0x00, 0x13, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, \ - 0x39, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, \ - 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, \ - 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, \ - 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0x00, \ - 0xb5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, 0x5b, 0xdb, \ - 0xc5, 0xe3, 0x9d, 0x9f, 0x6d, 0x39, 0x75, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, \ + 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, 0x19, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, 0x1d, 0xad, 0xb0, 0x67, 0x00, \ + 0x27, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, \ + 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x37, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ + 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x30, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x23, 0x8b, 0x8e, 0x23, 0x5b, 0x28, 0x6c, 0x8f, 0xdc, 0xbe, \ + 0xb4, 0x11, 0x97, 0x00, 0x83, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, \ + 0x0b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, 0x97, 0x1d, 0x9d, 0x84, 0x02, 0x9a, 0x5e, 0x04, 0xd3, 0x00, \ + 0x13, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, \ + 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, 0x39, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, \ + 0x8d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, \ + 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, \ + 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, \ + 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0x00, 0xb5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0x00, \ + 0xd5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, \ + 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, \ 0x61, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, \ 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x00, 0x4f, 0x00, 0x00, 0x00\ } -#define TYPE_INFO_CDR_SZ_DurableSupport_bead 556u +#define TYPE_INFO_CDR_SZ_DurableSupport_bead 604u #define TYPE_MAP_CDR_DurableSupport_bead (const unsigned char []){ \ - 0xc0, 0x03, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xf1, 0x19, 0x15, 0xeb, 0x63, 0xb1, 0xad, 0x42, \ - 0x83, 0xc9, 0x5c, 0x42, 0x29, 0x85, 0x12, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x18, 0x04, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xf1, 0xec, 0x4a, 0x62, 0xf3, 0x6a, 0xef, 0x58, \ + 0xa5, 0x3c, 0x25, 0xca, 0x35, 0x2c, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x21, 0x98, 0x13, 0xf9, 0x68, \ - 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, \ + 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, 0xf1, 0xef, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x21, 0x98, 0x13, 0xf9, 0x68, \ - 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, \ + 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, 0xf1, 0xef, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, \ 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ 0xa4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -413,8 +424,8 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, \ 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, \ - 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xa8, 0x2f, 0xee, 0xe3, \ + 0x01, 0x00, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xa8, 0x2f, 0xee, 0xe3, \ 0x24, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x04, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ @@ -438,139 +449,156 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, \ 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x73, 0xed, \ - 0xc9, 0x6c, 0xf1, 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, \ - 0x28, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0xc9, 0x6c, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, \ + 0x19, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, \ - 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, \ - 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x8d, 0x81, 0x02, 0xfb, 0xf1, 0xef, \ - 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x00, 0x00, \ - 0x33, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x08, 0x26, 0x40, 0x3e, 0xc6, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x08, 0x1c, 0x78, 0xb4, 0x86, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, \ - 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \ - 0xee, 0x26, 0x90, 0x8b, 0xcf, 0x05, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xf2, 0xa8, 0x9c, 0x56, \ - 0x9f, 0x6d, 0x50, 0x8f, 0x33, 0x72, 0xa8, 0xc6, 0x40, 0x71, 0x26, 0x00, 0x7f, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x62, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0x28, 0xee, 0xf0, 0x2b, 0xae, 0xaa, 0xd0, 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, \ - 0x47, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, \ - 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, \ - 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ - 0xf2, 0x28, 0xee, 0xf0, 0x2b, 0xae, 0xaa, 0xd0, 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, 0x47, 0x00, \ - 0x0f, 0x01, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x00, 0x13, 0x00, 0x00, 0x00, \ - 0x11, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, \ - 0x88, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, \ - 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x08, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, \ - 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, \ - 0x5b, 0xdb, 0xc5, 0xe3, 0x9d, 0x9f, 0x6d, 0x39, 0x75, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xa0, \ - 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, \ - 0x00, 0x00, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, \ - 0x3c, 0x88, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x62, 0x65, 0x61, 0x64, 0x74, 0x79, 0x70, 0x65, \ - 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x5d, 0xe9, \ - 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x89, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ + 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, \ + 0x0d, 0x1d, 0xad, 0xb0, 0x67, 0x74, 0x69, 0x3d, 0x2f, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, \ + 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x8d, 0x81, 0x02, 0xfb, 0xf1, 0x7d, \ + 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, 0x1d, 0xad, 0xb0, 0x67, 0x00, 0x00, 0x00, \ + 0x23, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x01, 0x1c, 0x63, 0x57, 0x19, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, \ + 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x26, 0x40, 0x3e, 0xc6, 0x00, \ + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x1c, 0x78, 0xb4, 0x86, 0xf1, \ + 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, \ + 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0x6f, 0x06, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x23, 0x8b, 0x8e, 0x23, 0x5b, 0x28, 0x6c, 0x8f, 0xdc, 0xbe, \ + 0xb4, 0x11, 0x97, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x62, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, \ + 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, \ + 0x97, 0x1d, 0x9d, 0x84, 0x02, 0x9a, 0x5e, 0x04, 0xd3, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ + 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, 0x97, 0x1d, \ + 0x9d, 0x84, 0x02, 0x9a, 0x5e, 0x04, 0xd3, 0x00, 0x0f, 0x01, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, \ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x63, 0x6f, 0x6e, 0x74, \ + 0x65, 0x6e, 0x74, 0x00, 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, \ + 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5d, \ + 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, \ + 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, \ + 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, \ + 0xea, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, \ + 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, \ + 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x83, \ - 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x6b, 0x69, 0x6e, 0x64, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, \ - 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, \ - 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, \ - 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, \ - 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, \ - 0x82, 0x38, 0x28, 0xeb, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x62, 0x65, 0x61, 0x64, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, \ + 0xa9, 0x05, 0xef, 0xcd, 0x89, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x22, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, \ - 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, \ - 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, \ - 0xb1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, \ - 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, \ - 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, \ - 0x5c, 0x6d, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, \ - 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, 0x5b, 0xdb, 0xc5, 0xe3, 0x9d, \ - 0x9f, 0x6d, 0x39, 0x75, 0xa1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, \ - 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, \ - 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x5d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x74, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, \ + 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6b, 0x69, 0x6e, 0x64, \ + 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x9c, \ + 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, 0x00, 0x00, \ + 0x0b, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x00, 0x00, \ + 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, \ + 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, \ + 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x9c, 0x5d, \ + 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x39, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, \ + 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0xb1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x61, 0x6e, 0x67, \ - 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6c, 0x62, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, \ - 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x4b, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x61, 0x74, 0x61, \ - 0x5f, 0x74, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, \ - 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0xf2, 0xa8, 0x9c, 0x56, 0x9f, 0x6d, 0x50, 0x8f, 0x33, 0x72, 0xa8, 0xc6, 0x40, 0x71, 0x26, 0xf1, \ - 0x19, 0x15, 0xeb, 0x63, 0xb1, 0xad, 0x42, 0x83, 0xc9, 0x5c, 0x42, 0x29, 0x85, 0x12, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x28, 0xee, 0xf0, \ - 0x2b, 0xae, 0xaa, 0xd0, 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, 0x47, 0xf1, 0x21, 0x98, 0x13, 0xf9, \ - 0x68, 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, \ - 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, \ - 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, \ - 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, \ - 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, \ - 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, \ - 0x53, 0x20, 0x89, 0xda, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, \ - 0x38, 0x28, 0xeb, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ - 0x6c, 0x27, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, \ - 0x39, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, \ - 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, 0x5b, 0xdb, 0xc5, 0xe3, 0x9d, 0x9f, 0x6d, 0x39, 0x75, 0xf1, \ - 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, 0x28, 0xf2, 0xd8, \ - 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, 0xef, 0x03, \ - 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0xf2, 0xa0, 0x92, 0x96, \ - 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, \ - 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x74, 0x5f, \ + 0x74, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, \ + 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xe6, 0xc4, \ + 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0xd1, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, \ + 0x1e, 0x14, 0x74, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x70, 0x72, 0x6f, 0x70, \ + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, \ + 0x73, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, \ + 0x01, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, \ + 0x12, 0x6c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, \ + 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, 0x00, \ + 0x5a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x24, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, \ + 0x72, 0x74, 0x69, 0x65, 0x73, 0x5f, 0x74, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, \ + 0x61, 0x75, 0x74, 0x6f, 0x64, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x00, 0x00, 0x00, 0xf2, 0xd8, \ + 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x00, \ + 0x5d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x6c, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, \ + 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, \ + 0x4b, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, \ + 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, \ + 0x6c, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x23, 0x8b, 0x8e, 0x23, 0x5b, 0x28, \ + 0x6c, 0x8f, 0xdc, 0xbe, 0xb4, 0x11, 0x97, 0xf1, 0xec, 0x4a, 0x62, 0xf3, 0x6a, 0xef, 0x58, 0xa5, \ + 0x3c, 0x25, 0xca, 0x35, 0x2c, 0x96, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, \ + 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, 0x97, 0x1d, 0x9d, 0x84, 0x02, 0x9a, \ + 0x5e, 0x04, 0xd3, 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, \ + 0xf1, 0xef, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, \ + 0x88, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, \ + 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0xf1, \ + 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0xf2, 0x83, \ + 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0xf1, 0x80, 0x45, \ + 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x9c, 0x5d, 0x42, \ + 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0xf1, 0xd8, 0x39, 0x8b, 0x25, \ + 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, \ + 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, \ + 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, \ + 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, \ + 0xa7, 0x4c, 0x9a, 0xa4, 0x27, 0x19, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, \ + 0x1e, 0x14, 0x74, 0xb3, 0x00, 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, \ + 0x1d, 0xad, 0xb0, 0x67, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, \ + 0xa7, 0x12, 0x6c, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, \ + 0x68, 0xcd, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, \ + 0x9b, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_bead 2794u +#define TYPE_MAP_CDR_SZ_DurableSupport_bead 3072u const dds_topic_descriptor_t DurableSupport_bead_desc = { .m_size = sizeof (DurableSupport_bead), @@ -579,7 +607,7 @@ const dds_topic_descriptor_t DurableSupport_bead_desc = .m_nkeys = 1u, .m_typename = "DurableSupport::bead", .m_keys = DurableSupport_bead_keys, - .m_nops = 35, + .m_nops = 39, .m_ops = DurableSupport_bead_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_bead, .sz = TYPE_INFO_CDR_SZ_DurableSupport_bead }, From d74ff57d4ecd70facca25c1043546e9db38dd779 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 2 Jan 2024 10:48:16 +0100 Subject: [PATCH 029/207] Inject historical data as unregistered when the proxy writer is not (yet?) discovered Signed-off-by: TheFixer --- src/core/ddsc/src/dds_reader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index 3a8df71815..0a706938e9 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -537,8 +537,8 @@ dds_return_t dds_reader_store_historical_serdata (dds_entity_t reader, dds_guid_ ret = DDS_RETCODE_BAD_PARAMETER; goto fail_tk_builtin; } - /* historical data is always unregistered */ - if (!ddsi_builtintopic_is_visible(gv->builtin_topic_interface, &ddsiguid, ddsi_get_entity_vendorid(&rd->e))) { + /* inject historical data as unregistered when the proxy writer is not (yet?) discovered */ + if (ddsi_entidx_lookup_proxy_writer_guid (gv->entity_index, &ddsiguid) == NULL) { serdata->statusinfo |= DDSI_STATUSINFO_UNREGISTER; } /* set the writer guid of the serdata */ From 2ff72c9a8e7029172333f6edf3ad1ba965d96841 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 5 Jan 2024 14:24:40 +0100 Subject: [PATCH 030/207] Fix crash when printing octet sequence, and improve printing of truncated octet sequences Signed-off-by: TheFixer --- src/durability/src/dds_durability.c | 99 +++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 27 deletions(-) diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index d79aba4ad6..aa48020a43 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -66,33 +66,78 @@ static char *dc_responsetype_image (DurableSupport_responsetype_t type) } } -static char *dc_blob_image (dds_sequence_octet blob) +static int dc_blob_image (dds_sequence_octet blob, char *buf, size_t n) { - char *buf; - uint32_t len; - uint32_t n; - uint32_t i; + uint32_t nrofbytes = 2 * blob._length + 1; /* the number of bytes to fill when the complete blob is stored, including the '\0' */ + uint32_t j; + size_t i = 0; + int l; -#define BLOB_IMAGE_SIZE 24 - len = (blob._length < BLOB_IMAGE_SIZE) ? blob._length : BLOB_IMAGE_SIZE; - n = len*2+1; - buf = ddsrt_malloc(n); - if (len < BLOB_IMAGE_SIZE) { - for (i=0; i < len; i++) { - sprintf(buf+i*2, "%02x", (char)blob._buffer[i]); + if (buf == NULL) { + /* no space allocated for display */ + return -1; + } + if (n == 0) { + /* do not print anything */ + return 0; + } + if (nrofbytes <= n) { + /* the complete blob fits in buf */ + for (j=0; j < blob._length; j++) { + if ((l = snprintf(buf+i, n-i, "%02x", (uint8_t)blob._buffer[j])) < 0) { + goto err; + } + assert(l < (int)(n-i)); /* never truncated */ + i += (size_t)l; } } else { - for (i=0; i < 11; i++) { - sprintf(buf+i*2, "%02x", (char)blob._buffer[i]); - } - strcpy(buf+22, "..."); - for (i=0; i < 11; i++) { - sprintf(buf+25+i*2, "%02x", (char)blob._buffer[len-11+i]); + /* The blob does not fit in buf. + * if n < 5 then we display '..'; + * if n >=5 and n < 7 we display 'AB..' + * if n > 7 we display 'AB..XY' (where the length of the head and tail varies depending on buf size n) + */ + if (n < 5) { + if ((l = snprintf(buf+i, n-i, "..")) < 0) { + goto err; + } + i += (size_t)l; + } else if (n < 7) { + if ((l = snprintf(buf+i, n-i, "%02x..", (uint8_t)blob._buffer[0])) < 0) { + goto err; + } + } else { + /* calculate head and tail part */ + size_t np = ((n-1) - 2) / 4; + size_t k; + /* print head */ + for (k=0; k < np; k++) { + if ((l = snprintf(buf+i, n-i, "%02x", (uint8_t)blob._buffer[k])) < 0) { + goto err; + } + assert(l < (int)(n-i)); /* impossible to overflow buf */ + i += (size_t)l; + } + /* print separator '..' */ + if ((l = snprintf(buf+i, n-i, "%s", "..")) < 0) { + goto err; + } + assert(l < (int)(n-i)); /* impossible to overflow buf */ + i += (size_t)l; + /* print tail */ + for (k=0; k < np; k++) { + if ((l = snprintf(buf+i, n-i, "%02x", (uint8_t)blob._buffer[blob._length - np + k])) < 0) { + goto err; + } + assert(l < (int)(n-i)); /* impossible to overflow buf */ + i += (size_t)l; + } } } - buf[2*len] = '\0'; -#undef BLOB_IMAGE_SIZE - return buf; + l = (int)i; + return (l >= (int)n) ? 0 /* no more space in buf */ : l; + +err: + return -1; } static int dc_stringify_request (char *buf, size_t n, const DurableSupport_request *request, bool valid_data) @@ -144,8 +189,8 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp { size_t i = 0; int l; - char *str; char id_str[37]; + char blob_str[64]; if (buf == NULL) { goto err; @@ -169,12 +214,12 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp i += (size_t)l; break; case DurableSupport_RESPONSETYPE_DATA : - str = dc_blob_image(response->body._u.data.blob); - if ((l = snprintf(buf+i, n-i, "\"blob\":\"%s\"", str)) < 0) { - ddsrt_free(str); + if (dc_blob_image(response->body._u.data.blob, blob_str, sizeof(blob_str)) < 0) { + goto err; + } + if ((l = snprintf(buf+i, n-i, "\"blob\":\"%s\"", blob_str)) < 0) { goto err; } - ddsrt_free(str); i += (size_t)l; break; default: @@ -2282,7 +2327,7 @@ dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) /* Check if the quorum for a durable writer is reached. * If not, we will head bang until the quorum is reached. - * To prevent starvation we use a 10ms sleep in between. + * To prevent starvation we use a 10ms sleep in between successive headbangs. * When the quorum is reached within the max_blocking_time, * DDS_RETCODE_OK is returned, otherwise DDS_PRECONDITION_NOT_MET * is returned. The max_blocking_time itself is retrieved lazily From 195a7d4d59d3938981b32c9480dcccb8f34faa62 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Wed, 7 Feb 2024 11:52:40 +0100 Subject: [PATCH 031/207] Add //CycloneDDS/Domain/Durability/Quorum configuration option to set the quorum Signed-off-by: TheFixer --- docs/manual/config/config_file_reference.rst | 32 ++++++++++++++-- docs/manual/options.md | 24 ++++++++++-- etc/cyclonedds.rnc | 14 ++++++- etc/cyclonedds.xsd | 23 +++++++++++- src/core/ddsi/defconfig.c | 7 +++- src/core/ddsi/include/dds/ddsi/ddsi_config.h | 4 ++ src/core/ddsi/src/ddsi__cfgelems.h | 39 ++++++++++++++++++++ 7 files changed, 131 insertions(+), 12 deletions(-) diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index 251f0e5f01..0cd03a9a2e 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -22,7 +22,7 @@ CycloneDDS configuration ******************* Attributes: :ref:`Id` -Children: :ref:`Compatibility`, :ref:`Discovery`, :ref:`General`, :ref:`Internal|Unsupported`, :ref:`Partitioning`, :ref:`SSL`, :ref:`Security|DDSSecurity`, :ref:`SharedMemory`, :ref:`Sizing`, :ref:`TCP`, :ref:`Threads`, :ref:`Tracing` +Children: :ref:`Compatibility`, :ref:`Discovery`, :ref:`Discovery`, :ref:`General`, :ref:`Internal|Unsupported`, :ref:`Partitioning`, :ref:`SSL`, :ref:`Security|DDSSecurity`, :ref:`SharedMemory`, :ref:`Sizing`, :ref:`TCP`, :ref:`Threads`, :ref:`Tracing` The General element specifying Domain related settings. @@ -374,6 +374,32 @@ String extension for domain id that remote participants must match to be discove The default value is: ```` +.. _`//CycloneDDS/Domain/Durability`: + +//CycloneDDS/Domain/Durability +============================== + +Children: `//CycloneDDS/Domain/Durability/Quorum`_ + +This element specifies settings related to durable data. + + +.. _`//CycloneDDS/Domain/Durability/Quorum`: + +//CycloneDDS/Domain/Durability/Quorum +------------------------------------- + +Integer + +This element specifies the minimum number of durable services that must be available before a durable writer can successfully publish durable data. The value must be equal or higher to 1 to ensure that there is at least one durable service present in the network that can receive the durable data and make it available to late joiners. By specifying a number higher than 1, additional fault tolerance can be achieved. + +As long as the number of available durable services drops below the specified quorum, durable writers will not be able to publish durable data. Any attempt to do so by calling dds\_write() (or one of its variants) will return DDS\_RETCODE\_TIMEOUT if the quorum is not reached within the configured max\_blocking\_time. + +The default quorum value is set to 1. + +The default value is: ``1`` + + .. _`//CycloneDDS/Domain/General`: //CycloneDDS/Domain/General @@ -2643,9 +2669,9 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: ``none`` .. - generated from ddsi_config.h[570f67bd3080674a4bad53d9580a8bb7ad1e6e4d] + generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] - generated from ddsi__cfgelems.h[de6d6357eef2d532b2450cec9732702107d2a03c] + generated from ddsi__cfgelems.h[0fe5caa90873f3af7436f0f201edeccaea9fedd4] generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] diff --git a/docs/manual/options.md b/docs/manual/options.md index b0fc932d1b..7b6de3a232 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -6,7 +6,7 @@ CycloneDDS configuration ## //CycloneDDS/Domain Attributes: [Id](#cycloneddsdomainid) -Children: [Compatibility](#cycloneddsdomaincompatibility), [Discovery](#cycloneddsdomaindiscovery), [General](#cycloneddsdomaingeneral), [Internal](#cycloneddsdomaininternal), [Partitioning](#cycloneddsdomainpartitioning), [SSL](#cycloneddsdomainssl), [Security](#cycloneddsdomainsecurity), [SharedMemory](#cycloneddsdomainsharedmemory), [Sizing](#cycloneddsdomainsizing), [TCP](#cycloneddsdomaintcp), [Threads](#cycloneddsdomainthreads), [Tracing](#cycloneddsdomaintracing) +Children: [Compatibility](#cycloneddsdomaincompatibility), [Discovery](#cycloneddsdomaindiscovery), [Durability](#cycloneddsdomaindurability), [General](#cycloneddsdomaingeneral), [Internal](#cycloneddsdomaininternal), [Partitioning](#cycloneddsdomainpartitioning), [SSL](#cycloneddsdomainssl), [Security](#cycloneddsdomainsecurity), [SharedMemory](#cycloneddsdomainsharedmemory), [Sizing](#cycloneddsdomainsizing), [TCP](#cycloneddsdomaintcp), [Threads](#cycloneddsdomainthreads), [Tracing](#cycloneddsdomaintracing) The General element specifying Domain related settings. @@ -244,6 +244,24 @@ String extension for domain id that remote participants must match to be discove The default value is: `` +### //CycloneDDS/Domain/Durability +Children: [Quorum](#cycloneddsdomaindurabilityquorum) + +This element specifies settings related to durable data. + + +#### //CycloneDDS/Domain/Durability/Quorum +Integer + +This element specifies the minimum number of durable services that must be available before a durable writer can successfully publish durable data. The value must be equal or higher to 1 to ensure that there is at least one durable service present in the network that can receive the durable data and make it available to late joiners. By specifying a number higher than 1, additional fault tolerance can be achieved. + +As long as the number of available durable services drops below the specified quorum, durable writers will not be able to publish durable data. Any attempt to do so by calling dds\_write() (or one of its variants) will return DDS\_RETCODE\_TIMEOUT if the quorum is not reached within the configured max\_blocking\_time. + +The default quorum value is set to 1. + +The default value is: `1` + + ### //CycloneDDS/Domain/General Children: [AllowMulticast](#cycloneddsdomaingeneralallowmulticast), [DontRoute](#cycloneddsdomaingeneraldontroute), [EnableMulticastLoopback](#cycloneddsdomaingeneralenablemulticastloopback), [EntityAutoNaming](#cycloneddsdomaingeneralentityautonaming), [ExternalNetworkAddress](#cycloneddsdomaingeneralexternalnetworkaddress), [ExternalNetworkMask](#cycloneddsdomaingeneralexternalnetworkmask), [FragmentSize](#cycloneddsdomaingeneralfragmentsize), [Interfaces](#cycloneddsdomaingeneralinterfaces), [MaxMessageSize](#cycloneddsdomaingeneralmaxmessagesize), [MaxRexmitMessageSize](#cycloneddsdomaingeneralmaxrexmitmessagesize), [MulticastRecvNetworkInterfaceAddresses](#cycloneddsdomaingeneralmulticastrecvnetworkinterfaceaddresses), [MulticastTimeToLive](#cycloneddsdomaingeneralmulticasttimetolive), [RedundantNetworking](#cycloneddsdomaingeneralredundantnetworking), [Transport](#cycloneddsdomaingeneraltransport), [UseIPv6](#cycloneddsdomaingeneraluseipv) @@ -1847,9 +1865,9 @@ While none prevents any message from being written to a DDSI2 log file. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest. The default value is: `none` - + - + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index aa08354fe2..dc2faeea56 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -178,6 +178,16 @@ CycloneDDS configuration""" ] ] }? }? & [ a:documentation [ xml:lang="en" """ +

    This element specifies settings related to durable data.

    """ ] ] + element Durability { + [ a:documentation [ xml:lang="en" """ +

    This element specifies the minimum number of durable services that must be available before a durable writer can successfully publish durable data. The value must be equal or higher to 1 to ensure that there is at least one durable service present in the network that can receive the durable data and make it available to late joiners. By specifying a number higher than 1, additional fault tolerance can be achieved.

    As long as the number of available durable services drops below the specified quorum, durable writers will not be able to publish durable data. Any attempt to do so by calling dds_write() (or one of its variants) will return DDS_RETCODE_TIMEOUT if the quorum is not reached within the configured max_blocking_time.

    The default quorum value is set to 1.

    +

    The default value is: 1

    """ ] ] + element Quorum { + xsd:integer + }? + }? + & [ a:documentation [ xml:lang="en" """

    The General element specifies overall Cyclone DDS service settings.

    """ ] ] element General { [ a:documentation [ xml:lang="en" """ @@ -1283,9 +1293,9 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
    duration_inf = xsd:token { pattern = "inf|0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)" } memsize = xsd:token { pattern = "0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B" } } -# generated from ddsi_config.h[570f67bd3080674a4bad53d9580a8bb7ad1e6e4d] +# generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] # generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] -# generated from ddsi__cfgelems.h[de6d6357eef2d532b2450cec9732702107d2a03c] +# generated from ddsi__cfgelems.h[0fe5caa90873f3af7436f0f201edeccaea9fedd4] # generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] # generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] # generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index f99660f865..a6ee743f36 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -20,6 +20,7 @@ CycloneDDS configuration + @@ -293,6 +294,24 @@ CycloneDDS configuration <p>The default value is: <code>&lt;empty&gt;</code></p> + + + +<p>This element specifies settings related to durable data.</p> + + + + + + + + + + +<p>This element specifies the minimum number of durable services that must be available before a durable writer can successfully publish durable data. The value must be equal or higher to 1 to ensure that there is at least one durable service present in the network that can receive the durable data and make it available to late joiners. By specifying a number higher than 1, additional fault tolerance can be achieved.</p> <p>As long as the number of available durable services drops below the specified quorum, durable writers will not be able to publish durable data. Any attempt to do so by calling dds_write() (or one of its variants) will return DDS_RETCODE_TIMEOUT if the quorum is not reached within the configured max_blocking_time.</p><p>The default quorum value is set to 1.</p> +<p>The default value is: <code>1</code></p> + + @@ -1939,9 +1958,9 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - + - + diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index b8e93bb381..3f49794bb1 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -21,6 +21,9 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->fragment_size = UINT16_C (1344); #ifdef DDS_HAS_SECURITY #endif /* DDS_HAS_SECURITY */ +#ifdef DDS_HAS_DURABILITY + cfg->quorum = UINT32_C (1); +#endif /* DDS_HAS_DURABILITY */ #ifdef DDS_HAS_NETWORK_PARTITIONS #endif /* DDS_HAS_NETWORK_PARTITIONS */ cfg->rbuf_size = UINT32_C (1048576); @@ -99,9 +102,9 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->ssl_min_version.minor = 3; #endif /* DDS_HAS_SSL */ } -/* generated from ddsi_config.h[570f67bd3080674a4bad53d9580a8bb7ad1e6e4d] */ +/* generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] */ /* generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] */ -/* generated from ddsi__cfgelems.h[de6d6357eef2d532b2450cec9732702107d2a03c] */ +/* generated from ddsi__cfgelems.h[0fe5caa90873f3af7436f0f201edeccaea9fedd4] */ /* generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] */ /* generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] */ /* generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] */ diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_config.h b/src/core/ddsi/include/dds/ddsi/ddsi_config.h index f3be421a94..bdd6319def 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_config.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_config.h @@ -422,6 +422,10 @@ struct ddsi_config struct ddsi_config_omg_security_listelem *omg_security_configuration; #endif +#ifdef DDS_HAS_DURABILITY + uint32_t quorum; /* quorum threshold for durable publishers */ +#endif + /* deprecated shm options */ int enable_shm; char *shm_locator; diff --git a/src/core/ddsi/src/ddsi__cfgelems.h b/src/core/ddsi/src/ddsi__cfgelems.h index 5f757799b9..14ece7cf3b 100644 --- a/src/core/ddsi/src/ddsi__cfgelems.h +++ b/src/core/ddsi/src/ddsi__cfgelems.h @@ -2035,6 +2035,32 @@ static struct cfgelem tracing_cfgelems[] = { END_MARKER }; +#ifdef DDS_HAS_DURABILITY + +static struct cfgelem durability_cfgelems[] = { + INT("Quorum", NULL, 1, "1", + MEMBER(quorum), + FUNCTIONS(0, uf_pos_uint, 0, pf_uint), + DESCRIPTION( + "

    This element specifies the minimum number of durable services " + "that must be available before a durable writer can successfully " + "publish durable data. The value must be equal or higher to 1 to ensure " + "that there is at least one durable service present in the network that " + "can receive the durable data and make it available to late joiners. " + "By specifying a number higher than 1, additional fault tolerance can be " + "achieved.

    " + "

    As long as the number of available durable services drops below the specified " + "quorum, durable writers will not be able to publish durable data. Any " + "attempt to do so by calling dds_write() (or one of its variants) " + "will return DDS_RETCODE_TIMEOUT if the quorum is not reached within the " + "configured max_blocking_time.

    " + "

    The default quorum value is set to 1.

    " + )), + END_MARKER +}; + +#endif + /* Multiplicity = 0 is a special for Domain/[@Id] as it has some special processing to only process relevant configuration sections. */ static struct cfgelem domain_cfgattrs[] = { @@ -2068,6 +2094,16 @@ static struct cfgelem domain_cfgelems[] = { MAXIMUM(1)), /* Security must occur at most once, but INT_MAX is required because of the way its processed (for now) */ #endif +#ifdef DDS_HAS_DURABILITY + GROUP("Durability", durability_cfgelems, NULL, 1, + NOMEMBER, + NOFUNCTIONS, + DESCRIPTION( + "

    This element specifies settings related to durable data.

    " + ), + BEHIND_FLAG("DDS_HAS_DURABILITY") + ), +#endif #ifdef DDS_HAS_NETWORK_PARTITIONS GROUP("Partitioning", partitioning_cfgelems, NULL, 1, NOMEMBER, @@ -2175,6 +2211,9 @@ static struct cfgelem root_cfgelems[] = { MOVED("TCP", "CycloneDDS/Domain/TCP"), #if DDS_HAS_SECURITY MOVED("DDSSecurity", "CycloneDDS/Domain/Security"), +#endif +#if DDS_HAS_DURABILITY + MOVED("Durability", "CycloneDDS/Domain/Durability"), #endif MOVED("SharedMemory", "CycloneDDS/Domain/SharedMemory"), #if DDS_HAS_SSL From 6fc6bc40c491922fd22b6bc10e643dcc59189b63 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Mon, 18 Mar 2024 09:10:15 +0100 Subject: [PATCH 032/207] Add type_id to dc_request and dc_response Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 4 + src/durability/src/dds_durability.c | 73 ++- src/durability/src/durablesupport.c | 589 +++++++++--------- 3 files changed, 356 insertions(+), 310 deletions(-) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index 837ca56dfc..2f8adc59b7 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -103,6 +103,7 @@ typedef struct DurableSupport_set { char * partition; char * tpname; + char * type_id; uint32_t flags; dds_sequence_DurableSupport_writer writers; } DurableSupport_set; @@ -173,6 +174,7 @@ typedef struct DurableSupport_set_t { char * partition; char * tpname; + char * type_id; uint32_t flags; dds_sequence_DurableSupport_id_t addressees; } DurableSupport_set_t; @@ -275,6 +277,7 @@ typedef struct DurableSupport_request DurableSupport_id_t client; char * partition; char * tpname; + char * type_id; DurableSupport_duration_t timeout; } DurableSupport_request; @@ -293,6 +296,7 @@ typedef struct DurableSupport_response_set_t DurableSupport_delivery_id_t delivery_id; char * partition; char * tpname; + char * type_id; uint32_t flags; } DurableSupport_response_set_t; diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index aa48020a43..0345f60dab 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -23,6 +23,7 @@ #include "dds/ddsi/ddsi_endpoint.h" #include "dds/ddsrt/avl.h" #include "dds/ddsi/ddsi_serdata.h" +#include "dds/ddsi/ddsi_typelib.h" #define DEFAULT_QOURUM 1 #define DEFAULT_IDENT "durable_support" @@ -33,9 +34,9 @@ #define DC_UNUSED_ARG(x) ((void)x) -#define DC_FLAG_SET_NOT_FOUND (((uint32_t)0x01) << 10) -#define DC_FLAG_SET_BEGIN (((uint32_t)0x01) << 11) -#define DC_FLAG_SET_END (((uint32_t)0x01) << 12) +#define DC_FLAG_SET_NOT_FOUND (((uint32_t)0x01) << 16) +#define DC_FLAG_SET_BEGIN (((uint32_t)0x01) << 17) +#define DC_FLAG_SET_END (((uint32_t)0x01) << 18) #define TRACE(...) DDS_CLOG (DDS_LC_DUR, &domaingv->logconfig, __VA_ARGS__) @@ -158,19 +159,19 @@ static int dc_stringify_request (char *buf, size_t n, const DurableSupport_reque if (valid_data) { /* also print non-key fields */ if (request->timeout == DDS_INFINITY) { - if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"timeout\":\"never\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname)) < 0) { + if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"timeout\":\"never\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, request->type_id)) < 0) { goto err; } } else { sec = (int64_t)(request->timeout / DDS_NSECS_IN_SEC); msec = (uint32_t)((request->timeout % DDS_NSECS_IN_SEC) / DDS_NSECS_IN_MSEC); - if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"timeout\":%" PRId64 ".%03" PRIu32 "}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, sec, msec)) < 0) { + if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"timeout\":%" PRId64 ".%03" PRIu32 "}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, request->type_id, sec, msec)) < 0) { goto err; } } } else { /* only print key fields */ - if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname)) < 0) { + if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, request->type_id)) < 0) { goto err; } } @@ -208,7 +209,7 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp } switch (response->body._d) { case DurableSupport_RESPONSETYPE_SET : - if ((l = snprintf(buf+i, n-i, "\"delivery_id\":%" PRIu64 ",\"partition\":\"%s\", \"tpname\":\"%s\", \"flags\":\"0x%04" PRIx32 "\"", response->body._u.set.delivery_id, response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.flags)) < 0) { + if ((l = snprintf(buf+i, n-i, "\"delivery_id\":%" PRIu64 ",\"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"flags\":\"0x%04" PRIx32 "\"", response->body._u.set.delivery_id, response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.type_id, response->body._u.set.flags)) < 0) { goto err; } i += (size_t)l; @@ -298,7 +299,7 @@ static const ddsrt_avl_ctreedef_t proxy_set_reader_td = DDSRT_AVL_CTREEDEF_INITI struct proxy_set_key_t { char *partition; /* partition name */ char *tpname; /* topic name */ - /* todo: typeid */ + char *type_id; /* type id */ }; struct proxy_set_t { @@ -326,6 +327,12 @@ static int cmp_proxy_set (const void *a, const void *b) } else if (cmp > 0) { return 1; } + /* compare type id */ + if ((cmp = strcmp(k1->type_id, k2->type_id)) < 0) { + return -1; + } else if (cmp > 0) { + return 1; + } return 0; } @@ -336,6 +343,7 @@ static void cleanup_proxy_set (void *n) ddsrt_avl_cfree(&proxy_set_reader_td, &proxy_set->readers, cleanup_proxy_set_reader); ddsrt_free(proxy_set->key.partition); ddsrt_free(proxy_set->key.tpname); + ddsrt_free(proxy_set->key.type_id); ddsrt_free(proxy_set); } @@ -1191,7 +1199,7 @@ static void dc_com_free (struct com_t *com) #define MAX_TOPIC_NAME_SIZE 255 -static dds_return_t dc_com_request_write (struct com_t *com, const char *partition, const char *tpname) +static dds_return_t dc_com_request_write (struct com_t *com, const char *partition, const char *tpname, const char *type_id) { /* note: we allow doing a request for volatile readers */ DurableSupport_request *request; @@ -1204,6 +1212,7 @@ static dds_return_t dc_com_request_write (struct com_t *com, const char *partiti memcpy(request->client, dc.cfg.id, 16); request->partition = ddsrt_strdup(partition); request->tpname = ddsrt_strdup(tpname); + request->type_id = ddsrt_strdup(type_id); request->timeout = DDS_INFINITY; l = dc_stringify_request(str, sizeof(str), request, true); assert(l > 0); @@ -1292,7 +1301,7 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } -static struct proxy_set_t *dc_create_proxy_set (struct dc_t *dc, const char *partition, const char *tpname) +static struct proxy_set_t *dc_create_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, const char *type_id) { struct proxy_set_t *proxy_set = NULL; @@ -1301,14 +1310,15 @@ static struct proxy_set_t *dc_create_proxy_set (struct dc_t *dc, const char *par proxy_set = (struct proxy_set_t *)ddsrt_malloc(sizeof(struct proxy_set_t)); proxy_set->key.partition = ddsrt_strdup(partition); proxy_set->key.tpname = ddsrt_strdup(tpname); + proxy_set->key.type_id = ddsrt_strdup(type_id); proxy_set->seq = 0; /* no pending request yet */ ddsrt_avl_cinit(&proxy_set_reader_td, &proxy_set->readers); ddsrt_avl_cinsert(&proxy_set_td, &dc->proxy_sets, proxy_set); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "proxy set '%s.%s' created\n", proxy_set->key.partition, proxy_set->key.tpname); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "proxy set '%s.%s<%s>' created\n", proxy_set->key.partition, proxy_set->key.tpname, proxy_set->key.type_id); return proxy_set; } -static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, bool autocreate) +static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, const char *type_id, bool autocreate) { struct proxy_set_key_t key; struct proxy_set_t *proxy_set; @@ -1317,11 +1327,13 @@ static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partit assert(tpname); key.partition = ddsrt_strdup(partition); key.tpname = ddsrt_strdup(tpname); + key.type_id = ddsrt_strdup(type_id); if (((proxy_set = ddsrt_avl_clookup (&proxy_set_td, &dc->proxy_sets, &key)) == NULL) && autocreate) { - proxy_set = dc_create_proxy_set(dc, partition, tpname); + proxy_set = dc_create_proxy_set(dc, partition, tpname, type_id); } ddsrt_free(key.partition); ddsrt_free(key.tpname); + ddsrt_free(key.type_id); return proxy_set; } @@ -1392,14 +1404,14 @@ static void dc_open_delivery (struct dc_t *dc, DurableSupport_response *respons } /* set the delivery_id and proxy set for this delivery context */ dc->delivery_ctx->delivery_id = delivery_id; - if ((dc->delivery_ctx->proxy_set = dc_get_proxy_set(dc, response->body._u.set.partition, response->body._u.set.tpname, false)) == NULL) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "no proxy set for \"%s.%s\" found, ignore delivery\n", response->body._u.set.partition, response->body._u.set.tpname); + if ((dc->delivery_ctx->proxy_set = dc_get_proxy_set(dc, response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.type_id, false)) == NULL) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "no proxy set for \"%s.%s<%s>\" found, ignore delivery\n", response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.type_id); /* abort this delivery context */ dc_abort_current_delivery(dc); return; } - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s\" opened\n", - delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str), dc->delivery_ctx->proxy_set->key.partition, dc->delivery_ctx->proxy_set->key.tpname); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s<%s>\" opened\n", + delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str), dc->delivery_ctx->proxy_set->key.partition, dc->delivery_ctx->proxy_set->key.tpname, dc->delivery_ctx->proxy_set->key.type_id); } /* close the current delivery context for the ds identified by id */ @@ -1693,16 +1705,21 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade uint32_t plen, i; char **partitions; struct proxy_set_t *proxy_set = NULL; - dds_instance_handle_t ih; dds_guid_t guid; char id_str[37]; + dds_typeinfo_t *typeinfo; + ddsi_typeid_t *tid = NULL; + struct ddsi_typeid_str tidstr = { 0 }; - /* LH: perhaps the qos should be added as parameter, since the caller already has the qos */ - /* verify if the reader still exists; if not, delete the request */ - if ((rc = dds_get_instance_handle(reader, &ih)) != DDS_RETCODE_OK) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "No need to create a proxy set, reader is not available [%s]\n", dds_strretcode(-rc)); - return; + if ((rc = dds_get_typeinfo(reader, &typeinfo)) != DDS_RETCODE_OK) { + DDS_ERROR("Unable to retrieve typeinfo [%s]\n", dds_strretcode(-rc)); + goto err_get_typeinfo; + } + if ((tid = ddsi_typeinfo_typeid(typeinfo, DDSI_TYPEID_KIND_COMPLETE)) == NULL) { + DDS_ERROR("Unable to retrieve typeid [%s]\n", dds_strretcode(-rc)); + goto err_typeid; } + (void)ddsi_make_typeid_str(&tidstr, tid); /* get reader guid */ if ((rc = dds_get_guid(reader, &guid)) < DDS_RETCODE_OK) { DDS_ERROR("Unable to retrieve the guid of the reader [%s]\n", dds_strretcode(-rc)); @@ -1738,7 +1755,7 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade /* for each partition create a proxy set if it does not exist yet * and request data for the proxy set (if not done so already) */ for (i=0; i < plen; i++) { - proxy_set = dc_get_proxy_set(dc, partitions[i], tpname, true); + proxy_set = dc_get_proxy_set(dc, partitions[i], tpname, tidstr.str, true); assert(proxy_set); /* Add the reader and rhc to this proxy set. * We do this BEFORE we send the request, so that we are sure @@ -1746,7 +1763,7 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade * sending the request) the reader and rhc are present */ dc_register_reader_to_proxy_set(dc, proxy_set, guid, reader, rhc); /* send a request for this proxy set */ - if ((rc = dc_com_request_write(dc->com, proxy_set->key.partition, proxy_set->key.tpname)) != DDS_RETCODE_OK) { + if ((rc = dc_com_request_write(dc->com, proxy_set->key.partition, proxy_set->key.tpname, proxy_set->key.type_id)) != DDS_RETCODE_OK) { DDS_ERROR("Failed to publish dc_request for proxy set %s.%s\n", proxy_set->key.partition, proxy_set->key.tpname); /* We failed to request data for this proxy set. * We could do several things now, e.g., 1) try again until we succeed, @@ -1759,6 +1776,8 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade } dc_free_partitions(plen, partitions); dds_delete_qos(rqos); + dds_free_typeinfo(typeinfo); + ddsrt_free(tid); return; err_qget_partition: @@ -1769,6 +1788,10 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade err_get_name: err_get_topic: err_get_guid: + ddsrt_free(tid); +err_typeid: + dds_free_typeinfo(typeinfo); +err_get_typeinfo: return; } diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index 4b91e5a5cc..2395d59455 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -106,6 +106,7 @@ static const uint32_t DurableSupport_state_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, partition), DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, tpname), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, type_id), DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_set, flags), DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_set, writers), sizeof (DurableSupport_writer), (4u << 16u) + 5u /* writer */, DDS_OP_RTS, @@ -129,62 +130,63 @@ static const uint32_t DurableSupport_state_ops [] = static const dds_key_descriptor_t DurableSupport_state_keys[1] = { - { "id", 40, 0 } + { "id", 42, 0 } }; /* Type Information: - [MINIMAL 29c25c35d5510f091b9d2951e87d] (#deps: 4) + [MINIMAL 9546da84e880713f59c93561b8d8] (#deps: 4) - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 4c34d21c8ec2020e687b75390553] + - [MINIMAL 0edda7680861b44f54f71e189994] - [MINIMAL 7b73d4df4f265b2da8c52f3c3a8e] - [MINIMAL ef038b7b19448c9ce27fa1c268cd] - [COMPLETE a4dc41b7052cef5bfdb62c313d77] (#deps: 4) + [COMPLETE 174aa20548235aee4aff5111d8a2] (#deps: 4) - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE ec0a17f45bf4c4917bb5db3c5b18] + - [COMPLETE 0b9ecead7e5e9db531d5a4ef26b1] - [COMPLETE 3be64a4fbc92a7b2f612cbd52a3a] - [COMPLETE d8d43c2295c185a21b9591a7126c] */ #define TYPE_INFO_CDR_DurableSupport_state (const unsigned char []){ \ 0x20, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x29, 0xc2, 0x5c, 0x35, 0xd5, 0x51, 0x0f, 0x09, 0x1b, 0x9d, 0x29, \ - 0x51, 0xe8, 0x7d, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x95, 0x46, 0xda, 0x84, 0xe8, 0x80, 0x71, 0x3f, 0x59, 0xc9, 0x35, \ + 0x61, 0xb8, 0xd8, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, 0x05, 0x53, 0x00, \ - 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, \ + 0xf1, 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, 0x94, 0x00, \ + 0x7a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, \ 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, \ 0x37, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa4, 0xdc, 0x41, 0xb7, 0x05, 0x2c, 0xef, 0x5b, 0xfd, 0xb6, 0x2c, \ - 0x31, 0x3d, 0x77, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x4a, 0xa2, 0x05, 0x48, 0x23, 0x5a, 0xee, 0x4a, 0xff, 0x51, \ + 0x11, 0xd8, 0xa2, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xec, 0x0a, 0x17, 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, 0x3c, 0x5b, 0x18, 0x00, \ - 0xae, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, \ + 0xf2, 0x0b, 0x9e, 0xce, 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0x00, \ + 0xca, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, \ 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, \ 0x61, 0x00, 0x00, 0x00\ } #define TYPE_INFO_CDR_SZ_DurableSupport_state 292u #define TYPE_MAP_CDR_DurableSupport_state (const unsigned char []){ \ - 0xef, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf1, 0x29, 0xc2, 0x5c, 0x35, 0xd5, 0x51, 0x0f, \ - 0x09, 0x1b, 0x9d, 0x29, 0x51, 0xe8, 0x7d, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0xff, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf1, 0x95, 0x46, 0xda, 0x84, 0xe8, 0x80, 0x71, \ + 0x3f, 0x59, 0xc9, 0x35, 0x61, 0xb8, 0xd8, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0xb0, 0x68, 0x93, 0x1c, \ 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ - 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, 0x05, 0x53, 0x17, 0x8d, \ + 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, 0x94, 0x17, 0x8d, \ 0x51, 0x02, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, \ 0x89, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x10, 0x02, 0xf1, 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, 0x05, \ - 0x53, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, \ + 0x10, 0x02, 0xf1, 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, \ + 0x94, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x0b, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, \ + 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x0c, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, 0x0b, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, \ 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0xbf, 0x63, 0x9b, 0x5f, 0xf1, 0x7b, \ 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0x00, 0x00, 0x00, \ 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -198,8 +200,8 @@ static const dds_key_descriptor_t DurableSupport_state_keys[1] = 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x26, \ 0x40, 0x3e, 0xc6, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x1c, \ - 0x78, 0xb4, 0x86, 0x00, 0xe5, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf2, 0xa4, 0xdc, 0x41, \ - 0xb7, 0x05, 0x2c, 0xef, 0x5b, 0xfd, 0xb6, 0x2c, 0x31, 0x3d, 0x77, 0x00, 0x9b, 0x00, 0x00, 0x00, \ + 0x78, 0xb4, 0x86, 0x00, 0x01, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x4a, 0xa2, \ + 0x05, 0x48, 0x23, 0x5a, 0xee, 0x4a, 0xff, 0x51, 0x11, 0xd8, 0xa2, 0x00, 0x9b, 0x00, 0x00, 0x00, \ 0xf2, 0x51, 0x02, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ 0x73, 0x74, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ @@ -208,55 +210,57 @@ static const dds_key_descriptor_t DurableSupport_state_keys[1] = 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0x70, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, \ 0x27, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, \ - 0xec, 0x0a, 0x17, 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, 0x3c, 0x5b, 0x18, 0x00, 0x00, \ + 0x0b, 0x9e, 0xce, 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0x00, 0x00, \ 0x05, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, \ 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0xec, 0x0a, 0x17, \ - 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, 0x3c, 0x5b, 0x18, 0x00, 0xaa, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x0b, 0x9e, 0xce, \ + 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0x00, 0xc6, 0x00, 0x00, 0x00, \ 0xf2, 0x51, 0x0a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x73, 0x65, 0x74, 0x00, 0x82, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ + 0x73, 0x65, 0x74, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x31, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, \ - 0xbc, 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, \ - 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, \ - 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ - 0x29, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, \ - 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, \ - 0x07, 0x00, 0x00, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, \ - 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x5d, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x6c, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x9a, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf2, 0xa4, 0xdc, 0x41, 0xb7, 0x05, 0x2c, 0xef, \ - 0x5b, 0xfd, 0xb6, 0x2c, 0x31, 0x3d, 0x77, 0xf1, 0x29, 0xc2, 0x5c, 0x35, 0xd5, 0x51, 0x0f, 0x09, \ - 0x1b, 0x9d, 0x29, 0x51, 0xe8, 0x7d, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, \ - 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0xec, 0x0a, 0x17, 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, \ - 0x3c, 0x5b, 0x18, 0xf1, 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, \ - 0x05, 0x53, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, \ - 0x3a, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, \ - 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, \ - 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd\ + 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, \ + 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, \ + 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, \ + 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x77, 0x72, 0x69, 0x74, \ + 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, 0xf6, \ + 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, \ + 0x65, 0x72, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, \ + 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, \ + 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x5d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x61, 0x6e, 0x67, \ + 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6c, 0x62, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x4a, 0xa2, 0x05, 0x48, 0x23, 0x5a, 0xee, 0x4a, 0xff, 0x51, \ + 0x11, 0xd8, 0xa2, 0xf1, 0x95, 0x46, 0xda, 0x84, 0xe8, 0x80, 0x71, 0x3f, 0x59, 0xc9, 0x35, 0x61, \ + 0xb8, 0xd8, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ + 0xf2, 0x0b, 0x9e, 0xce, 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0xf1, \ + 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, 0x94, 0xf2, 0x3b, \ + 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0xf1, 0x7b, 0x73, \ + 0xd4, 0xdf, 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0xf2, 0xd8, 0xd4, 0x3c, \ + 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, 0xef, 0x03, 0x8b, 0x7b, \ + 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_state 1406u +#define TYPE_MAP_CDR_SZ_DurableSupport_state 1450u const dds_topic_descriptor_t DurableSupport_state_desc = { .m_size = sizeof (DurableSupport_state), @@ -265,7 +269,7 @@ const dds_topic_descriptor_t DurableSupport_state_desc = .m_nkeys = 1u, .m_typename = "DurableSupport::state", .m_keys = DurableSupport_state_keys, - .m_nops = 20, + .m_nops = 21, .m_ops = DurableSupport_state_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_state, .sz = TYPE_INFO_CDR_SZ_DurableSupport_state }, @@ -285,8 +289,8 @@ static const uint32_t DurableSupport_bead_ops [] = DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_content, _d), 4u, (20u << 16u) + 4u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 17 /* session_t */, 1, offsetof (DurableSupport_content, _u.session), 0u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 19 /* set_t */, 2, offsetof (DurableSupport_content, _u.set), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 31 /* writer_t */, 3, offsetof (DurableSupport_content, _u.writer), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 51 /* data_t */, 4, offsetof (DurableSupport_content, _u.data), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 33 /* writer_t */, 3, offsetof (DurableSupport_content, _u.writer), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 53 /* data_t */, 4, offsetof (DurableSupport_content, _u.data), 0u, DDS_OP_RTS, /* session_t */ @@ -299,6 +303,7 @@ static const uint32_t DurableSupport_bead_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, partition), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, tpname), + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, type_id), DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_set_t, flags), DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_ARR, offsetof (DurableSupport_set_t, addressees), sizeof (DurableSupport_id_t), (8u << 16u) + 4u, DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, 0u, 16u, @@ -335,29 +340,29 @@ static const uint32_t DurableSupport_bead_ops [] = static const dds_key_descriptor_t DurableSupport_bead_keys[1] = { - { "id", 80, 0 } + { "id", 82, 0 } }; /* Type Information: - [MINIMAL ec4a62f36aef58a53c25ca352c96] (#deps: 10) + [MINIMAL 333a527587be11928ad9cbfa1803] (#deps: 10) - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 8081d593c0e4df1bcd51ee4ff1ef] + - [MINIMAL e4bc4a05081322db5581a91d817f] - [MINIMAL 80455e796dd3437163cb532089da] - [MINIMAL 7fe2256248fb0dc7c6a9b6c616fb] - [MINIMAL d8398b259af5a04792e296996c27] - - [MINIMAL 0d686e35dcd446cd843b793a485c] + - [MINIMAL 5068289639b114fecda3f2c2ebd6] - [MINIMAL 889fb89d6714387ca74c9aa42719] - [MINIMAL 7d1dfbcf78261b30f20d1dadb067] - [MINIMAL ef038b7b19448c9ce27fa1c268cd] - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE 17238b8e235b286c8fdcbeb41197] (#deps: 11) + [COMPLETE a10b59cc2ac5234a0ab0c89deed6] (#deps: 11) - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE 1b1b74c5e6971d9d84029a5e04d3] + - [COMPLETE ad3badfa4313f0bde4a077931856] - [COMPLETE 105e7fa73d9700c1960716873c88] - [COMPLETE 5de973c540260a829429a905efcd] - [COMPLETE 838f13c80cfd7a0061fb91f88e49] - [COMPLETE 9c5d42ec81585355d169823828eb] - - [COMPLETE dd9a1bfb3c68ff5066e4b763a939] + - [COMPLETE e2beee99b860e5aa4c372c3b5655] - [COMPLETE e6c4e5bb805c08c1d9e923e071ea] - [COMPLETE 7a239210b1658deca81e1474b300] - [COMPLETE d8d43c2295c185a21b9591a7126c] @@ -365,37 +370,37 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = */ #define TYPE_INFO_CDR_DurableSupport_bead (const unsigned char []){ \ 0x58, 0x02, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x18, 0x01, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0xec, 0x4a, 0x62, 0xf3, 0x6a, 0xef, 0x58, 0xa5, 0x3c, 0x25, 0xca, \ - 0x35, 0x2c, 0x96, 0x00, 0x55, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x33, 0x3a, 0x52, 0x75, 0x87, 0xbe, 0x11, 0x92, 0x8a, 0xd9, 0xcb, \ + 0xfa, 0x18, 0x03, 0x00, 0x55, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, \ 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, 0xf1, 0xef, 0x00, \ + 0xf1, 0xe4, 0xbc, 0x4a, 0x05, 0x08, 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0x00, \ 0xcc, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0x00, \ 0x55, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, \ - 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, \ + 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, 0xb1, 0x14, 0xfe, 0xcd, 0xa3, 0xf2, 0xc2, 0xeb, 0xd6, 0x00, \ + 0x7a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, \ 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, 0x19, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, 0x1d, 0xad, 0xb0, 0x67, 0x00, \ 0x27, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, \ 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x37, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x30, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x23, 0x8b, 0x8e, 0x23, 0x5b, 0x28, 0x6c, 0x8f, 0xdc, 0xbe, \ - 0xb4, 0x11, 0x97, 0x00, 0x83, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa1, 0x0b, 0x59, 0xcc, 0x2a, 0xc5, 0x23, 0x4a, 0x0a, 0xb0, 0xc8, \ + 0x9d, 0xee, 0xd6, 0x00, 0x83, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, \ 0x0b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, 0x97, 0x1d, 0x9d, 0x84, 0x02, 0x9a, 0x5e, 0x04, 0xd3, 0x00, \ + 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, 0x13, 0xf0, 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0x00, \ 0x13, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, \ 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, 0x39, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, \ 0x8d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, \ 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, \ - 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, \ - 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0x00, 0xb5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, 0xe5, \ + 0xaa, 0x4c, 0x37, 0x2c, 0x3b, 0x56, 0x55, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0x00, \ 0xd5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, \ 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ @@ -405,24 +410,24 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = } #define TYPE_INFO_CDR_SZ_DurableSupport_bead 604u #define TYPE_MAP_CDR_DurableSupport_bead (const unsigned char []){ \ - 0x18, 0x04, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xf1, 0xec, 0x4a, 0x62, 0xf3, 0x6a, 0xef, 0x58, \ - 0xa5, 0x3c, 0x25, 0xca, 0x35, 0x2c, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x28, 0x04, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xf1, 0x33, 0x3a, 0x52, 0x75, 0x87, 0xbe, 0x11, \ + 0x92, 0x8a, 0xd9, 0xcb, 0xfa, 0x18, 0x03, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, \ - 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, 0xf1, 0xef, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xe4, 0xbc, 0x4a, 0x05, 0x08, \ + 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, \ - 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, 0xf1, 0xef, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0xe4, 0xbc, 0x4a, 0x05, 0x08, \ + 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, \ 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ 0xa4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, \ 0xfb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0xd6, 0xf4, 0x0c, \ - 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, \ - 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, \ + 0xb1, 0x14, 0xfe, 0xcd, 0xa3, 0xf2, 0xc2, 0xeb, 0xd6, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, \ 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xa8, 0x2f, 0xee, 0xe3, \ @@ -441,13 +446,14 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x06, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, 0x46, 0xcd, \ - 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, 0xb1, 0x14, 0xfe, \ + 0xcd, 0xa3, 0xf2, 0xc2, 0xeb, 0xd6, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ - 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, \ + 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x73, 0xed, \ 0xc9, 0x6c, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, \ 0x19, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ @@ -470,23 +476,23 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, \ 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0x6f, 0x06, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x23, 0x8b, 0x8e, 0x23, 0x5b, 0x28, 0x6c, 0x8f, 0xdc, 0xbe, \ - 0xb4, 0x11, 0x97, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0x8b, 0x06, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0xf2, 0xa1, 0x0b, 0x59, 0xcc, 0x2a, 0xc5, 0x23, 0x4a, 0x0a, 0xb0, 0xc8, \ + 0x9d, 0xee, 0xd6, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x62, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, \ 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, \ - 0x97, 0x1d, 0x9d, 0x84, 0x02, 0x9a, 0x5e, 0x04, 0xd3, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, \ + 0x13, 0xf0, 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, 0x97, 0x1d, \ - 0x9d, 0x84, 0x02, 0x9a, 0x5e, 0x04, 0xd3, 0x00, 0x0f, 0x01, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, 0x13, 0xf0, \ + 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0x00, 0x0f, 0x01, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, \ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x63, 0x6f, 0x6e, 0x74, \ 0x65, 0x6e, 0x74, 0x00, 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, \ @@ -495,8 +501,8 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, \ 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, \ - 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, 0xe5, 0xaa, 0x4c, 0x37, 0x2c, 0x3b, 0x56, \ + 0x55, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, \ 0xea, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ @@ -527,78 +533,80 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = 0xf2, 0x30, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, \ - 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0xb1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, \ + 0xe5, 0xaa, 0x4c, 0x37, 0x2c, 0x3b, 0x56, 0x55, 0xcd, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x74, 0x5f, \ - 0x74, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ + 0x74, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, \ - 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xe6, 0xc4, \ - 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0xd1, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, \ + 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ + 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x72, \ + 0x65, 0x73, 0x73, 0x65, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, \ + 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0xd1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, \ + 0x65, 0x72, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, \ + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, \ + 0x65, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ + 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, \ + 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, \ + 0x07, 0x00, 0x00, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x7a, 0x23, \ + 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, 0x00, 0x5a, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, \ - 0x1e, 0x14, 0x74, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x70, 0x72, 0x6f, 0x70, \ - 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, \ - 0x73, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, \ - 0x01, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, \ - 0x12, 0x6c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, \ - 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, 0x00, \ - 0x5a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x24, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, \ - 0x72, 0x74, 0x69, 0x65, 0x73, 0x5f, 0x74, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, \ - 0x61, 0x75, 0x74, 0x6f, 0x64, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x00, 0x00, 0x00, 0xf2, 0xd8, \ - 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x00, \ - 0x5d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x6c, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, \ - 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, \ - 0x4b, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, \ - 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, \ - 0x6c, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x23, 0x8b, 0x8e, 0x23, 0x5b, 0x28, \ - 0x6c, 0x8f, 0xdc, 0xbe, 0xb4, 0x11, 0x97, 0xf1, 0xec, 0x4a, 0x62, 0xf3, 0x6a, 0xef, 0x58, 0xa5, \ - 0x3c, 0x25, 0xca, 0x35, 0x2c, 0x96, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, \ - 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, 0x97, 0x1d, 0x9d, 0x84, 0x02, 0x9a, \ - 0x5e, 0x04, 0xd3, 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, \ - 0xf1, 0xef, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, \ - 0x88, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, \ - 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0xf1, \ - 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0xf2, 0x83, \ - 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0xf1, 0x80, 0x45, \ - 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x9c, 0x5d, 0x42, \ - 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0xf1, 0xd8, 0x39, 0x8b, 0x25, \ - 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, \ - 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, \ - 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, \ - 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, \ - 0xa7, 0x4c, 0x9a, 0xa4, 0x27, 0x19, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, \ - 0x1e, 0x14, 0x74, 0xb3, 0x00, 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, \ - 0x1d, 0xad, 0xb0, 0x67, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, \ - 0xa7, 0x12, 0x6c, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, \ - 0x68, 0xcd, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, \ - 0x9b, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ + 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, \ + 0x73, 0x5f, 0x74, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x61, 0x75, 0x74, 0x6f, \ + 0x64, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, \ + 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x6c, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0xf2, 0xa0, 0x92, \ + 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x4b, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \ + 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x01, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0xf2, 0xa1, 0x0b, 0x59, 0xcc, 0x2a, 0xc5, 0x23, 0x4a, 0x0a, 0xb0, 0xc8, \ + 0x9d, 0xee, 0xd6, 0xf1, 0x33, 0x3a, 0x52, 0x75, 0x87, 0xbe, 0x11, 0x92, 0x8a, 0xd9, 0xcb, 0xfa, \ + 0x18, 0x03, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ + 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, 0x13, 0xf0, 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0xf1, \ + 0xe4, 0xbc, 0x4a, 0x05, 0x08, 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0xf2, 0x10, \ + 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0xf1, 0x80, 0x45, \ + 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x5d, 0xe9, 0x73, \ + 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0xf1, 0x7f, 0xe2, 0x25, 0x62, \ + 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, \ + 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, \ + 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, \ + 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, \ + 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, 0xe5, 0xaa, 0x4c, \ + 0x37, 0x2c, 0x3b, 0x56, 0x55, 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, 0xb1, 0x14, 0xfe, 0xcd, 0xa3, \ + 0xf2, 0xc2, 0xeb, 0xd6, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, \ + 0xe0, 0x71, 0xea, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, \ + 0x27, 0x19, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, \ + 0x00, 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, 0x1d, 0xad, 0xb0, 0x67, \ + 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, \ + 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0xf2, 0xa0, \ + 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0xf1, 0xa5, 0x80, \ + 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_bead 3072u +#define TYPE_MAP_CDR_SZ_DurableSupport_bead 3116u const dds_topic_descriptor_t DurableSupport_bead_desc = { .m_size = sizeof (DurableSupport_bead), @@ -607,7 +615,7 @@ const dds_topic_descriptor_t DurableSupport_bead_desc = .m_nkeys = 1u, .m_typename = "DurableSupport::bead", .m_keys = DurableSupport_bead_keys, - .m_nops = 39, + .m_nops = 40, .m_ops = DurableSupport_bead_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_bead, .sz = TYPE_INFO_CDR_SZ_DurableSupport_bead }, @@ -621,44 +629,49 @@ static const uint32_t DurableSupport_request_ops [] = DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, client), 16u, DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, partition), DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, type_id), DDS_OP_ADR | DDS_OP_TYPE_8BY | DDS_OP_FLAG_SGN, offsetof (DurableSupport_request, timeout), DDS_OP_RTS, /* key: client */ DDS_OP_KOF | 1, 1u /* order: 0 */, - + /* key: partition */ DDS_OP_KOF | 1, 4u /* order: 1 */, /* key: tpname */ - DDS_OP_KOF | 1, 6u /* order: 2 */ + DDS_OP_KOF | 1, 6u /* order: 2 */, + + /* key: type_id */ + DDS_OP_KOF | 1, 8u /* order: 3 */ }; -static const dds_key_descriptor_t DurableSupport_request_keys[3] = +static const dds_key_descriptor_t DurableSupport_request_keys[4] = { - { "client", 11, 0 }, - { "partition", 13, 1 }, - { "tpname", 15, 2 } + { "client", 13, 0 }, + { "partition", 15, 1 }, + { "tpname", 17, 2 }, + { "type_id", 19, 3 } }; /* Type Information: - [MINIMAL 3f4b9832b556de33be4c31963879] (#deps: 2) + [MINIMAL dd0d9462a253e8cce609462197f1] (#deps: 2) - [MINIMAL 43f53a2be35b432cc735e9431a89] - [MINIMAL 84ce9c3d894c1483f859c00d5927] - [COMPLETE 2992c8ff086f0c3d6eb4041c2b94] (#deps: 2) + [COMPLETE 798973adc9bb497149ff155ebd9a] (#deps: 2) - [COMPLETE aca4d5a256d39713924333e85c6d] - [COMPLETE 023df3bd21223779cd1936cef928] */ #define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ 0xc0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x3f, 0x4b, 0x98, 0x32, 0xb5, 0x56, 0xde, 0x33, 0xbe, 0x4c, 0x31, \ - 0x96, 0x38, 0x79, 0x00, 0x75, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0xdd, 0x0d, 0x94, 0x62, 0xa2, 0x53, 0xe8, 0xcc, 0xe6, 0x09, 0x46, \ + 0x21, 0x97, 0xf1, 0x00, 0x85, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, \ 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x29, 0x92, 0xc8, 0xff, 0x08, 0x6f, 0x0c, 0x3d, 0x6e, 0xb4, 0x04, \ - 0x1c, 0x2b, 0x94, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x79, 0x89, 0x73, 0xad, 0xc9, 0xbb, 0x49, 0x71, 0x49, 0xff, 0x15, \ + 0x5e, 0xbd, 0x9a, 0x00, 0xde, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ @@ -666,61 +679,64 @@ static const dds_key_descriptor_t DurableSupport_request_keys[3] = } #define TYPE_INFO_CDR_SZ_DurableSupport_request 196u #define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ - 0xdb, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0x3f, 0x4b, 0x98, 0x32, 0xb5, 0x56, 0xde, \ - 0x33, 0xbe, 0x4c, 0x31, 0x96, 0x38, 0x79, 0x00, 0x71, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0xeb, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0xdd, 0x0d, 0x94, 0x62, 0xa2, 0x53, 0xe8, \ + 0xcc, 0xe6, 0x09, 0x46, 0x21, 0x97, 0xf1, 0x00, 0x81, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ - 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ + 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, \ + 0x19, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ - 0x71, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0x29, 0x92, 0xc8, 0xff, 0x08, 0x6f, 0x0c, \ - 0x3d, 0x6e, 0xb4, 0x04, 0x1c, 0x2b, 0x94, 0x00, 0xbe, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x8d, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0x79, 0x89, 0x73, 0xad, 0xc9, 0xbb, 0x49, \ + 0x71, 0x49, 0xff, 0x15, 0x5e, 0xbd, 0x9a, 0x00, 0xda, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x00, 0x92, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ + 0x65, 0x73, 0x74, 0x00, 0xae, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, \ 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, \ 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, \ 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x26, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, \ - 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, \ - 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x02, 0x3d, 0xf3, \ - 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x35, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0xf2, 0x29, 0x92, 0xc8, 0xff, 0x08, 0x6f, 0x0c, 0x3d, 0x6e, 0xb4, 0x04, 0x1c, 0x2b, 0x94, 0xf1, \ - 0x3f, 0x4b, 0x98, 0x32, 0xb5, 0x56, 0xde, 0x33, 0xbe, 0x4c, 0x31, 0x96, 0x38, 0x79, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, 0x3d, 0xf3, \ - 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, 0x9c, 0x3d, \ - 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ + 0x16, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, \ + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, \ + 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, \ + 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, \ + 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x75, 0x72, 0x61, \ + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0x79, 0x89, 0x73, \ + 0xad, 0xc9, 0xbb, 0x49, 0x71, 0x49, 0xff, 0x15, 0x5e, 0xbd, 0x9a, 0xf1, 0xdd, 0x0d, 0x94, 0x62, \ + 0xa2, 0x53, 0xe8, 0xcc, 0xe6, 0x09, 0x46, 0x21, 0x97, 0xf1, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, \ + 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, \ + 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, \ + 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_request 698u +#define TYPE_MAP_CDR_SZ_DurableSupport_request 742u const dds_topic_descriptor_t DurableSupport_request_desc = { .m_size = sizeof (DurableSupport_request), .m_align = dds_alignof (DurableSupport_request), .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 3u, + .m_nkeys = 4u, .m_typename = "DurableSupport::request", .m_keys = DurableSupport_request_keys, - .m_nops = 6, + .m_nops = 7, .m_ops = DurableSupport_request_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request }, @@ -739,7 +755,7 @@ static const uint32_t DurableSupport_response_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_response_content, _d), 2u, (12u << 16u) + 4u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 9 /* response_set_t */, 1, offsetof (DurableSupport_response_content, _u.set), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 15 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 17 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, DDS_OP_RTS, /* response_set_t */ @@ -747,6 +763,7 @@ static const uint32_t DurableSupport_response_ops [] = DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_response_set_t, delivery_id), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, partition), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, tpname), + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, type_id), DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_response_set_t, flags), DDS_OP_RTS, @@ -754,119 +771,120 @@ static const uint32_t DurableSupport_response_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_response_data_t, blob), DDS_OP_RTS, - + /* key: id */ DDS_OP_KOF | 1, 1u /* order: 0 */ }; static const dds_key_descriptor_t DurableSupport_response_keys[1] = { - { "id", 36, 0 } + { "id", 38, 0 } }; /* Type Information: - [MINIMAL 730b9fd245b7a2458badcdadd452] (#deps: 6) + [MINIMAL 7172db81541171f4d3215f317121] (#deps: 6) - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL b2788efd3d9c71afbf128dd8d568] + - [MINIMAL adf1bdbb30b9d6975e377ee51fa4] - [MINIMAL 80455e796dd3437163cb532089da] - - [MINIMAL 26fb4226a2ccc89e6a040bf4add4] + - [MINIMAL 19656e10c4f1e4cd8e04106c5b0f] - [MINIMAL d8398b259af5a04792e296996c27] - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE 11d82f7f8e658cff91d8836b578f] (#deps: 6) + [COMPLETE eb98abe5dd8d7bfb5b2507da617d] (#deps: 6) - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE b6edd532689bbbb0dee0ee93c7ae] + - [COMPLETE 5c1f20e6410aad78dfe023066879] - [COMPLETE eec1bad6badde73f40ef199fedcc] - - [COMPLETE 6c90b4bf595ec04bb56d1fd6e2b5] + - [COMPLETE e4730a78f541604cc1a1a037ef05] - [COMPLETE 7b005a124ff7bda9c39eb4003556] - [COMPLETE 008875599776c39ce0c1fe897846] */ #define TYPE_INFO_CDR_DurableSupport_response (const unsigned char []){ \ 0x80, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x73, 0x0b, 0x9f, 0xd2, 0x45, 0xb7, 0xa2, 0x45, 0x8b, 0xad, 0xcd, \ - 0xad, 0xd4, 0x52, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x71, 0x72, 0xdb, 0x81, 0x54, 0x11, 0x71, 0xf4, 0xd3, 0x21, 0x5f, \ + 0x31, 0x71, 0x21, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xb2, 0x78, 0x8e, 0xfd, 0x3d, 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0x00, \ + 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, 0xb9, 0xd6, 0x97, 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0x00, \ 0x7c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x26, 0xfb, 0x42, 0x26, 0xa2, 0xcc, 0xc8, 0x9e, 0x6a, 0x04, 0x0b, 0xf4, 0xad, 0xd4, 0x00, \ - 0x67, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ + 0xf1, 0x19, 0x65, 0x6e, 0x10, 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, 0x5b, 0x0f, 0x00, \ + 0x77, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x11, 0xd8, 0x2f, 0x7f, 0x8e, 0x65, 0x8c, 0xff, 0x91, 0xd8, 0x83, \ - 0x6b, 0x57, 0x8f, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0xeb, 0x98, 0xab, 0xe5, 0xdd, 0x8d, 0x7b, 0xfb, 0x5b, 0x25, 0x07, \ + 0xda, 0x61, 0x7d, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xb6, 0xed, 0xd5, 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, 0xe0, 0xee, 0x93, 0xc7, 0xae, 0x00, \ + 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, 0x78, 0xdf, 0xe0, 0x23, 0x06, 0x68, 0x79, 0x00, \ 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, \ 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, 0xc0, 0x4b, 0xb5, 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0x00, \ - 0xbc, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, \ + 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, 0x60, 0x4c, 0xc1, 0xa1, 0xa0, 0x37, 0xef, 0x05, 0x00, \ + 0xd8, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, \ 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ 0x57, 0x00, 0x00, 0x00\ } #define TYPE_INFO_CDR_SZ_DurableSupport_response 388u #define TYPE_MAP_CDR_DurableSupport_response (const unsigned char []){ \ - 0x20, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0x73, 0x0b, 0x9f, 0xd2, 0x45, 0xb7, 0xa2, \ - 0x45, 0x8b, 0xad, 0xcd, 0xad, 0xd4, 0x52, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x30, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0x71, 0x72, 0xdb, 0x81, 0x54, 0x11, 0x71, \ + 0xf4, 0xd3, 0x21, 0x5f, 0x31, 0x71, 0x21, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xb2, 0x78, 0x8e, 0xfd, 0x3d, \ - 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, \ + 0xb9, 0xd6, 0x97, 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0xb2, 0x78, 0x8e, 0xfd, 0x3d, \ - 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, \ + 0xb9, 0xd6, 0x97, 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ 0x54, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x26, 0xfb, 0x42, 0x26, 0xa2, 0xcc, 0xc8, 0x9e, 0x6a, 0x04, 0x0b, 0xf4, 0xad, \ - 0xd4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ + 0x01, 0x00, 0xf1, 0x19, 0x65, 0x6e, 0x10, 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, 0x5b, \ + 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x26, 0xfb, 0x42, 0x26, \ - 0xa2, 0xcc, 0xc8, 0x9e, 0x6a, 0x04, 0x0b, 0xf4, 0xad, 0xd4, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x19, 0x65, 0x6e, 0x10, \ + 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, 0x5b, 0x0f, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x7c, 0x4b, 0x99, \ 0xfe, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x7e, 0x75, 0xc0, 0xed, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, \ + 0x7e, 0x75, 0xc0, 0xed, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x94, 0x75, 0x7c, 0xae, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, \ 0x58, 0x68, 0xd6, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, \ 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \ - 0xee, 0x26, 0x90, 0x8b, 0x7f, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0x11, 0xd8, 0x2f, \ - 0x7f, 0x8e, 0x65, 0x8c, 0xff, 0x91, 0xd8, 0x83, 0x6b, 0x57, 0x8f, 0x00, 0x83, 0x00, 0x00, 0x00, \ + 0xee, 0x26, 0x90, 0x8b, 0x9b, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0xeb, 0x98, 0xab, \ + 0xe5, 0xdd, 0x8d, 0x7b, 0xfb, 0x5b, 0x25, 0x07, 0xda, 0x61, 0x7d, 0x00, 0x83, 0x00, 0x00, 0x00, \ 0xf2, 0x51, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, \ 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xb6, 0xed, 0xd5, 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, \ - 0xe0, 0xee, 0x93, 0xc7, 0xae, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, 0x78, 0xdf, \ + 0xe0, 0x23, 0x06, 0x68, 0x79, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, \ 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, \ 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x10, 0x02, 0x00, 0x00, 0xf2, 0xb6, 0xed, 0xd5, 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, 0xe0, 0xee, \ - 0x93, 0xc7, 0xae, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, \ + 0x10, 0x02, 0x00, 0x00, 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, 0x78, 0xdf, 0xe0, 0x23, \ + 0x06, 0x68, 0x79, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, \ 0x11, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, \ 0xcc, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, 0xc0, 0x4b, 0xb5, \ - 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, 0x60, 0x4c, 0xc1, \ + 0xa1, 0xa0, 0x37, 0xef, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, \ 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ @@ -875,47 +893,48 @@ static const dds_key_descriptor_t DurableSupport_response_keys[1] = 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, \ - 0xc0, 0x4b, 0xb5, 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0xb8, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, \ + 0x60, 0x4c, 0xc1, 0xa1, 0xa0, 0x37, 0xef, 0x05, 0xd4, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, \ - 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x7b, \ + 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x7b, \ 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, 0x00, 0x00, \ 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, \ - 0x73, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, \ - 0x00, 0x35, 0x56, 0x00, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, \ - 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, \ - 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, \ - 0x53, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x20, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, \ - 0x61, 0x5f, 0x74, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, \ - 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0xf2, 0x11, 0xd8, 0x2f, 0x7f, 0x8e, 0x65, 0x8c, 0xff, 0x91, 0xd8, 0x83, 0x6b, 0x57, 0x8f, 0xf1, \ - 0x73, 0x0b, 0x9f, 0xd2, 0x45, 0xb7, 0xa2, 0x45, 0x8b, 0xad, 0xcd, 0xad, 0xd4, 0x52, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0xb6, 0xed, 0xd5, \ - 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, 0xe0, 0xee, 0x93, 0xc7, 0xae, 0xf1, 0xb2, 0x78, 0x8e, 0xfd, \ - 0x3d, 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, \ - 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, \ - 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, 0xc0, \ - 0x4b, 0xb5, 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0xf1, 0x26, 0xfb, 0x42, 0x26, 0xa2, 0xcc, 0xc8, 0x9e, \ - 0x6a, 0x04, 0x0b, 0xf4, 0xad, 0xd4, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, \ - 0x9e, 0xb4, 0x00, 0x35, 0x56, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, \ - 0x96, 0x99, 0x6c, 0x27, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, \ - 0x89, 0x78, 0x46, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, \ - 0xe8, 0x44\ + 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, \ + 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ + 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, \ + 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x5f, \ + 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xf2, 0x00, 0x88, \ + 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x53, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, \ + 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0xeb, 0x98, 0xab, \ + 0xe5, 0xdd, 0x8d, 0x7b, 0xfb, 0x5b, 0x25, 0x07, 0xda, 0x61, 0x7d, 0xf1, 0x71, 0x72, 0xdb, 0x81, \ + 0x54, 0x11, 0x71, 0xf4, 0xd3, 0x21, 0x5f, 0x31, 0x71, 0x21, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, \ + 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, \ + 0x78, 0xdf, 0xe0, 0x23, 0x06, 0x68, 0x79, 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, 0xb9, 0xd6, 0x97, \ + 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ + 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, \ + 0x53, 0x20, 0x89, 0xda, 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, 0x60, 0x4c, 0xc1, 0xa1, 0xa0, \ + 0x37, 0xef, 0x05, 0xf1, 0x19, 0x65, 0x6e, 0x10, 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, \ + 0x5b, 0x0f, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, \ + 0x56, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, \ + 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0xf1, \ + 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_response 1666u +#define TYPE_MAP_CDR_SZ_DurableSupport_response 1710u const dds_topic_descriptor_t DurableSupport_response_desc = { .m_size = sizeof (DurableSupport_response), @@ -924,7 +943,7 @@ const dds_topic_descriptor_t DurableSupport_response_desc = .m_nkeys = 1u, .m_typename = "DurableSupport::response", .m_keys = DurableSupport_response_keys, - .m_nops = 18, + .m_nops = 19, .m_ops = DurableSupport_response_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_response, .sz = TYPE_INFO_CDR_SZ_DurableSupport_response }, From 174ee2ee93fc3bfd389ef18e65ee4f8a67c2a430 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 22 Mar 2024 14:02:16 +0100 Subject: [PATCH 033/207] Fix merge issues when rebasing on CycloneDDS master Signed-off-by: TheFixer --- docs/manual/config/config_file_reference.rst | 6 +++--- docs/manual/options.md | 2 +- etc/cyclonedds.rnc | 2 +- etc/cyclonedds.xsd | 2 +- src/core/ddsc/src/dds_participant.c | 13 +++++++++++-- src/core/ddsc/src/dds_reader.c | 8 +++++++- src/core/ddsc/src/dds_write.c | 8 +++++--- src/core/ddsi/defconfig.c | 2 +- src/durability/src/dds_durability.c | 12 +++++++----- 9 files changed, 37 insertions(+), 18 deletions(-) diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index 0cd03a9a2e..d58d6b10c2 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -22,7 +22,7 @@ CycloneDDS configuration ******************* Attributes: :ref:`Id` -Children: :ref:`Compatibility`, :ref:`Discovery`, :ref:`Discovery`, :ref:`General`, :ref:`Internal|Unsupported`, :ref:`Partitioning`, :ref:`SSL`, :ref:`Security|DDSSecurity`, :ref:`SharedMemory`, :ref:`Sizing`, :ref:`TCP`, :ref:`Threads`, :ref:`Tracing` +Children: :ref:`Compatibility`, :ref:`Discovery`, :ref:`Durability`, :ref:`General`, :ref:`Internal|Unsupported`, :ref:`Partitioning`, :ref:`SSL`, :ref:`Security|DDSSecurity`, :ref:`SharedMemory`, :ref:`Sizing`, :ref:`TCP`, :ref:`Threads`, :ref:`Tracing` The General element specifying Domain related settings. @@ -379,7 +379,7 @@ The default value is: ```` //CycloneDDS/Domain/Durability ============================== -Children: `//CycloneDDS/Domain/Durability/Quorum`_ +Children: :ref:`Quorum` This element specifies settings related to durable data. @@ -2671,7 +2671,7 @@ The default value is: ``none`` .. generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] - generated from ddsi__cfgelems.h[0fe5caa90873f3af7436f0f201edeccaea9fedd4] + generated from ddsi__cfgelems.h[fb5382bc6dbb34bca275d20c3c4282f948318862] generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] diff --git a/docs/manual/options.md b/docs/manual/options.md index 7b6de3a232..62d966b3da 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -1867,7 +1867,7 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: `none` - + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index dc2faeea56..dc224869db 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -1295,7 +1295,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
    } # generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] # generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] -# generated from ddsi__cfgelems.h[0fe5caa90873f3af7436f0f201edeccaea9fedd4] +# generated from ddsi__cfgelems.h[fb5382bc6dbb34bca275d20c3c4282f948318862] # generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] # generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] # generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index a6ee743f36..bf2efad66d 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -1960,7 +1960,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - + diff --git a/src/core/ddsc/src/dds_participant.c b/src/core/ddsc/src/dds_participant.c index dd3e8a6169..e5aabf8b91 100644 --- a/src/core/ddsc/src/dds_participant.c +++ b/src/core/ddsc/src/dds_participant.c @@ -63,9 +63,16 @@ static dds_return_t dds_participant_delete (dds_entity *e) ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); #ifdef DDS_HAS_DURABILITY - dds_durability_fini(); + (void)dds_durability_fini(); #endif + /* todo It seems incorrect that dds_participant_delete() + * always returns DDS_RETCODE_OK, even if an error has + * occurred along the way (e.g., in ddsi_delete_participant()). + * I tried returning the actual return code, but that causes + * test cases to fail. For now I leave it as is, but this is + * something that should be fixed eventually (I think). + */ return DDS_RETCODE_OK; } @@ -172,7 +179,9 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ dds_entity_unpin_and_drop_ref (&dds_global.m_entity); #ifdef DDS_HAS_DURABILITY - dds_durability_init (domain, &dom->gv); + if (ret > 0) { + (void)dds_durability_init (domain, &dom->gv); + } #endif return ret; diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index 0a706938e9..61e88f8484 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -704,7 +704,10 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe #ifdef DDS_HAS_DURABILITY dds_durability_kind_t dkind; - dds_qget_durability(rqos, &dkind); + if (!dds_qget_durability(rqos, &dkind)) { + rc = DDS_RETCODE_ERROR; + goto err_qget_durability; + } #endif /* Create reader and associated read cache (if not provided by caller) */ @@ -786,6 +789,9 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe err_psmx_endpoint_setcb: dds_endpoint_remove_psmx_endpoints (&rd->m_endpoint); err_create_endpoint: +#ifdef DDS_HAS_DURABILITY +err_qget_durability: +#endif err_bad_qos: err_data_repr: err_psmx: diff --git a/src/core/ddsc/src/dds_write.c b/src/core/ddsc/src/dds_write.c index 1b8e3d33fc..a9761aaf1f 100644 --- a/src/core/ddsc/src/dds_write.c +++ b/src/core/ddsc/src/dds_write.c @@ -52,7 +52,7 @@ dds_return_t dds_write (dds_entity_t writer, const void *data) * LH: This implementation may be suboptimal, because determining whether the * quorum is fulfilled, and the actual publication of the data is not done * within the same writer lock. So after the quorum has been established, - * and before the data is published, the quorum could have been dropped. + * and before the data is published, the quorum could have been dropped again. * Chances for this to happen are slim, but still ... */ if ((ret = dds_durability_wait_for_quorum(writer)) != DDS_RETCODE_OK) { return ret; @@ -790,13 +790,15 @@ dds_return_t dds_write_impl (dds_writer *wr, const void *data, dds_time_t timest return DDS_RETCODE_OK; #ifdef DDS_HAS_DURABILITY - /* check if the quorum of durable services for the writer is fulfilled - * + /* Check if the quorum of durable services for the writer is fulfilled + * If it is not met within the max_blocking_time, then DDS_RETCODE_PRECONDITION_NOT_MET + * is returned. * LH: * todo this currently is solution to handle the case when the quorum is not yet reached. * A better solution would be to use the max_blocking_time and use it to figure out * if the quorum is reached within this time frame. The headbang period would then be * used to check if the quorum is met. */ + struct ddsi_writer * const ddsi_wr = wr->m_wr; if ((ddsi_wr->xqos->durability.kind == DDS_DURABILITY_TRANSIENT) || (ddsi_wr->xqos->durability.kind == DDS_DURABILITY_PERSISTENT)) { if (!wr->quorum_reached) { return DDS_RETCODE_PRECONDITION_NOT_MET; diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index 3f49794bb1..c76bf097fe 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -104,7 +104,7 @@ void ddsi_config_init_default (struct ddsi_config *cfg) } /* generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] */ /* generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] */ -/* generated from ddsi__cfgelems.h[0fe5caa90873f3af7436f0f201edeccaea9fedd4] */ +/* generated from ddsi__cfgelems.h[fb5382bc6dbb34bca275d20c3c4282f948318862] */ /* generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] */ /* generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] */ /* generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] */ diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 0345f60dab..696c1c4392 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -751,7 +751,7 @@ static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *e /* Determine if the quorum for the writer is reached or not. * This function also does its job when the quorum threshold is 0, - * even though this case is likely to be prohibited because it + * even though this case should likely be prohibited because it * violates eventual consistency. After all, how can you provide * historical data if you allow that durable publishers start to * publish when there is no durable support? */ @@ -810,8 +810,9 @@ static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer, bool * that the quorum_reached property of the writer changes. * Because the call to dds_get_matched_subscriptions() requires * an preallocated list of reader handles and we don't know the - * size of the list beforehand, we dynamically extend the list - * until it is large enough to hold all handles of matching readers. */ + * size of the list beforehand, we initially bound the list to + * 256 and extend it dynamically until it is large enough to hold + * all handles of matching readers. */ do { nrds = nrds * 2; rd_ihs = ddsrt_malloc(nrds * sizeof(dds_instance_handle_t)); @@ -1751,7 +1752,6 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade DDS_ERROR("failed to get partitions from qos\n"); goto err_qget_partition; } - assert(plen > 0); /* for each partition create a proxy set if it does not exist yet * and request data for the proxy set (if not done so already) */ for (i=0; i < plen; i++) { @@ -2122,13 +2122,15 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); ddsrt_free(dc.cfg.ident); + ddsrt_atomic_dec32(&dc.refcount); + memset(&dc, 0, sizeof(struct dc_t)); return DDS_RETCODE_ERROR; } /* make sure that dc terminates when the last participant is destroyed */ dds_return_t dds_durability_fini (void) { - dds_return_t rc; + dds_return_t rc = DDS_RETCODE_OK; uint32_t refcount; /* The durable client is deinitialized when the last participant is about From 4e46317b6dbcac5fdb664e943505f9d264ba0bd3 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 22 Mar 2024 14:04:04 +0100 Subject: [PATCH 034/207] Exclude test cases for transient and persistent profiles when there is no durable support yet Signed-off-by: TheFixer --- src/core/ddsc/tests/entity_status.c | 2 +- src/core/ddsc/tests/qosmatch.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/ddsc/tests/entity_status.c b/src/core/ddsc/tests/entity_status.c index 83611e56a7..9defb9c7b1 100644 --- a/src/core/ddsc/tests/entity_status.c +++ b/src/core/ddsc/tests/entity_status.c @@ -235,7 +235,7 @@ CU_Test(ddsc_entity, incompatible_qos, .init=init_entity_status, .fini=fini_enti dds_offered_incompatible_qos_status_t off_incompatible_qos; memset (&req_incompatible_qos, 0, sizeof (req_incompatible_qos)); memset (&off_incompatible_qos, 0, sizeof (off_incompatible_qos)); - dds_qset_durability (qos, DDS_DURABILITY_PERSISTENT); + dds_qset_durability (qos, DDS_DURABILITY_TRANSIENT_LOCAL); /* Create a reader with persistent durability */ reader2 = dds_create_reader(participant, top, qos, NULL); diff --git a/src/core/ddsc/tests/qosmatch.c b/src/core/ddsc/tests/qosmatch.c index 8a1448d1d7..e6329f5842 100644 --- a/src/core/ddsc/tests/qosmatch.c +++ b/src/core/ddsc/tests/qosmatch.c @@ -81,10 +81,12 @@ static void setqos (dds_qos_t *q, size_t i, bool isrd, bool create) } /* Cyclone's accepting unimplemented QoS settings is a bug, but it does allow - us to feed it all kinds of nonsense and see whether discovery manages it */ + us to feed it all kinds of nonsense and see whether discovery manages it. + As far as the durability qos setting is concerned, we restrict it to VOLATILE + and TRANSIENT-LOCAL for the moment while implementing the durable profiles */ /* this makes topic transient-local, keep-last 1 */ - dds_qset_durability (q, (dds_durability_kind_t) ((i + 1) % 4)); + dds_qset_durability (q, (dds_durability_kind_t) ((i + 1) % 2)); dds_qset_history (q, (dds_history_kind_t) ((i + 1) % 2), (int32_t) (i + 1)); dds_qset_resource_limits (q, (int32_t) i + 3, (int32_t) i + 2, (int32_t) i + 1); dds_qset_presentation (q, (dds_presentation_access_scope_kind_t) ((psi + 1) % 3), 1, 1); From 53a204fa67f045704451471b5b7195eb9daca330 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 29 Jan 2024 13:49:32 +0100 Subject: [PATCH 035/207] Allow multipathing between PSMX and DDSI Once upon a time sending a sample to a single destination via PSMX and DDSI at the same time would lead to stuttering because of insufficient precise filtering in the delivery paths, but that problem has been fixed a long time ago (I think in commit ef91c275e5b6649279fff7d29462d491a0d08b28). For a long time, no-one realised that the bit that prevented this from happening was left in. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_wraddrset.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/core/ddsi/src/ddsi_wraddrset.c b/src/core/ddsi/src/ddsi_wraddrset.c index 90fa3dd570..3805e76d43 100644 --- a/src/core/ddsi/src/ddsi_wraddrset.c +++ b/src/core/ddsi/src/ddsi_wraddrset.c @@ -324,9 +324,7 @@ static const int32_t cost_discarded = 1; // Cost associated with delivering another time to a reader that has // already been covered by a (selected) PSMX locator. -// Currently, it is quite painful when this happens because it can -// lead to user observable stuttering. -static const int32_t cost_redundant_psmx = 1000000; +static const int32_t cost_redundant_psmx = 0; // Cost associated with delivering data for the first time (slightly // negative cost makes it possible to give a slightly higher initial From 648a898d686e6664ab3267bc9b3e86bac2d06992 Mon Sep 17 00:00:00 2001 From: MarcelJordense <37329887+MarcelJordense@users.noreply.github.com> Date: Mon, 25 Mar 2024 11:55:59 +0100 Subject: [PATCH 036/207] remove deprecate warnings when using openssl v3 (#1826) * update the security plugins remove deprecate warning when using openssl v3 Signed-off-by: Marcel Jordense * resolve memory leak in security test cases and process review comments Signed-off-by: Marcel Jordense --------- Signed-off-by: Marcel Jordense --- .../authentication/src/auth_utils.c | 341 ++++++-- .../tests/common/src/handshake_helper.c | 762 +++++++++++++++--- .../tests/common/src/handshake_helper.h | 39 +- ...thenticated_peer_credential_token_utests.c | 214 ----- .../src/listeners_authentication_utests.c | 368 +-------- .../src/process_handshake_utests.c | 220 ----- .../validate_begin_handshake_reply_utests.c | 32 +- src/security/core/tests/common/cert_utils.c | 4 +- .../include/dds/security/openssl_support.h | 6 +- 9 files changed, 981 insertions(+), 1005 deletions(-) diff --git a/src/security/builtin_plugins/authentication/src/auth_utils.c b/src/security/builtin_plugins/authentication/src/auth_utils.c index 6acbf9bbc1..388f58fff6 100644 --- a/src/security/builtin_plugins/authentication/src/auth_utils.c +++ b/src/security/builtin_plugins/authentication/src/auth_utils.c @@ -74,7 +74,7 @@ char *get_certificate_subject_name(X509 *cert, DDS_Security_SecurityException *e dds_time_t get_certificate_expiry(const X509 *cert) { assert(cert); - ASN1_TIME *asn1 = X509_get_notAfter(cert); + const ASN1_TIME *asn1 = X509_get0_notAfter(cert); if (asn1 != NULL) { int days, seconds; @@ -123,6 +123,75 @@ DDS_Security_ValidationResult_t get_subject_name_DER_encoded(const X509 *cert, u return DDS_SECURITY_VALIDATION_OK; } +#if OPENSSL_VERSION_NUMBER < 0x30000000L + +static DDS_Security_ValidationResult_t check_key(EVP_PKEY *key, const char *key_type, bool isPrivate, DDS_Security_SecurityException *ex) +{ + DDSRT_UNUSED_ARG(key_type); + + if (EVP_PKEY_id(key) == EVP_PKEY_RSA) + { + if (isPrivate) + { + RSA *rsaKey = EVP_PKEY_get1_RSA(key); + const bool fail = (rsaKey && RSA_check_key(rsaKey) != 1); + RSA_free(rsaKey); + if (fail) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "RSA key not correct : "); + return DDS_SECURITY_VALIDATION_FAILED; + } + } + } + else + { + assert(EVP_PKEY_id(key) == EVP_PKEY_EC); + EC_KEY *ecKey = EVP_PKEY_get1_EC_KEY(key); + const bool fail = (ecKey && EC_KEY_check_key(ecKey) != 1); + EC_KEY_free(ecKey); + if (fail) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EC key not correct : "); + return DDS_SECURITY_VALIDATION_FAILED; + } + } + return DDS_SECURITY_VALIDATION_OK; +} + +#else + +static DDS_Security_ValidationResult_t check_key(EVP_PKEY *key, const char *key_type, int isPrivate, DDS_Security_SecurityException *ex) +{ + DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; + EVP_PKEY_CTX *ctx = NULL; + + if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, key, NULL)) == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EVP_PKEY_CTX_new_from_pkey(%s) failed : ", key_type); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (isPrivate) + { + if (EVP_PKEY_private_check(ctx) != 1) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "%s key not correct : ", key_type); + result = DDS_SECURITY_VALIDATION_FAILED ; + } + } + else + { + if (EVP_PKEY_public_check(ctx) != 1) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "%s key not correct : ", key_type); + result = DDS_SECURITY_VALIDATION_FAILED ; + } + } + EVP_PKEY_CTX_free(ctx); + return result; +} + +#endif + static DDS_Security_ValidationResult_t check_key_type_and_size(EVP_PKEY *key, int isPrivate, DDS_Security_SecurityException *ex) { const char *sub = isPrivate ? "private key" : "certificate"; @@ -135,18 +204,7 @@ static DDS_Security_ValidationResult_t check_key_type_and_size(EVP_PKEY *key, in DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "RSA %s has unsupported key size (%d)", sub, EVP_PKEY_bits(key)); return DDS_SECURITY_VALIDATION_FAILED; } - if (isPrivate) - { - RSA *rsaKey = EVP_PKEY_get1_RSA(key); - const bool fail = (rsaKey && RSA_check_key(rsaKey) != 1); - RSA_free(rsaKey); - if (fail) - { - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "RSA key not correct : "); - return DDS_SECURITY_VALIDATION_FAILED; - } - } - return DDS_SECURITY_VALIDATION_OK; + return check_key(key, "RSA", isPrivate, ex); case EVP_PKEY_EC: if (EVP_PKEY_bits(key) != 256) @@ -154,15 +212,7 @@ static DDS_Security_ValidationResult_t check_key_type_and_size(EVP_PKEY *key, in DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EC %s has unsupported key size (%d)", sub, EVP_PKEY_bits(key)); return DDS_SECURITY_VALIDATION_FAILED; } - EC_KEY *ecKey = EVP_PKEY_get1_EC_KEY(key); - const bool fail = (ecKey && EC_KEY_check_key(ecKey) != 1); - EC_KEY_free(ecKey); - if (fail) - { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EC key not correct : "); - return DDS_SECURITY_VALIDATION_FAILED; - } - return DDS_SECURITY_VALIDATION_OK; + return check_key(key, "EC", isPrivate, ex); default: DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "%s has not supported type", sub); @@ -187,12 +237,12 @@ static DDS_Security_ValidationResult_t check_certificate_type_and_size(X509 *cer DDS_Security_ValidationResult_t check_certificate_expiry(const X509 *cert, DDS_Security_SecurityException *ex) { assert(cert); - if (X509_cmp_current_time(X509_get_notBefore(cert)) == 0) + if (X509_cmp_current_time(X509_get0_notBefore(cert)) == 0) { DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CERT_STARTDATE_IN_FUTURE_CODE, DDS_SECURITY_VALIDATION_FAILED, DDS_SECURITY_ERR_CERT_STARTDATE_IN_FUTURE_MESSAGE); return DDS_SECURITY_VALIDATION_FAILED; } - if (X509_cmp_current_time(X509_get_notAfter(cert)) == 0) + if (X509_cmp_current_time(X509_get0_notAfter(cert)) == 0) { DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CERT_EXPIRED_CODE, DDS_SECURITY_VALIDATION_FAILED, DDS_SECURITY_ERR_CERT_EXPIRED_MESSAGE); return DDS_SECURITY_VALIDATION_FAILED; @@ -681,6 +731,8 @@ DDS_Security_ValidationResult_t get_certificate_contents(X509 *cert, unsigned ch return DDS_SECURITY_VALIDATION_OK; } +#if OPENSSL_VERSION_NUMBER < 0x30000000L + static DDS_Security_ValidationResult_t get_rsa_dh_parameters(EVP_PKEY **params, DDS_Security_SecurityException *ex) { DH *dh = NULL; @@ -708,6 +760,48 @@ static DDS_Security_ValidationResult_t get_rsa_dh_parameters(EVP_PKEY **params, return DDS_SECURITY_VALIDATION_OK; } +#else + +static DDS_Security_ValidationResult_t get_rsa_dh_parameters(EVP_PKEY **params, DDS_Security_SecurityException *ex) +{ + DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; + OSSL_PARAM pkey_params[2]; + EVP_PKEY_CTX *pctx = NULL; + char group_name[] = "dh_2048_256"; + + *params = NULL; + + pkey_params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0); + pkey_params[1] = OSSL_PARAM_construct_end(); + + if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "DHX", NULL)) == NULL) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EVP_PKEY_CTX_new_from_name(DHX) failed: "); + result = DDS_SECURITY_VALIDATION_FAILED; + } + else if (EVP_PKEY_keygen_init(pctx) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EVP_PKEY_keygen_init(DHX) failed: "); + result = DDS_SECURITY_VALIDATION_FAILED; + } + else if (EVP_PKEY_CTX_set_params(pctx, pkey_params) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EVP_PKEY_CTX_set_params(DHX) failed: "); + result = DDS_SECURITY_VALIDATION_FAILED; + } + else if (EVP_PKEY_keygen(pctx, params) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EVP_PKEY_keygen(DHX) failed: "); + result = DDS_SECURITY_VALIDATION_FAILED; + } + + EVP_PKEY_CTX_free(pctx); + return result; +} + +#endif + + static DDS_Security_ValidationResult_t get_ec_dh_parameters(EVP_PKEY **params, DDS_Security_SecurityException *ex) { EVP_PKEY_CTX *pctx = NULL; @@ -788,6 +882,9 @@ DDS_Security_ValidationResult_t generate_dh_keys(EVP_PKEY **dhkey, Authenticatio return DDS_SECURITY_VALIDATION_FAILED; } + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + static const BIGNUM *dh_get_public_key(DH *dhkey) { #ifdef AUTH_INCLUDE_DH_ACCESSORS @@ -811,6 +908,7 @@ static int dh_set_public_key(DH *dhkey, BIGNUM *pubkey) static DDS_Security_ValidationResult_t dh_public_key_to_oct_modp(EVP_PKEY *pkey, unsigned char **buffer, uint32_t *length, DDS_Security_SecurityException *ex) { + DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_FAILED; DH *dhkey; ASN1_INTEGER *asn1int; *buffer = NULL; @@ -822,31 +920,32 @@ static DDS_Security_ValidationResult_t dh_public_key_to_oct_modp(EVP_PKEY *pkey, if (!(asn1int = BN_to_ASN1_INTEGER (dh_get_public_key(dhkey), NULL))) { DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to convert DH key to ASN1 integer: "); - DH_free(dhkey); - return DDS_SECURITY_VALIDATION_FAILED; + goto failed_asn1int; } int i2dlen = i2d_ASN1_INTEGER (asn1int, NULL); if (i2dlen <= 0) { DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to convert DH key to ASN1 integer: "); - DH_free(dhkey); - return DDS_SECURITY_VALIDATION_FAILED; + goto failed_i2d; } *length = (uint32_t) i2dlen; if ((*buffer = ddsrt_malloc (*length)) == NULL) { DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to convert DH key to ASN1 integer: "); - DH_free(dhkey); - return DDS_SECURITY_VALIDATION_FAILED; + goto failed_i2d; } unsigned char *buffer_arg = *buffer; (void) i2d_ASN1_INTEGER (asn1int, &buffer_arg); + result = DDS_SECURITY_VALIDATION_OK; + +failed_i2d: ASN1_INTEGER_free (asn1int); +failed_asn1int: DH_free (dhkey); - return DDS_SECURITY_VALIDATION_OK; + return result; } static DDS_Security_ValidationResult_t dh_public_key_to_oct_ecdh(EVP_PKEY *pkey, unsigned char **buffer, uint32_t *length, DDS_Security_SecurityException *ex) @@ -892,24 +991,6 @@ static DDS_Security_ValidationResult_t dh_public_key_to_oct_ecdh(EVP_PKEY *pkey, return DDS_SECURITY_VALIDATION_FAILED; } -DDS_Security_ValidationResult_t dh_public_key_to_oct(EVP_PKEY *pkey, AuthenticationAlgoKind_t algo, unsigned char **buffer, uint32_t *length, DDS_Security_SecurityException *ex) -{ - assert(pkey); - assert(buffer); - assert(length); - switch (algo) - { - case AUTH_ALGO_KIND_RSA_2048: - return dh_public_key_to_oct_modp(pkey, buffer, length, ex); - case AUTH_ALGO_KIND_EC_PRIME256V1: - return dh_public_key_to_oct_ecdh(pkey, buffer, length, ex); - default: - assert(0); - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Invalid key algorithm specified"); - return DDS_SECURITY_VALIDATION_FAILED; - } -} - static DDS_Security_ValidationResult_t dh_oct_to_public_key_modp(EVP_PKEY **pkey, const unsigned char *keystr, uint32_t size, DDS_Security_SecurityException *ex) { DH *dhkey; @@ -961,6 +1042,7 @@ static DDS_Security_ValidationResult_t dh_oct_to_public_key_ecdh(EVP_PKEY **pkey EC_KEY *eckey; EC_GROUP *group; EC_POINT *point; + if (!(group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1))) { DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to allocate EC group: "); @@ -1020,6 +1102,167 @@ static DDS_Security_ValidationResult_t dh_oct_to_public_key_ecdh(EVP_PKEY **pkey return DDS_SECURITY_VALIDATION_FAILED; } +#else + +static DDS_Security_ValidationResult_t dh_public_key_to_oct_modp(EVP_PKEY *pkey, unsigned char **buffer, uint32_t *length, DDS_Security_SecurityException *ex) +{ + DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_FAILED; + BIGNUM *pubkey = NULL; + ASN1_INTEGER *asn1int = NULL; + int len; + + *buffer = NULL; + + if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &pubkey) != 1) { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to get DH key from PKEY: "); + goto fail_pubkey; + } + if ((asn1int = BN_to_ASN1_INTEGER(pubkey, NULL)) == NULL) { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to convert DH key to ASN1 integer: "); + goto fail_asn1int; + } + if ((len = i2d_ASN1_INTEGER(asn1int, buffer)) < 0) { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to convert ASN1 integer to DER format: "); + goto fail_to_der; + } + *length = (uint32_t) len; + result = DDS_SECURITY_VALIDATION_OK; + +fail_to_der: + ASN1_INTEGER_free(asn1int); +fail_asn1int: + BN_free(pubkey); +fail_pubkey: + return result; +} + +static DDS_Security_ValidationResult_t dh_public_key_to_oct_ecdh(EVP_PKEY *pkey, unsigned char **buffer, uint32_t *length, DDS_Security_SecurityException *ex) +{ + size_t size; + if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &size) != 1) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to get length of encoded public key: "); + return DDS_SECURITY_VALIDATION_FAILED; + } + *buffer = ddsrt_malloc(size); + if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, *buffer, size, NULL) != 1) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to get encoded public key: "); + ddsrt_free(*buffer); + return DDS_SECURITY_VALIDATION_FAILED; + } + *length = (uint32_t)size; + return DDS_SECURITY_VALIDATION_OK; +} + +static DDS_Security_ValidationResult_t dh_oct_to_public_key_modp(EVP_PKEY **pkey, const unsigned char *keystr, uint32_t size, DDS_Security_SecurityException *ex) +{ + DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; + ASN1_INTEGER *asn1int = NULL; + BIGNUM *pubkey = NULL; + EVP_PKEY_CTX *pctx = NULL; + char group_name[] = "dh_2048_256"; + int keylen = 0; + unsigned char *buffer = NULL; + uint32_t buflen = 0; + OSSL_PARAM params[3]; + + if ((asn1int = d2i_ASN1_INTEGER(NULL, &keystr, size)) == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to convert key string to ASN1 integer: "); + return DDS_SECURITY_VALIDATION_FAILED; + } + if ((pubkey = ASN1_INTEGER_to_BN(asn1int, NULL)) == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to convert ASN1 integer to BIGNUM: "); + ASN1_INTEGER_free(asn1int); + return DDS_SECURITY_VALIDATION_FAILED; + } + + keylen = BN_num_bytes(pubkey) + 1; + buffer = ddsrt_malloc((size_t)keylen); + buflen = (uint32_t)BN_bn2nativepad(pubkey, buffer, keylen); + + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0); + params[1] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_PUB_KEY, buffer, buflen); + params[2] = OSSL_PARAM_construct_end(); + + if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "DHX", NULL)) == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EVP_PKEY_CTX_new_from_name(DHX) failed: "); + result = DDS_SECURITY_VALIDATION_FAILED; + } + else if (EVP_PKEY_fromdata_init(pctx) != 1) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EVP_PKEY_fromdata_init(DHX) failed: "); + result = DDS_SECURITY_VALIDATION_FAILED; + } + else if (EVP_PKEY_fromdata(pctx, pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EVP_PKEY_fromdata(DHX) failed: "); + result = DDS_SECURITY_VALIDATION_FAILED; + } + + EVP_PKEY_CTX_free(pctx); + ddsrt_free(buffer); + BN_free(pubkey); + ASN1_INTEGER_free(asn1int); + + return result; +} + +static DDS_Security_ValidationResult_t dh_oct_to_public_key_ecdh(EVP_PKEY **pkey, const unsigned char *keystr, uint32_t size, DDS_Security_SecurityException *ex) +{ + DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM params[3]; + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, SN_X9_62_prime256v1, 0); + params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY, (void *)keystr, size); + params[2] = OSSL_PARAM_construct_end(); + + if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EVP_PKEY_CTX_new_from_name(EC) failed: "); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (EVP_PKEY_fromdata_init(ctx) != 1) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EVP_PKEY_fromdata_init(EC) failed: "); + result = DDS_SECURITY_VALIDATION_FAILED; + goto failed; + } + if (EVP_PKEY_fromdata(ctx, pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EVP_PKEY_fromdata(EC) failed: "); + result = DDS_SECURITY_VALIDATION_FAILED; + goto failed; + } + +failed: + EVP_PKEY_CTX_free(ctx); + return result; +} + +#endif + +DDS_Security_ValidationResult_t dh_public_key_to_oct(EVP_PKEY *pkey, AuthenticationAlgoKind_t algo, unsigned char **buffer, uint32_t *length, DDS_Security_SecurityException *ex) +{ + assert(pkey); + assert(buffer); + assert(length); + switch (algo) + { + case AUTH_ALGO_KIND_RSA_2048: + return dh_public_key_to_oct_modp(pkey, buffer, length, ex); + case AUTH_ALGO_KIND_EC_PRIME256V1: + return dh_public_key_to_oct_ecdh(pkey, buffer, length, ex); + default: + assert(0); + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Invalid key algorithm specified"); + return DDS_SECURITY_VALIDATION_FAILED; + } +} + DDS_Security_ValidationResult_t dh_oct_to_public_key(EVP_PKEY **data, AuthenticationAlgoKind_t algo, const unsigned char *str, uint32_t size, DDS_Security_SecurityException *ex) { assert(data); diff --git a/src/security/builtin_plugins/tests/common/src/handshake_helper.c b/src/security/builtin_plugins/tests/common/src/handshake_helper.c index 9429a4151d..8e4ee733a9 100644 --- a/src/security/builtin_plugins/tests/common/src/handshake_helper.c +++ b/src/security/builtin_plugins/tests/common/src/handshake_helper.c @@ -24,7 +24,29 @@ #include "CUnit/Test.h" #include "handshake_helper.h" -const BIGNUM * + +void +octet_seq_init( + struct octet_seq *seq, + unsigned char *data, + uint32_t size) +{ + seq->data = ddsrt_malloc(size); + memcpy(seq->data, data, size); + seq->length = size; +} + +void +octet_seq_deinit( + struct octet_seq *seq) +{ + ddsrt_free(seq->data); +} + + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + +static const BIGNUM * dh_get_public_key( DH *dhkey) { @@ -37,7 +59,7 @@ dh_get_public_key( #endif } -int +static int dh_set_public_key( DH *dhkey, BIGNUM *pubkey) @@ -50,6 +72,622 @@ dh_set_public_key( return 1; } +ASN1_INTEGER * +get_pubkey_asn1int(EVP_PKEY *pkey) +{ + ASN1_INTEGER *result; + DH *dhkey = EVP_PKEY_get1_DH(pkey); + if (!dhkey) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to get DH key from PKEY: %s", msg); + ddsrt_free(msg); + return NULL; + } + result = BN_to_ASN1_INTEGER(dh_get_public_key(dhkey), NULL); + DH_free(dhkey); + return result; +} + +int +get_dh_public_key_modp_2048( + EVP_PKEY *pkey, + struct octet_seq *pubkey) +{ + int r = 0; + DH *dhkey; + unsigned char *buffer = NULL; + uint32_t size; + ASN1_INTEGER *asn1int; + + dhkey = EVP_PKEY_get1_DH(pkey); + if (!dhkey) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to get DH key from PKEY: %s", msg); + ddsrt_free(msg); + r = -1; + goto fail_get_dhkey; + } + + asn1int = BN_to_ASN1_INTEGER( dh_get_public_key(dhkey) , NULL); + if (!asn1int) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to convert DH key to ASN1 integer: %s", msg); + ddsrt_free(msg); + r = -1; + goto fail_get_pubkey; + } + + size = (uint32_t)i2d_ASN1_INTEGER(asn1int, &buffer); + octet_seq_init(pubkey, buffer, size); + + ASN1_INTEGER_free(asn1int); + OPENSSL_free(buffer); + +fail_get_pubkey: + DH_free(dhkey); +fail_get_dhkey: + return r; +} + +int +get_dh_public_key_ecdh( + EVP_PKEY *pkey, + struct octet_seq *pubkey) +{ + int r = 0; + EC_KEY *eckey = NULL; + const EC_GROUP *group = NULL; + const EC_POINT *point = NULL; + size_t sz; + + if (!(eckey = EVP_PKEY_get1_EC_KEY(pkey))) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to get EC key from PKEY: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (!(point = EC_KEY_get0_public_key(eckey))) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to get public key from ECKEY: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (!(group = EC_KEY_get0_group(eckey))) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to get group from ECKEY: %s", msg); + ddsrt_free(msg); + r = -1; + } else if ((sz = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL)) != 0) { + pubkey->data = ddsrt_malloc(sz); + pubkey->length = (uint32_t) EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, pubkey->data, sz, NULL); + if (pubkey->length == 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to serialize public EC key: %s", msg); + ddsrt_free(msg); + octet_seq_deinit(pubkey); + r = -1; + } + } else { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to serialize public EC key: %s", msg); + ddsrt_free(msg); + r = -1; + } + + if (eckey) EC_KEY_free(eckey); + + return r; +} + +static EVP_PKEY * +modp_data_to_pubkey( + const unsigned char *data, + uint32_t size) +{ + EVP_PKEY *pkey= NULL; + DH *dhkey = NULL; + ASN1_INTEGER *asni; + BIGNUM *bn = NULL; + + if (!(asni = d2i_ASN1_INTEGER(NULL, &data, (long)size))) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to decode DH public key: %s", msg); + ddsrt_free(msg); + goto fail_asni; + } + + if (!(bn = ASN1_INTEGER_to_BN(asni, NULL))) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to convert to BIGNU<: %s", msg); + ddsrt_free(msg); + goto fail_bn; + } + + if (!(dhkey = DH_get_2048_256())) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate dhkey: %s", msg); + ddsrt_free(msg); + goto fail_dhkey; + } + + dh_set_public_key(dhkey,bn); + + if (!(pkey = EVP_PKEY_new())) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate pkey: %s", msg); + ddsrt_free(msg); + goto fail_pkey; + } + + if (!EVP_PKEY_set1_DH(pkey, dhkey)) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to set public key: %s", msg); + ddsrt_free(msg); + EVP_PKEY_free(pkey); + pkey = NULL; + } + + ASN1_INTEGER_free(asni); + DH_free(dhkey); + + return pkey; + +fail_pkey: + DH_free(dhkey); +fail_dhkey: + BN_free(bn); +fail_bn: + ASN1_INTEGER_free(asni); +fail_asni: + return NULL; +} + +static EVP_PKEY * +ecdh_data_to_pubkey( + const unsigned char *data, + uint32_t size) +{ + EVP_PKEY *pkey = NULL; + EC_KEY *eckey = NULL; + EC_GROUP *group = NULL; + EC_POINT *point = NULL; + + if (!(group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1))) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate EC group: %s", msg); + ddsrt_free(msg); + } else if (!(point = EC_POINT_new(group))) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate EC point: %s", msg); + ddsrt_free(msg); + } else if (EC_POINT_oct2point(group, point, data, size, NULL) != 1) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to deserialize EC public key to EC point: %s", msg); + ddsrt_free(msg); + } else if (!(eckey = EC_KEY_new())) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate EC KEY: %s", msg); + ddsrt_free(msg); + } else if (EC_KEY_set_group(eckey, group) != 1) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to convert octet sequence to ASN1 integer: %s", msg); + ddsrt_free(msg); + } else if (EC_KEY_set_public_key(eckey, point) != 1) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to set EC public key: %s", msg); + ddsrt_free(msg); + } else if (!(pkey = EVP_PKEY_new())) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate EVP key: %s", msg); + ddsrt_free(msg); + } else if (EVP_PKEY_set1_EC_KEY(pkey, eckey) != 1) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to set EVP key to EC public key: %s", msg); + ddsrt_free(msg); + EVP_PKEY_free(pkey); + pkey = NULL; + } + + if (eckey) EC_KEY_free(eckey); + if (point) EC_POINT_free(point); + if (group) EC_GROUP_free(group); + + return pkey; +} + +int +create_dh_key_modp_2048( + EVP_PKEY **pkey) +{ + int r = 0; + EVP_PKEY *params = NULL; + EVP_PKEY_CTX *kctx = NULL; + DH *dh = NULL; + + *pkey = NULL; + + if ((params = EVP_PKEY_new()) == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate EVP_PKEY: %s", msg); + ddsrt_free(msg); + r = -1; + } else if ((dh = DH_get_2048_256()) == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate DH parameter: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_set1_DH(params, dh) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to set DH parameter to MODP_2048_256: %s", msg); + ddsrt_free(msg); + r = -1; + } else if ((kctx = EVP_PKEY_CTX_new(params, NULL)) == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate KEY context %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_keygen_init(kctx) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to initialize KEY context: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_keygen(kctx, pkey) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to generate :MODP_2048_256 keys %s", msg); + ddsrt_free(msg); + r = -1; + } + + if (params) EVP_PKEY_free(params); + if (kctx) EVP_PKEY_CTX_free(kctx); + if (dh) DH_free(dh); + + return r; +} + +int +create_dh_key_ecdh( + EVP_PKEY **pkey) +{ + int r = 0; + EVP_PKEY *params = NULL; + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY_CTX *kctx = NULL; + + *pkey = NULL; + + if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate DH parameter context: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_paramgen_init(pctx) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to initialize DH generation context: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to set DH generation parameter generation method: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_paramgen(pctx, ¶ms) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to generate DH parameters: %s", msg); + ddsrt_free(msg); + r = -1; + } else if ((kctx = EVP_PKEY_CTX_new(params, NULL)) == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate KEY context %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_keygen_init(kctx) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to initialize KEY context: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_keygen(kctx, pkey) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to generate :MODP_2048_256 keys %s", msg); + ddsrt_free(msg); + r = -1; + } + + if (kctx) EVP_PKEY_CTX_free(kctx); + if (params) EVP_PKEY_free(params); + if (pctx) EVP_PKEY_CTX_free(pctx); + + return r; +} + + +#else + +ASN1_INTEGER * +get_pubkey_asn1int(EVP_PKEY *pkey) +{ + BIGNUM *pubkey_bn = NULL; + ASN1_INTEGER *asn1int = NULL; + + if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &pubkey_bn) != 1) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to get DH key from PKEY: %s", msg); + ddsrt_free(msg); + return NULL; + } + asn1int = BN_to_ASN1_INTEGER(pubkey_bn, NULL); + BN_free(pubkey_bn); + return asn1int; +} + +int +get_dh_public_key_modp_2048( + EVP_PKEY *pkey, + struct octet_seq *pubkey) +{ + int r = -1; + BIGNUM *pubkbn = NULL; + ASN1_INTEGER *asn1int = NULL; + unsigned char *buffer = NULL; + int size = 0; + + if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &pubkbn) != 1) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to get DH key from PKEY: %s", msg); + ddsrt_free(msg); + goto fail_get_pubkey; + } + + asn1int = BN_to_ASN1_INTEGER(pubkbn, NULL); + if (asn1int == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to convert bignum to ASN.1 integer: %s", msg); + ddsrt_free(msg); + goto fail_pubkey_to_asn1int; + } + + size = i2d_ASN1_INTEGER(asn1int, &buffer); + if (size < 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to convert ASN.1 integer to der: %s", msg); + ddsrt_free(msg); + goto fail_asn1int_to_der; + } + + octet_seq_init(pubkey, buffer, (uint32_t)size); + OPENSSL_free(buffer); + r = 0; + +fail_asn1int_to_der: + ASN1_INTEGER_free(asn1int); +fail_pubkey_to_asn1int: + BN_free(pubkbn); +fail_get_pubkey: + return r; +} + +int +get_dh_public_key_ecdh( + EVP_PKEY *pkey, + struct octet_seq *pubkey) +{ + unsigned char *keyval = NULL; + size_t size; + + if (!EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY , NULL, 0, &size)) + { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to get size of encoded public key: %s", msg); + ddsrt_free(msg); + return -1; + } + keyval = ddsrt_malloc(size); + if (!EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, keyval, size, NULL)) + { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to get size of encoded public key: %s", msg); + ddsrt_free(msg); + ddsrt_free(keyval); + return -1; + } + + octet_seq_init(pubkey, keyval, (uint32_t)size); + ddsrt_free(keyval); + + return 0; +} + +static EVP_PKEY * +modp_data_to_pubkey( + const unsigned char *data, + uint32_t size) +{ + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *pctx = NULL; + ASN1_INTEGER *asn1int = NULL; + BIGNUM *pubkey = NULL; + unsigned char *buffer; + int bufsize; + OSSL_PARAM params[3]; + size_t keysize; + char group_name[] = "dh_2048_256"; + + if (!(asn1int = d2i_ASN1_INTEGER(NULL, &data, size))) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to decode DH public key: %s", msg); + ddsrt_free(msg); + goto fail_asni; + } + + if (!(pubkey = ASN1_INTEGER_to_BN(asn1int, NULL))) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to convert to BIGNUN: %s", msg); + ddsrt_free(msg); + goto fail_pubkey; + } + + bufsize = BN_num_bytes(pubkey) + 1; + buffer = ddsrt_malloc((size_t)bufsize); + keysize = (size_t)BN_bn2nativepad(pubkey, buffer, bufsize); + + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0); + params[1] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_PUB_KEY, buffer, keysize); + params[2] = OSSL_PARAM_construct_end(); + + pctx = EVP_PKEY_CTX_new_from_name(NULL, "DHX", NULL); + if (pctx == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("EVP_PKEY_CTX_new_from_name(DHX) failed: %s", msg); + ddsrt_free(msg); + goto fail_ctx; + } + + if (EVP_PKEY_fromdata_init(pctx) != 1) { + char *msg = get_openssl_error_message_for_test(); + printf("EVP_PKEY_fromdata_init(DHX) failed: %s", msg); + ddsrt_free(msg); + goto fail_key_init; + } + + if (EVP_PKEY_fromdata(pctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { + char *msg = get_openssl_error_message_for_test(); + printf("EVP_PKEY_fromdata(DHX) failed: %s", msg); + ddsrt_free(msg); + goto fail_key_init; + } + +fail_key_init: + EVP_PKEY_CTX_free(pctx); +fail_ctx: + BN_free(pubkey); + ddsrt_free(buffer); +fail_pubkey: + ASN1_INTEGER_free(asn1int); +fail_asni: + return pkey; +} + +static EVP_PKEY * +ecdh_data_to_pubkey( + const unsigned char *data, + uint32_t size) +{ + EVP_PKEY_CTX *ctx; + EVP_PKEY *pkey = NULL; + + OSSL_PARAM params[3]; + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, SN_X9_62_prime256v1, 0); + params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY, (void *)data, size); + params[2] = OSSL_PARAM_construct_end(); + + ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); + if (ctx == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("EVP_PKEY_CTX_new_from_name(EC) failed: %s", msg); + ddsrt_free(msg); + goto fail_ctx; + } + + if (EVP_PKEY_fromdata_init(ctx) != 1) { + char *msg = get_openssl_error_message_for_test(); + printf("EVP_PKEY_fromdata_init(EC) failed: %s", msg); + ddsrt_free(msg); + goto fail_init; + } + + if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { + char *msg = get_openssl_error_message_for_test(); + printf("EVP_PKEY_fromdata(EC) failed: %s", msg); + ddsrt_free(msg); + } + +fail_init: + EVP_PKEY_CTX_free(ctx); +fail_ctx: + return pkey; +} + +int +create_dh_key_modp_2048( + EVP_PKEY **pkey) +{ + int r = 0; + EVP_PKEY_CTX *pctx = NULL; + OSSL_PARAM pkey_params[2]; + char group_name[] = "dh_2048_256"; + + *pkey = NULL; + + pkey_params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0); + pkey_params[1] = OSSL_PARAM_construct_end(); + + if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "DHX", NULL)) == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("EVP_PKEY_CTX_new_from_name(DHX) failed: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_keygen_init(pctx) != 1) { + char *msg = get_openssl_error_message_for_test(); + printf("EVP_PKEY_keygen_init(DHX, %s) failed: %s", group_name, msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_CTX_set_params(pctx, pkey_params) != 1) { + char *msg = get_openssl_error_message_for_test(); + printf("EVP_PKEY_CTX_set_params(DHX) failed: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_keygen(pctx, pkey) != 1) { + char *msg = get_openssl_error_message_for_test(); + printf("EVP_PKEY_CTX_set_params(DHX) failed: %s", msg); + ddsrt_free(msg); + r = -1; + } + + if (pctx) EVP_PKEY_CTX_free(pctx); + return r; +} + +int +create_dh_key_ecdh( + EVP_PKEY **pkey) +{ + int r = 0; + EVP_PKEY_CTX *pctx = NULL; + OSSL_PARAM pkey_params[3]; + char group_name[] = "prime256v1"; + + *pkey = NULL; + + pkey_params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0); + pkey_params[1] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_COMPRESSED, 0); + pkey_params[2] = OSSL_PARAM_construct_end(); + + if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("EVP_PKEY_CTX_new_from_name(ECDH) failed: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (!EVP_PKEY_keygen_init(pctx)) { + char *msg = get_openssl_error_message_for_test(); + printf("EVP_PKEY_keygen_init(ECDH, %s) failed: %s", group_name, msg); + ddsrt_free(msg); + r = -1; + } else if (!EVP_PKEY_CTX_set_params(pctx, pkey_params)) { + char *msg = get_openssl_error_message_for_test(); + printf("EVP_PKEY_CTX_set_params(ECDH) failed: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (!EVP_PKEY_keygen(pctx, pkey)) { + char *msg = get_openssl_error_message_for_test(); + printf("EVP_PKEY_CTX_set_params(ECDH) failed: %s", msg); + ddsrt_free(msg); + r = -1; + } + + if (pctx) EVP_PKEY_CTX_free(pctx); + return r; +} + +#endif + /* for DEBUG purposes */ void print_binary_test( char* name, unsigned char *value, uint32_t size){ @@ -285,122 +923,6 @@ get_public_key( return result; } -static EVP_PKEY * -modp_data_to_pubkey( - const unsigned char *data, - uint32_t size) -{ - EVP_PKEY *pkey= NULL; - DH *dhkey = NULL; - ASN1_INTEGER *asni; - BIGNUM *bn = NULL; - - if (!(asni = d2i_ASN1_INTEGER(NULL, &data, (long)size))) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to decode DH public key: %s", msg); - ddsrt_free(msg); - goto fail_asni; - } - - if (!(bn = ASN1_INTEGER_to_BN(asni, NULL))) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to convert to BIGNU<: %s", msg); - ddsrt_free(msg); - goto fail_bn; - } - - if (!(dhkey = DH_get_2048_256())) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate dhkey: %s", msg); - ddsrt_free(msg); - goto fail_dhkey; - } - - dh_set_public_key(dhkey,bn); - - if (!(pkey = EVP_PKEY_new())) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate pkey: %s", msg); - ddsrt_free(msg); - goto fail_pkey; - } - - if (!EVP_PKEY_set1_DH(pkey, dhkey)) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to set public key: %s", msg); - ddsrt_free(msg); - EVP_PKEY_free(pkey); - pkey = NULL; - } - - ASN1_INTEGER_free(asni); - DH_free(dhkey); - - return pkey; - -fail_pkey: - DH_free(dhkey); -fail_dhkey: - BN_free(bn); -fail_bn: - ASN1_INTEGER_free(asni); -fail_asni: - return NULL; -} - -static EVP_PKEY * -ecdh_data_to_pubkey( - const unsigned char *data, - uint32_t size) -{ - EVP_PKEY *pkey = NULL; - EC_KEY *eckey = NULL; - EC_GROUP *group = NULL; - EC_POINT *point = NULL; - - if (!(group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1))) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate EC group: %s", msg); - ddsrt_free(msg); - } else if (!(point = EC_POINT_new(group))) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate EC point: %s", msg); - ddsrt_free(msg); - } else if (EC_POINT_oct2point(group, point, data, size, NULL) != 1) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to deserialize EC public key to EC point: %s", msg); - ddsrt_free(msg); - } else if (!(eckey = EC_KEY_new())) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate EC KEY: %s", msg); - ddsrt_free(msg); - } else if (EC_KEY_set_group(eckey, group) != 1) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to convert octet sequence to ASN1 integer: %s", msg); - ddsrt_free(msg); - } else if (EC_KEY_set_public_key(eckey, point) != 1) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to set EC public key: %s", msg); - ddsrt_free(msg); - } else if (!(pkey = EVP_PKEY_new())) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate EVP key: %s", msg); - ddsrt_free(msg); - } else if (EVP_PKEY_set1_EC_KEY(pkey, eckey) != 1) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to set EVP key to EC public key: %s", msg); - ddsrt_free(msg); - EVP_PKEY_free(pkey); - pkey = NULL; - } - - if (eckey) EC_KEY_free(eckey); - if (point) EC_POINT_free(point); - if (group) EC_GROUP_free(group); - - return pkey; -} - int check_shared_secret( dds_security_authentication *auth, @@ -557,9 +1079,9 @@ create_asymmetrical_signature_for_test( ddsrt_free(*signature); } - err_sign: +err_sign: EVP_MD_CTX_destroy(mdctx); - err_create_ctx: +err_create_ctx: return result; } diff --git a/src/security/builtin_plugins/tests/common/src/handshake_helper.h b/src/security/builtin_plugins/tests/common/src/handshake_helper.h index 7c82ecd092..0deb4e28ed 100644 --- a/src/security/builtin_plugins/tests/common/src/handshake_helper.h +++ b/src/security/builtin_plugins/tests/common/src/handshake_helper.h @@ -15,14 +15,41 @@ #include "dds/security/core/dds_security_serialize.h" #include "dds/security/openssl_support.h" -const BIGNUM * -dh_get_public_key( - DH *dhkey); +struct octet_seq { + unsigned char *data; + uint32_t length; +}; + +void +octet_seq_init( + struct octet_seq *seq, + unsigned char *data, + uint32_t size); + +void +octet_seq_deinit( + struct octet_seq *seq); + +ASN1_INTEGER * +get_pubkey_asn1int(EVP_PKEY *pkey); + +int +get_dh_public_key_modp_2048( + EVP_PKEY *pkey, + struct octet_seq *pubkey); + +int +get_dh_public_key_ecdh( + EVP_PKEY *pkey, + struct octet_seq *pubkey); + +int +create_dh_key_modp_2048( + EVP_PKEY **pkey); int -dh_set_public_key( - DH *dhkey, - BIGNUM *pubkey); +create_dh_key_ecdh( + EVP_PKEY **pkey); DDS_Security_ValidationResult_t create_signature_for_test( diff --git a/src/security/builtin_plugins/tests/get_authenticated_peer_credential_token/src/get_authenticated_peer_credential_token_utests.c b/src/security/builtin_plugins/tests/get_authenticated_peer_credential_token/src/get_authenticated_peer_credential_token_utests.c index 08a414da4b..f905df39fa 100644 --- a/src/security/builtin_plugins/tests/get_authenticated_peer_credential_token/src/get_authenticated_peer_credential_token_utests.c +++ b/src/security/builtin_plugins/tests/get_authenticated_peer_credential_token/src/get_authenticated_peer_credential_token_utests.c @@ -48,11 +48,6 @@ typedef enum { } HandshakeStep_t; -struct octet_seq { - unsigned char *data; - uint32_t length; -}; - static const char * AUTH_DSIGN_ALGO_RSA_NAME = "RSASSA-PSS-SHA256"; static const char * AUTH_KAGREE_ALGO_RSA_NAME = "DH+MODP-2048-256"; static const char * AUTH_KAGREE_ALGO_ECDH_NAME = "ECDH+prime256v1-CEUM"; @@ -219,25 +214,6 @@ static EVP_PKEY *g_dh_ecdh_key = NULL; static struct octet_seq g_dh_modp_pub_key = {NULL, 0}; static struct octet_seq g_dh_ecdh_pub_key = {NULL, 0}; - -static void -octet_seq_init( - struct octet_seq *seq, - unsigned char *data, - uint32_t size) -{ - seq->data = ddsrt_malloc(size); - memcpy(seq->data, data, size); - seq->length = size; -} - -static void -octet_seq_deinit( - struct octet_seq *seq) -{ - ddsrt_free(seq->data); -} - static void serializer_participant_data( DDS_Security_ParticipantBuiltinTopicData *pdata, @@ -541,199 +517,9 @@ get_adjusted_participant_guid( return result; } -static int -create_dh_key_modp_2048( - EVP_PKEY **pkey) -{ - int r = 0; - EVP_PKEY *params = NULL; - EVP_PKEY_CTX *kctx = NULL; - DH *dh = NULL; - - *pkey = NULL; - - if ((params = EVP_PKEY_new()) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate EVP_PKEY: %s", msg); - ddsrt_free(msg); - r = -1; - } else if ((dh = DH_get_2048_256()) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate DH parameter: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_set1_DH(params, dh) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to set DH parameter to MODP_2048_256: %s", msg); - ddsrt_free(msg); - r = -1; - } else if ((kctx = EVP_PKEY_CTX_new(params, NULL)) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate KEY context %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_keygen_init(kctx) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to initialize KEY context: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_keygen(kctx, pkey) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to generate :MODP_2048_256 keys %s", msg); - ddsrt_free(msg); - r = -1; - } - - if (params) EVP_PKEY_free(params); - if (kctx) EVP_PKEY_CTX_free(kctx); - if (dh) DH_free(dh); - - return r; -} -static int -get_dh_public_key_modp_2048( - EVP_PKEY *pkey, - struct octet_seq *pubkey) -{ - int r = 0; - DH *dhkey; - unsigned char *buffer = NULL; - uint32_t size; - ASN1_INTEGER *asn1int; - - dhkey = EVP_PKEY_get1_DH(pkey); - if (!dhkey) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to get DH key from PKEY: %s", msg); - ddsrt_free(msg); - r = -1; - goto fail_get_dhkey; - } - - asn1int = BN_to_ASN1_INTEGER( dh_get_public_key(dhkey) , NULL); - if (!asn1int) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to convert DH key to ASN1 integer: %s", msg); - ddsrt_free(msg); - r = -1; - goto fail_get_pubkey; - } - size = (uint32_t)i2d_ASN1_INTEGER(asn1int, &buffer); - octet_seq_init(pubkey, buffer, size); - ASN1_INTEGER_free(asn1int); - OPENSSL_free(buffer); - -fail_get_pubkey: - DH_free(dhkey); -fail_get_dhkey: - return r; -} - -static int -create_dh_key_ecdh( - EVP_PKEY **pkey) -{ - int r = 0; - EVP_PKEY *params = NULL; - EVP_PKEY_CTX *pctx = NULL; - EVP_PKEY_CTX *kctx = NULL; - - *pkey = NULL; - - if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate DH parameter context: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_paramgen_init(pctx) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to initialize DH generation context: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to set DH generation parameter generation method: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_paramgen(pctx, ¶ms) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to generate DH parameters: %s", msg); - ddsrt_free(msg); - r = -1; - } else if ((kctx = EVP_PKEY_CTX_new(params, NULL)) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate KEY context %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_keygen_init(kctx) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to initialize KEY context: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_keygen(kctx, pkey) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to generate :MODP_2048_256 keys %s", msg); - ddsrt_free(msg); - r = -1; - } - - if (kctx) EVP_PKEY_CTX_free(kctx); - if (params) EVP_PKEY_free(params); - if (pctx) EVP_PKEY_CTX_free(pctx); - - return r; -} - -static int -get_dh_public_key_ecdh( - EVP_PKEY *pkey, - struct octet_seq *pubkey) -{ - int r = 0; - EC_KEY *eckey = NULL; - const EC_GROUP *group = NULL; - const EC_POINT *point = NULL; - size_t sz; - - if (!(eckey = EVP_PKEY_get1_EC_KEY(pkey))) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to get EC key from PKEY: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (!(point = EC_KEY_get0_public_key(eckey))) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to get public key from ECKEY: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (!(group = EC_KEY_get0_group(eckey))) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to get group from ECKEY: %s", msg); - ddsrt_free(msg); - r = -1; - } else if ((sz = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL)) != 0) { - pubkey->data = ddsrt_malloc(sz); - pubkey->length = (uint32_t) EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, pubkey->data, sz, NULL); - if (pubkey->length == 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to serialize public EC key: %s", msg); - ddsrt_free(msg); - octet_seq_deinit(pubkey); - r = -1; - } - } else { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to serialize public EC key: %s", msg); - ddsrt_free(msg); - r = -1; - } - - if (eckey) EC_KEY_free(eckey); - - return r; -} static int validate_remote_identities (const char *remote_id_certificate) diff --git a/src/security/builtin_plugins/tests/listeners_authentication/src/listeners_authentication_utests.c b/src/security/builtin_plugins/tests/listeners_authentication/src/listeners_authentication_utests.c index 7c743e29e1..8d4179fb3e 100644 --- a/src/security/builtin_plugins/tests/listeners_authentication/src/listeners_authentication_utests.c +++ b/src/security/builtin_plugins/tests/listeners_authentication/src/listeners_authentication_utests.c @@ -31,6 +31,7 @@ #include "dds/security/openssl_support.h" #include "CUnit/CUnit.h" #include "CUnit/Test.h" +#include "common/src/handshake_helper.h" #include "common/src/loader.h" #include "config_env.h" #include "auth_tokens.h" @@ -188,12 +189,6 @@ typedef enum { HANDSHAKE_FINAL } HandshakeStep_t; - -struct octet_seq { - unsigned char *data; - uint32_t length; -}; - static struct plugins_hdl *plugins = NULL; static dds_security_authentication *auth = NULL; static dds_security_access_control *access_control = NULL; @@ -284,11 +279,11 @@ get_certificate_expiry( /*_In_*/ X509 *cert) { dds_time_t expiry = DDS_TIME_INVALID; - ASN1_TIME *ans1; + const ASN1_TIME *ans1; assert(cert); - ans1 = X509_get_notAfter(cert); + ans1 = X509_get0_notAfter(cert); if (ans1 != NULL) { int days; int seconds; @@ -459,12 +454,12 @@ static DDS_Security_boolean create_certificate_from_csr(const char* csr, long va /* ---------------------------------------------------------- * * Set X509V3 start date (now) and expiration date (+365 days)* * -----------------------------------------------------------*/ - if (!(X509_gmtime_adj(X509_get_notBefore(newcert), -10))) { + if (!(X509_gmtime_adj(X509_getm_notBefore(newcert), -10))) { BIO_printf(outbio, "Error setting start time\n"); return false; } - if (!(X509_gmtime_adj(X509_get_notAfter(newcert), valid_secs))) { + if (!(X509_gmtime_adj(X509_getm_notAfter(newcert), valid_secs))) { BIO_printf(outbio, "Error setting expiration time\n"); return false; } @@ -829,259 +824,6 @@ find_binary_property( return result; } - -static void -octet_seq_init( - struct octet_seq *seq, - unsigned char *data, - uint32_t size) -{ - seq->data = ddsrt_malloc(size); - memcpy(seq->data, data, size); - seq->length = size; -} - -static void -octet_seq_deinit( - struct octet_seq *seq) -{ - ddsrt_free(seq->data); -} -static char * -get_openssl_error_message_for_test( - void) -{ - BIO *bio = BIO_new(BIO_s_mem()); - char *msg; - char *buf = NULL; - size_t len; - - if (bio) { - ERR_print_errors(bio); - len = (uint32_t)BIO_get_mem_data (bio, &buf); - msg = ddsrt_malloc(len + 1); - memset(msg, 0, len+1); - memcpy(msg, buf, len); - BIO_free(bio); - } else { - msg = ddsrt_strdup("BIO_new failed"); - } - - return msg; -} - - -static const BIGNUM * -dh_get_public_key( - /*_In_ */DH *dhkey) -{ -#ifdef AUTH_INCLUDE_DH_ACCESSORS - const BIGNUM *pubkey, *privkey; - DH_get0_key(dhkey, &pubkey, &privkey); - return pubkey; -#else - return dhkey->pub_key; -#endif -} - - - -/* DH Helper Functions */ - -static int -create_dh_key_modp_2048( - EVP_PKEY **pkey) -{ - int r = 0; - EVP_PKEY *params = NULL; - EVP_PKEY_CTX *kctx = NULL; - DH *dh = NULL; - - *pkey = NULL; - - if ((params = EVP_PKEY_new()) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate EVP_PKEY: %s", msg); - ddsrt_free(msg); - r = -1; - } else if ((dh = DH_get_2048_256()) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate DH parameter: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_set1_DH(params, dh) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to set DH parameter to MODP_2048_256: %s", msg); - ddsrt_free(msg); - r = -1; - } else if ((kctx = EVP_PKEY_CTX_new(params, NULL)) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate KEY context %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_keygen_init(kctx) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to initialize KEY context: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_keygen(kctx, pkey) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to generate :MODP_2048_256 keys %s", msg); - ddsrt_free(msg); - r = -1; - } - - if (params) EVP_PKEY_free(params); - if (kctx) EVP_PKEY_CTX_free(kctx); - if (dh) DH_free(dh); - - return r; -} - -static int -get_dh_public_key_modp_2048( - EVP_PKEY *pkey, - struct octet_seq *pubkey) -{ - int r = 0; - DH *dhkey; - unsigned char *buffer = NULL; - uint32_t size; - ASN1_INTEGER *asn1int; - - dhkey = EVP_PKEY_get1_DH(pkey); - if (!dhkey) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to get DH key from PKEY: %s", msg); - ddsrt_free(msg); - r = -1; - goto fail_get_dhkey; - } - - asn1int = BN_to_ASN1_INTEGER( dh_get_public_key(dhkey) , NULL); - if (!asn1int) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to convert DH key to ASN1 integer: %s", msg); - ddsrt_free(msg); - r = -1; - goto fail_get_pubkey; - } - - size = (uint32_t)i2d_ASN1_INTEGER(asn1int, &buffer); - octet_seq_init(pubkey, buffer, size); - - ASN1_INTEGER_free(asn1int); - OPENSSL_free(buffer); - -fail_get_pubkey: - DH_free(dhkey); -fail_get_dhkey: - return r; -} - -static int -create_dh_key_ecdh( - EVP_PKEY **pkey) -{ - int r = 0; - EVP_PKEY *params = NULL; - EVP_PKEY_CTX *pctx = NULL; - EVP_PKEY_CTX *kctx = NULL; - - *pkey = NULL; - - if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate DH parameter context: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_paramgen_init(pctx) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to initialize DH generation context: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to set DH generation parameter generation method: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_paramgen(pctx, ¶ms) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to generate DH parameters: %s", msg); - ddsrt_free(msg); - r = -1; - } else if ((kctx = EVP_PKEY_CTX_new(params, NULL)) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate KEY context %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_keygen_init(kctx) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to initialize KEY context: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_keygen(kctx, pkey) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to generate :MODP_2048_256 keys %s", msg); - ddsrt_free(msg); - r = -1; - } - - if (kctx) EVP_PKEY_CTX_free(kctx); - if (params) EVP_PKEY_free(params); - if (pctx) EVP_PKEY_CTX_free(pctx); - - return r; -} - -static int -get_dh_public_key_ecdh( - EVP_PKEY *pkey, - struct octet_seq *pubkey) -{ - int r = 0; - EC_KEY *eckey = NULL; - const EC_GROUP *group = NULL; - const EC_POINT *point = NULL; - size_t sz; - - if (!(eckey = EVP_PKEY_get1_EC_KEY(pkey))) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to get EC key from PKEY: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (!(point = EC_KEY_get0_public_key(eckey))) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to get public key from ECKEY: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (!(group = EC_KEY_get0_group(eckey))) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to get group from ECKEY: %s", msg); - ddsrt_free(msg); - r = -1; - } else if ((sz = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL)) != 0) { - pubkey->data = ddsrt_malloc(sz); - pubkey->length = (uint32_t)EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, pubkey->data, sz, NULL); - if (pubkey->length == 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to serialize public EC key: %s", msg); - ddsrt_free(msg); - octet_seq_deinit(pubkey); - r = -1; - } - } else { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to serialize public EC key: %s", msg); - ddsrt_free(msg); - r = -1; - } - - if (eckey) EC_KEY_free(eckey); - - return r; -} - CU_Init(ddssec_builtin_listeners_auth) { int res = 0; @@ -1176,76 +918,6 @@ set_binary_property_string( set_binary_property_value(bp, name, (const unsigned char *)data, length); } - -static DDS_Security_ValidationResult_t -create_asymmetrical_signature_for_test( - EVP_PKEY *pkey, - void *data, - size_t dataLen, - unsigned char **signature, - size_t *signatureLen, - DDS_Security_SecurityException *ex) -{ - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - EVP_MD_CTX *mdctx = NULL; - EVP_PKEY_CTX *kctx = NULL; - - if (!(mdctx = EVP_MD_CTX_create())) { - char *msg = get_openssl_error_message_for_test(); - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, "Authentication", DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to create signing context: %s", msg); - ddsrt_free(msg); - goto err_create_ctx; - } - - if (EVP_DigestSignInit(mdctx, &kctx, EVP_sha256(), NULL, pkey) != 1) { - char *msg = get_openssl_error_message_for_test(); - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, "Authentication", DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to initialize signing context: %s", msg); - ddsrt_free(msg); - goto err_sign; - } - - if (EVP_PKEY_CTX_set_rsa_padding(kctx, RSA_PKCS1_PSS_PADDING) < 1) { - char *msg = get_openssl_error_message_for_test(); - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, "Authentication", DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to initialize signing context: %s", msg); - ddsrt_free(msg); - goto err_sign; - } - - if (EVP_DigestSignUpdate(mdctx, data, dataLen) != 1) { - char *msg = get_openssl_error_message_for_test(); - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, "Authentication", DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to update signing context: %s", msg); - ddsrt_free(msg); - goto err_sign; - } - - if (EVP_DigestSignFinal(mdctx, NULL, signatureLen) != 1) { - char *msg = get_openssl_error_message_for_test(); - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, "Authentication", DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to finalize signing context: %s", msg); - ddsrt_free(msg); - goto err_sign; - } - - *signature = ddsrt_malloc(*signatureLen); - if (EVP_DigestSignFinal(mdctx, *signature, signatureLen) != 1) { - char *msg = get_openssl_error_message_for_test(); - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, "Authentication", DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to finalize signing context: %s", msg); - ddsrt_free(msg); - ddsrt_free(*signature); - } - -err_sign: - EVP_MD_CTX_destroy(mdctx); -err_create_ctx: - return result; -} - - static X509 * load_certificate( const char *data) @@ -1305,34 +977,6 @@ get_adjusted_participant_guid( return result; } -static DDS_Security_ValidationResult_t -create_signature_for_test( - EVP_PKEY *pkey, - const DDS_Security_BinaryProperty_t **binary_properties, - const uint32_t binary_properties_length, - unsigned char **signature, - size_t *signatureLen, - DDS_Security_SecurityException *ex) -{ - DDS_Security_ValidationResult_t result; - DDS_Security_Serializer serializer; - unsigned char *buffer; - size_t size; - - serializer = DDS_Security_Serializer_new(4096, 4096); - - DDS_Security_Serialize_BinaryPropertyArray(serializer,binary_properties, binary_properties_length); - DDS_Security_Serializer_buffer(serializer, &buffer, &size); - - result = create_asymmetrical_signature_for_test(pkey, buffer, size, signature, signatureLen, ex); - - ddsrt_free(buffer); - DDS_Security_Serializer_free(serializer); - - return result; -} - - static void deinitialize_identity_token( DDS_Security_IdentityToken *token) @@ -1340,8 +984,6 @@ deinitialize_identity_token( DDS_Security_DataHolder_deinit(token); } - - static void fill_auth_request_token( DDS_Security_AuthRequestMessageToken *token) diff --git a/src/security/builtin_plugins/tests/process_handshake/src/process_handshake_utests.c b/src/security/builtin_plugins/tests/process_handshake/src/process_handshake_utests.c index 78976438b2..08a5f06ea3 100644 --- a/src/security/builtin_plugins/tests/process_handshake/src/process_handshake_utests.c +++ b/src/security/builtin_plugins/tests/process_handshake/src/process_handshake_utests.c @@ -46,17 +46,10 @@ typedef enum { } HandshakeStep_t; -struct octet_seq { - unsigned char *data; - uint32_t length; -}; - static const char * AUTH_DSIGN_ALGO_RSA_NAME = "RSASSA-PSS-SHA256"; static const char * AUTH_KAGREE_ALGO_RSA_NAME = "DH+MODP-2048-256"; static const char * AUTH_KAGREE_ALGO_ECDH_NAME = "ECDH+prime256v1-CEUM"; - - static const char *identity_certificate = "data:,-----BEGIN CERTIFICATE-----\n" "MIIDYDCCAkigAwIBAgIBBDANBgkqhkiG9w0BAQsFADByMQswCQYDVQQGEwJOTDEL\n" @@ -438,25 +431,6 @@ static struct octet_seq dh_modp_pub_key = {NULL, 0}; static struct octet_seq dh_ecdh_pub_key = {NULL, 0}; static struct octet_seq invalid_dh_pub_key = {NULL, 0}; - -static void -octet_seq_init( - struct octet_seq *seq, - unsigned char *data, - uint32_t size) -{ - seq->data = ddsrt_malloc(size); - memcpy(seq->data, data, size); - seq->length = size; -} - -static void -octet_seq_deinit( - struct octet_seq *seq) -{ - ddsrt_free(seq->data); -} - static void serializer_participant_data( DDS_Security_ParticipantBuiltinTopicData *pdata, @@ -770,200 +744,6 @@ get_adjusted_participant_guid( return result; } -static int -create_dh_key_modp_2048( - EVP_PKEY **pkey) -{ - int r = 0; - EVP_PKEY *params = NULL; - EVP_PKEY_CTX *kctx = NULL; - DH *dh = NULL; - - *pkey = NULL; - - if ((params = EVP_PKEY_new()) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate EVP_PKEY: %s", msg); - ddsrt_free(msg); - r = -1; - } else if ((dh = DH_get_2048_256()) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate DH parameter: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_set1_DH(params, dh) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to set DH parameter to MODP_2048_256: %s", msg); - ddsrt_free(msg); - r = -1; - } else if ((kctx = EVP_PKEY_CTX_new(params, NULL)) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate KEY context %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_keygen_init(kctx) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to initialize KEY context: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_keygen(kctx, pkey) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to generate :MODP_2048_256 keys %s", msg); - ddsrt_free(msg); - r = -1; - } - - if (params) EVP_PKEY_free(params); - if (kctx) EVP_PKEY_CTX_free(kctx); - if (dh) DH_free(dh); - - return r; -} - -static int -get_dh_public_key_modp_2048( - EVP_PKEY *pkey, - struct octet_seq *pubkey) -{ - int r = 0; - DH *dhkey; - unsigned char *buffer = NULL; - uint32_t size; - ASN1_INTEGER *asn1int; - - dhkey = EVP_PKEY_get1_DH(pkey); - if (!dhkey) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to get DH key from PKEY: %s", msg); - ddsrt_free(msg); - r = -1; - goto fail_get_dhkey; - } - - asn1int = BN_to_ASN1_INTEGER( dh_get_public_key(dhkey) , NULL); - if (!asn1int) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to convert DH key to ASN1 integer: %s", msg); - ddsrt_free(msg); - r = -1; - goto fail_get_pubkey; - } - - size = (uint32_t) i2d_ASN1_INTEGER(asn1int, &buffer); - octet_seq_init(pubkey, buffer, size); - - ASN1_INTEGER_free(asn1int); - OPENSSL_free(buffer); - -fail_get_pubkey: - DH_free(dhkey); -fail_get_dhkey: - return r; -} - -static int -create_dh_key_ecdh( - EVP_PKEY **pkey) -{ - int r = 0; - EVP_PKEY *params = NULL; - EVP_PKEY_CTX *pctx = NULL; - EVP_PKEY_CTX *kctx = NULL; - - *pkey = NULL; - - if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate DH parameter context: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_paramgen_init(pctx) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to initialize DH generation context: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to set DH generation parameter generation method: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_paramgen(pctx, ¶ms) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to generate DH parameters: %s", msg); - ddsrt_free(msg); - r = -1; - } else if ((kctx = EVP_PKEY_CTX_new(params, NULL)) == NULL) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to allocate KEY context %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_keygen_init(kctx) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to initialize KEY context: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (EVP_PKEY_keygen(kctx, pkey) <= 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to generate :MODP_2048_256 keys %s", msg); - ddsrt_free(msg); - r = -1; - } - - if (kctx) EVP_PKEY_CTX_free(kctx); - if (params) EVP_PKEY_free(params); - if (pctx) EVP_PKEY_CTX_free(pctx); - - return r; -} - -static int -get_dh_public_key_ecdh( - EVP_PKEY *pkey, - struct octet_seq *pubkey) -{ - int r = 0; - EC_KEY *eckey = NULL; - const EC_GROUP *group = NULL; - const EC_POINT *point = NULL; - size_t sz; - - if (!(eckey = EVP_PKEY_get1_EC_KEY(pkey))) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to get EC key from PKEY: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (!(point = EC_KEY_get0_public_key(eckey))) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to get public key from ECKEY: %s", msg); - ddsrt_free(msg); - r = -1; - } else if (!(group = EC_KEY_get0_group(eckey))) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to get group from ECKEY: %s", msg); - ddsrt_free(msg); - r = -1; - } else if ((sz = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL)) != 0) { - pubkey->data = ddsrt_malloc(sz); - pubkey->length = (uint32_t) EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, pubkey->data, sz, NULL); - if (pubkey->length == 0) { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to serialize public EC key: %s", msg); - ddsrt_free(msg); - octet_seq_deinit(pubkey); - r = -1; - } - } else { - char *msg = get_openssl_error_message_for_test(); - printf("Failed to serialize public EC key: %s", msg); - ddsrt_free(msg); - r = -1; - } - - if (eckey) EC_KEY_free(eckey); - - return r; -} - static int validate_remote_identities (const char *remote_id_certificate) { diff --git a/src/security/builtin_plugins/tests/validate_begin_handshake_reply/src/validate_begin_handshake_reply_utests.c b/src/security/builtin_plugins/tests/validate_begin_handshake_reply/src/validate_begin_handshake_reply_utests.c index 3e2de239e5..138c960e6e 100644 --- a/src/security/builtin_plugins/tests/validate_begin_handshake_reply/src/validate_begin_handshake_reply_utests.c +++ b/src/security/builtin_plugins/tests/validate_begin_handshake_reply/src/validate_begin_handshake_reply_utests.c @@ -22,6 +22,7 @@ #include "dds/security/openssl_support.h" #include "CUnit/CUnit.h" #include "CUnit/Test.h" +#include "common/src/handshake_helper.h" #include "common/src/loader.h" #include "config_env.h" #include "auth_tokens.h" @@ -342,21 +343,6 @@ static bool future_challenge_done = false; #error "version not found" #endif - -static const BIGNUM * -dh_get_public_key( - DH *dhkey) -{ -#ifdef AUTH_INCLUDE_DH_ACCESSORS - const BIGNUM *pubkey, *privkey; - DH_get0_key(dhkey, &pubkey, &privkey); - return pubkey; -#else - return dhkey->pub_key; -#endif -} - - static void serializer_participant_data( DDS_Security_ParticipantBuiltinTopicData *pdata, @@ -704,13 +690,11 @@ set_dh_public_key( int r = 0; BIO *bio = NULL; EVP_PKEY *pkey; - DH *dhkey; unsigned char *buffer = NULL; ASN1_INTEGER *asn1int; *pubkey = NULL; - /* load certificate in buffer */ bio = BIO_new_mem_buf((void *) keystr, -1); if (!bio) { @@ -730,17 +714,7 @@ set_dh_public_key( goto fail_key_read; } - dhkey = EVP_PKEY_get1_DH(pkey); - if (!dhkey) { - char *msg = get_openssl_error(); - r = -1; - printf("Failed to get DH key from PKEY: %s", msg); - ddsrt_free(msg); - goto fail_get_dhkey; - } - - asn1int = BN_to_ASN1_INTEGER(dh_get_public_key(dhkey), NULL); - + asn1int = get_pubkey_asn1int(pkey); if (!asn1int) { char *msg = get_openssl_error(); r = -1; @@ -758,8 +732,6 @@ set_dh_public_key( ASN1_INTEGER_free(asn1int); fail_get_pubkey: - DH_free(dhkey); -fail_get_dhkey: EVP_PKEY_free(pkey); fail_key_read: BIO_free(bio); diff --git a/src/security/core/tests/common/cert_utils.c b/src/security/core/tests/common/cert_utils.c index e6a8709565..49a2d5892e 100644 --- a/src/security/core/tests/common/cert_utils.c +++ b/src/security/core/tests/common/cert_utils.c @@ -25,8 +25,8 @@ static X509 * get_x509(int not_valid_before, int not_valid_after, const char * c X509 * cert = X509_new (); CU_ASSERT_FATAL (cert != NULL); ASN1_INTEGER_set (X509_get_serialNumber (cert), 1); - X509_gmtime_adj (X509_get_notBefore (cert), not_valid_before); - X509_gmtime_adj (X509_get_notAfter (cert), not_valid_after); + X509_gmtime_adj (X509_getm_notBefore (cert), not_valid_before); + X509_gmtime_adj (X509_getm_notAfter (cert), not_valid_after); X509_NAME * name = X509_get_subject_name (cert); X509_NAME_add_entry_by_txt (name, "C", MBSTRING_ASC, (unsigned char *) "NL", -1, -1, 0); diff --git a/src/security/openssl/include/dds/security/openssl_support.h b/src/security/openssl/include/dds/security/openssl_support.h index eec09a6519..352c16bb9f 100644 --- a/src/security/openssl/include/dds/security/openssl_support.h +++ b/src/security/openssl/include/dds/security/openssl_support.h @@ -38,7 +38,8 @@ #include #endif -#define OPENSSL_API_COMPAT 10101 +/* Setting this macro to 30000 specifies that the code will be compatible with openssl version 3 and lower like version 1.1 */ +#define OPENSSL_API_COMPAT 30000 #include #include @@ -52,6 +53,9 @@ #if OPENSSL_VERSION_NUMBER >= 0x10100000L #define AUTH_INCLUDE_DH_ACCESSORS #endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#endif #else #error "OpenSSL version is not supported" #endif From 6f5ce8647814cbf339893ec5547335bcfd3f5a7c Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 22 Mar 2024 15:28:43 +0100 Subject: [PATCH 037/207] Drop support for OpenSSL pre-1.1.1 OpenSSL versions older than 1.1.1 have all been dead for over 4 years. I don't see why an Cyclone would have to continue supporting the bad practice of not updating EOL'd security sensitive libraries full of known vulnerabilities. Of course nobody should be using OpenSSL 1.1.1 anymore (it has been EOL'd about half a year ago), but I know there are still plenty of systems in the field that rely on it and even the CI on Azure gets the latest Linux images with it pre-installed. Signed-off-by: Erik Boasson --- README.md | 2 +- docs/dev/dds_security_effort.md | 4 +- src/core/ddsi/src/ddsi_ssl.c | 79 ------------------- .../authentication/src/auth_utils.c | 16 +--- .../tests/common/src/handshake_helper.c | 21 +---- .../src/get_xxx_sec_attributes_utests.c | 4 - .../src/register_local_datareader_utests.c | 4 - .../src/register_local_datawriter_utests.c | 4 - .../src/register_local_participant_utests.c | 4 - ...egister_matched_remote_datareader_utests.c | 4 - ...egister_matched_remote_datawriter_utests.c | 4 - ...gister_matched_remote_participant_utests.c | 4 - .../validate_begin_handshake_reply_utests.c | 8 -- .../include/dds/security/openssl_support.h | 35 -------- src/security/openssl/src/openssl_support.c | 76 ------------------ 15 files changed, 4 insertions(+), 265 deletions(-) diff --git a/README.md b/README.md index 7f08fae3e9..808566ded4 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ In order to build Cyclone DDS you need a Linux, Mac or Windows 10 machine (or, w * C compiler (most commonly GCC on Linux, Visual Studio on Windows, Xcode on macOS); * Optionally GIT version control system; * [CMake](https://cmake.org/download/), version 3.16 or later; - * Optionally [OpenSSL](https://www.openssl.org/), preferably version 1.1; + * Optionally [OpenSSL](https://www.openssl.org/), we recommend a fully patched and supported version but 1.1.1 will still work; * Optionally [Eclipse Iceoryx](https://iceoryx.io) version 2.0 for shared memory and zero-copy support; * Optionally [Bison](https://www.gnu.org/software/bison/) parser generator. A cached source is checked into the repository. diff --git a/docs/dev/dds_security_effort.md b/docs/dev/dds_security_effort.md index 5f150838c1..265363a448 100644 --- a/docs/dev/dds_security_effort.md +++ b/docs/dev/dds_security_effort.md @@ -137,9 +137,7 @@ No major changes between the DDS Security plugins in OpenSplice and Cyclone are expected. The DDS Security plugins require OpenSSL. Cyclone DDS already uses OpenSSL. -However, it expects (or at least it's preferred to have) version 1.1 or newer, -while the OpenSplice Security plugins are build against 1.0.2. There are some -API changes between the two versions. This will take some porting effort. +We recommend a fully patched and supported version but 1.1.1 will still work. The build system should be ported from makefiles to cmake files. diff --git a/src/core/ddsi/src/ddsi_ssl.c b/src/core/ddsi/src/ddsi_ssl.c index 26c75f9970..e43f8e53fb 100644 --- a/src/core/ddsi/src/ddsi_ssl.c +++ b/src/core/ddsi/src/ddsi_ssl.c @@ -129,52 +129,6 @@ static ssize_t ddsi_ssl_write (SSL *ssl, const void *buf, size_t len, dds_return return sent; } -/* Standard OpenSSL init and thread support routines. See O'Reilly. */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L -static unsigned long ddsi_ssl_id (void) -{ - return (unsigned long) ddsrt_gettid (); -} - -typedef struct CRYPTO_dynlock_value { - ddsrt_mutex_t m_mutex; -} CRYPTO_dynlock_value; - -static CRYPTO_dynlock_value *ddsi_ssl_locks = NULL; - -static void ddsi_ssl_dynlock_lock (int mode, CRYPTO_dynlock_value *lock, const char *file, int line) -{ - (void) file; - (void) line; - if (mode & CRYPTO_LOCK) - ddsrt_mutex_lock (&lock->m_mutex); - else - ddsrt_mutex_unlock (&lock->m_mutex); -} - -static void ddsi_ssl_lock (int mode, int n, const char *file, int line) -{ - ddsi_ssl_dynlock_lock (mode, &ddsi_ssl_locks[n], file, line); -} - -static CRYPTO_dynlock_value *ddsi_ssl_dynlock_create (const char *file, int line) -{ - (void) file; - (void) line; - CRYPTO_dynlock_value *val = ddsrt_malloc (sizeof (*val)); - ddsrt_mutex_init (&val->m_mutex); - return val; -} - -static void ddsi_ssl_dynlock_destroy (CRYPTO_dynlock_value *lock, const char *file, int line) -{ - (void) file; - (void) line; - ddsrt_mutex_destroy (&lock->m_mutex); - ddsrt_free (lock); -} -#endif - static int ddsi_ssl_password (char *buf, int num, int rwflag, void *udata) { size_t cnt; @@ -361,48 +315,15 @@ static bool ddsi_ssl_init (struct ddsi_domaingv *gv) SSL_load_error_strings (); SSL_library_init (); OpenSSL_add_all_algorithms (); - -#if OPENSSL_VERSION_NUMBER < 0x10100000L - { - const int locks = CRYPTO_num_locks (); - assert (locks >= 0); - ddsi_ssl_locks = ddsrt_malloc (sizeof (CRYPTO_dynlock_value) * (size_t) locks); - for (int i = 0; i < locks; i++) - ddsrt_mutex_init (&ddsi_ssl_locks[i].m_mutex); - } -#endif - /* Leave these in place: OpenSSL 1.1 defines them as no-op macros that not even reference the symbol, - therefore leaving them in means we get compile time errors if we the library expects the callbacks - to be defined and we somehow failed to detect that previously */ - CRYPTO_set_id_callback (ddsi_ssl_id); - CRYPTO_set_locking_callback (ddsi_ssl_lock); - CRYPTO_set_dynlock_create_callback (ddsi_ssl_dynlock_create); - CRYPTO_set_dynlock_lock_callback (ddsi_ssl_dynlock_lock); - CRYPTO_set_dynlock_destroy_callback (ddsi_ssl_dynlock_destroy); ddsi_ssl_ctx = ddsi_ssl_ctx_init (gv); - return (ddsi_ssl_ctx != NULL); } static void ddsi_ssl_fini (void) { SSL_CTX_free (ddsi_ssl_ctx); - CRYPTO_set_id_callback (0); - CRYPTO_set_locking_callback (0); - CRYPTO_set_dynlock_create_callback (0); - CRYPTO_set_dynlock_lock_callback (0); - CRYPTO_set_dynlock_destroy_callback (0); ERR_free_strings (); EVP_cleanup (); - -#if OPENSSL_VERSION_NUMBER < 0x10100000L - { - const int locks = CRYPTO_num_locks (); - for (int i = 0; i < locks; i++) - ddsrt_mutex_destroy (&ddsi_ssl_locks[i].m_mutex); - ddsrt_free (ddsi_ssl_locks); - } -#endif } void ddsi_ssl_config_plugin (struct ddsi_ssl_plugins *plugin) diff --git a/src/security/builtin_plugins/authentication/src/auth_utils.c b/src/security/builtin_plugins/authentication/src/auth_utils.c index 388f58fff6..6b71c13e73 100644 --- a/src/security/builtin_plugins/authentication/src/auth_utils.c +++ b/src/security/builtin_plugins/authentication/src/auth_utils.c @@ -887,23 +887,9 @@ DDS_Security_ValidationResult_t generate_dh_keys(EVP_PKEY **dhkey, Authenticatio static const BIGNUM *dh_get_public_key(DH *dhkey) { -#ifdef AUTH_INCLUDE_DH_ACCESSORS const BIGNUM *pubkey, *privkey; DH_get0_key(dhkey, &pubkey, &privkey); return pubkey; -#else - return dhkey->pub_key; -#endif -} - -static int dh_set_public_key(DH *dhkey, BIGNUM *pubkey) -{ -#ifdef AUTH_INCLUDE_DH_ACCESSORS - return DH_set0_key(dhkey, pubkey, NULL); -#else - dhkey->pub_key = pubkey; -#endif - return 1; } static DDS_Security_ValidationResult_t dh_public_key_to_oct_modp(EVP_PKEY *pkey, unsigned char **buffer, uint32_t *length, DDS_Security_SecurityException *ex) @@ -1014,7 +1000,7 @@ static DDS_Security_ValidationResult_t dh_oct_to_public_key_modp(EVP_PKEY **pkey } dhkey = DH_get_2048_256(); - if (dh_set_public_key(dhkey, pubkey) == 0) + if (DH_set0_key(dhkey, pubkey, NULL) == 0) { DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to set DH public key: "); goto fail_get_pubkey; diff --git a/src/security/builtin_plugins/tests/common/src/handshake_helper.c b/src/security/builtin_plugins/tests/common/src/handshake_helper.c index 8e4ee733a9..1ba43b8b5e 100644 --- a/src/security/builtin_plugins/tests/common/src/handshake_helper.c +++ b/src/security/builtin_plugins/tests/common/src/handshake_helper.c @@ -50,26 +50,9 @@ static const BIGNUM * dh_get_public_key( DH *dhkey) { -#ifdef AUTH_INCLUDE_DH_ACCESSORS const BIGNUM *pubkey, *privkey; DH_get0_key(dhkey, &pubkey, &privkey); return pubkey; -#else - return dhkey->pub_key; -#endif -} - -static int -dh_set_public_key( - DH *dhkey, - BIGNUM *pubkey) -{ -#ifdef AUTH_INCLUDE_DH_ACCESSORS - return DH_set0_key(dhkey, pubkey, NULL); -#else - dhkey->pub_key = pubkey; -#endif - return 1; } ASN1_INTEGER * @@ -208,8 +191,7 @@ modp_data_to_pubkey( goto fail_dhkey; } - dh_set_public_key(dhkey,bn); - + DH_set0_key(dhkey, bn, NULL); if (!(pkey = EVP_PKEY_new())) { char *msg = get_openssl_error_message_for_test(); printf("Failed to allocate pkey: %s", msg); @@ -688,7 +670,6 @@ create_dh_key_ecdh( #endif - /* for DEBUG purposes */ void print_binary_test( char* name, unsigned char *value, uint32_t size){ uint32_t i; diff --git a/src/security/builtin_plugins/tests/get_xxx_sec_attributes/src/get_xxx_sec_attributes_utests.c b/src/security/builtin_plugins/tests/get_xxx_sec_attributes/src/get_xxx_sec_attributes_utests.c index d4053dfadd..80316008aa 100644 --- a/src/security/builtin_plugins/tests/get_xxx_sec_attributes/src/get_xxx_sec_attributes_utests.c +++ b/src/security/builtin_plugins/tests/get_xxx_sec_attributes/src/get_xxx_sec_attributes_utests.c @@ -23,10 +23,6 @@ #include "common/src/loader.h" #include "config_env.h" -#if OPENSLL_VERSION_NUMBER >= 0x10002000L -#define AUTH_INCLUDE_EC -#endif - static const char *RELATIVE_PATH_TO_ETC_DIR = "/get_xxx_sec_attributes/etc/"; static const char *IDENTITY_CERTIFICATE = diff --git a/src/security/builtin_plugins/tests/register_local_datareader/src/register_local_datareader_utests.c b/src/security/builtin_plugins/tests/register_local_datareader/src/register_local_datareader_utests.c index 6eebf2c4cc..b6b218354e 100644 --- a/src/security/builtin_plugins/tests/register_local_datareader/src/register_local_datareader_utests.c +++ b/src/security/builtin_plugins/tests/register_local_datareader/src/register_local_datareader_utests.c @@ -25,10 +25,6 @@ #include "common/src/crypto_helper.h" #include "crypto_objects.h" -#if OPENSLL_VERSION_NUMBER >= 0x10002000L -#define AUTH_INCLUDE_EC -#endif - #define TEST_SHARED_SECRET_SIZE 32 static struct plugins_hdl *plugins = NULL; diff --git a/src/security/builtin_plugins/tests/register_local_datawriter/src/register_local_datawriter_utests.c b/src/security/builtin_plugins/tests/register_local_datawriter/src/register_local_datawriter_utests.c index 63d0cc2eab..5e4d8ec63f 100644 --- a/src/security/builtin_plugins/tests/register_local_datawriter/src/register_local_datawriter_utests.c +++ b/src/security/builtin_plugins/tests/register_local_datawriter/src/register_local_datawriter_utests.c @@ -25,10 +25,6 @@ #include "common/src/crypto_helper.h" #include "crypto_objects.h" -#if OPENSLL_VERSION_NUMBER >= 0x10002000L -#define AUTH_INCLUDE_EC -#endif - #define TEST_SHARED_SECRET_SIZE 32 static struct plugins_hdl *plugins = NULL; diff --git a/src/security/builtin_plugins/tests/register_local_participant/src/register_local_participant_utests.c b/src/security/builtin_plugins/tests/register_local_participant/src/register_local_participant_utests.c index 8dfd71f47a..50f847ae24 100644 --- a/src/security/builtin_plugins/tests/register_local_participant/src/register_local_participant_utests.c +++ b/src/security/builtin_plugins/tests/register_local_participant/src/register_local_participant_utests.c @@ -24,10 +24,6 @@ #include "common/src/loader.h" #include "crypto_objects.h" -#if OPENSLL_VERSION_NUMBER >= 0x10002000L -#define AUTH_INCLUDE_EC -#endif - static struct plugins_hdl *plugins = NULL; static dds_security_cryptography *crypto = NULL; diff --git a/src/security/builtin_plugins/tests/register_matched_remote_datareader/src/register_matched_remote_datareader_utests.c b/src/security/builtin_plugins/tests/register_matched_remote_datareader/src/register_matched_remote_datareader_utests.c index 3b2bdaa895..d170f187f5 100644 --- a/src/security/builtin_plugins/tests/register_matched_remote_datareader/src/register_matched_remote_datareader_utests.c +++ b/src/security/builtin_plugins/tests/register_matched_remote_datareader/src/register_matched_remote_datareader_utests.c @@ -25,10 +25,6 @@ #include "common/src/crypto_helper.h" #include "crypto_objects.h" -#if OPENSLL_VERSION_NUMBER >= 0x10002000L -#define AUTH_INCLUDE_EC -#endif - #define TEST_SHARED_SECRET_SIZE 32 static struct plugins_hdl *plugins = NULL; diff --git a/src/security/builtin_plugins/tests/register_matched_remote_datawriter/src/register_matched_remote_datawriter_utests.c b/src/security/builtin_plugins/tests/register_matched_remote_datawriter/src/register_matched_remote_datawriter_utests.c index eded0ccd5d..9ff2c04d87 100644 --- a/src/security/builtin_plugins/tests/register_matched_remote_datawriter/src/register_matched_remote_datawriter_utests.c +++ b/src/security/builtin_plugins/tests/register_matched_remote_datawriter/src/register_matched_remote_datawriter_utests.c @@ -25,10 +25,6 @@ #include "common/src/crypto_helper.h" #include "crypto_objects.h" -#if OPENSLL_VERSION_NUMBER >= 0x10002000L -#define AUTH_INCLUDE_EC -#endif - #define TEST_SHARED_SECRET_SIZE 32 static struct plugins_hdl *plugins = NULL; diff --git a/src/security/builtin_plugins/tests/register_matched_remote_participant/src/register_matched_remote_participant_utests.c b/src/security/builtin_plugins/tests/register_matched_remote_participant/src/register_matched_remote_participant_utests.c index 60f4bd1144..b9faf9a6e9 100644 --- a/src/security/builtin_plugins/tests/register_matched_remote_participant/src/register_matched_remote_participant_utests.c +++ b/src/security/builtin_plugins/tests/register_matched_remote_participant/src/register_matched_remote_participant_utests.c @@ -22,10 +22,6 @@ #include "common/src/loader.h" #include "crypto_objects.h" -#if OPENSLL_VERSION_NUMBER >= 0x10002000L -#define AUTH_INCLUDE_EC -#endif - #define TEST_SHARED_SECRET_SIZE 32 static struct plugins_hdl *plugins = NULL; diff --git a/src/security/builtin_plugins/tests/validate_begin_handshake_reply/src/validate_begin_handshake_reply_utests.c b/src/security/builtin_plugins/tests/validate_begin_handshake_reply/src/validate_begin_handshake_reply_utests.c index 138c960e6e..92f26f3396 100644 --- a/src/security/builtin_plugins/tests/validate_begin_handshake_reply/src/validate_begin_handshake_reply_utests.c +++ b/src/security/builtin_plugins/tests/validate_begin_handshake_reply/src/validate_begin_handshake_reply_utests.c @@ -333,15 +333,7 @@ static DDS_Security_GUID_t remote_participant_guid2; static bool future_challenge_done = false; -#if OPENSSL_VERSION_NUMBER >= 0x1000200fL -#define AUTH_INCLUDE_EC #include -#if OPENSSL_VERSION_NUMBER >= 0x10100000L -#define AUTH_INCLUDE_DH_ACCESSORS -#endif -#else -#error "version not found" -#endif static void serializer_participant_data( diff --git a/src/security/openssl/include/dds/security/openssl_support.h b/src/security/openssl/include/dds/security/openssl_support.h index 352c16bb9f..ceff5dce88 100644 --- a/src/security/openssl/include/dds/security/openssl_support.h +++ b/src/security/openssl/include/dds/security/openssl_support.h @@ -13,26 +13,6 @@ #include "dds/security/dds_security_api_types.h" -/* There's OpenSSL 1.1.x and there's OpenSSL 1.0.2 and the difference is like - night and day: 1.1.0 deprecated all the initialization and cleanup routines - and so any library can link with OpenSSL and use it safely without breaking - the application code or some other library in the same process. - - OpenSSL 1.0.2h deprecated the cleanup functions such as EVP_cleanup because - calling the initialisation functions multiple times was survivable, but an - premature invocation of the cleanup functions deadly. It still has the per- - thread error state that one ought to clean up, but that firstly requires - keeping track of which threads make OpenSSL calls, and secondly we do - perform OpenSSL calls on the applications main-thread and so cleaning up - might interfere with the application code. - - Compatibility with 1.0.2 exists merely as a courtesy to those who insist on - using it with that problematic piece of code. We only initialise it, and we - don't clean up thread state. If Cyclone DDS is the only part of the process - that uses OpenSSL, it should be ok (just some some minor leaks at the end), - if the application code or another library also uses it, it'll probably be - fine too. */ - #ifdef _WIN32 /* WinSock2 must be included before openssl 1.0.2 headers otherwise winsock will be used */ #include @@ -47,19 +27,10 @@ #include #include -#if OPENSSL_VERSION_NUMBER >= 0x1000200fL -#define AUTH_INCLUDE_EC #include -#if OPENSSL_VERSION_NUMBER >= 0x10100000L -#define AUTH_INCLUDE_DH_ACCESSORS -#endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L #include #endif -#else -#error "OpenSSL version is not supported" -#endif - #include #include #include @@ -73,12 +44,6 @@ void dds_openssl_init (void); -#if OPENSSL_VERSION_NUMBER < 0x10100000L -/* 1.1.0 has it as a supported API. 1.0.2 has it in practice and since that has been - obsolete for ages, chances are that we can safely use it */ -struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result); -#endif - void DDS_Security_Exception_set_with_openssl_error (DDS_Security_SecurityException *ex, const char *context, int code, int minor_code, const char *error_area) ddsrt_nonnull_all; diff --git a/src/security/openssl/src/openssl_support.c b/src/security/openssl/src/openssl_support.c index a72ddceac6..2ab2d5ced6 100644 --- a/src/security/openssl/src/openssl_support.c +++ b/src/security/openssl/src/openssl_support.c @@ -18,86 +18,10 @@ #include "dds/security/core/dds_security_utils.h" #include "dds/security/openssl_support.h" -#if OPENSSL_VERSION_NUMBER < 0x10100000L -static unsigned long ssl_id (void) -{ - return (unsigned long) ddsrt_gettid (); -} - -typedef struct CRYPTO_dynlock_value { - ddsrt_mutex_t m_mutex; -} CRYPTO_dynlock_value; - -CRYPTO_dynlock_value *dds_openssl102_ssl_locks = NULL; - -static void ssl_dynlock_lock (int mode, CRYPTO_dynlock_value *lock, const char *file, int line) -{ - (void) file; - (void) line; - if (mode & CRYPTO_LOCK) - ddsrt_mutex_lock (&lock->m_mutex); - else - ddsrt_mutex_unlock (&lock->m_mutex); -} - -static void ssl_lock (int mode, int n, const char *file, int line) -{ - ssl_dynlock_lock (mode, &dds_openssl102_ssl_locks[n], file, line); -} - -static CRYPTO_dynlock_value *ssl_dynlock_create (const char *file, int line) -{ - (void) file; - (void) line; - CRYPTO_dynlock_value *val = ddsrt_malloc (sizeof (*val)); - ddsrt_mutex_init (&val->m_mutex); - return val; -} - -static void ssl_dynlock_destroy (CRYPTO_dynlock_value *lock, const char *file, int line) -{ - (void) file; - (void) line; - ddsrt_mutex_destroy (&lock->m_mutex); - ddsrt_free (lock); -} - -void dds_openssl_init (void) -{ - // This is terribly fragile and broken-by-design, but with OpenSSL sometimes - // linked dynamically and sometimes linked statically, with Windows and Unix - // in the mix, this appears to be the compromise that makes it work reliably - // enough ... - if (CRYPTO_get_id_callback () == 0) - { - CRYPTO_set_id_callback (ssl_id); - CRYPTO_set_locking_callback (ssl_lock); - CRYPTO_set_dynlock_create_callback (ssl_dynlock_create); - CRYPTO_set_dynlock_lock_callback (ssl_dynlock_lock); - CRYPTO_set_dynlock_destroy_callback (ssl_dynlock_destroy); - - if (dds_openssl102_ssl_locks == NULL) - { - const int locks = CRYPTO_num_locks (); - assert (locks >= 0); - dds_openssl102_ssl_locks = ddsrt_malloc (sizeof (CRYPTO_dynlock_value) * (size_t) locks); - for (int i = 0; i < locks; i++) - ddsrt_mutex_init (&dds_openssl102_ssl_locks[i].m_mutex); - } - - OpenSSL_add_all_algorithms (); - OpenSSL_add_all_ciphers (); - OpenSSL_add_all_digests (); - ERR_load_BIO_strings (); - ERR_load_crypto_strings (); - } -} -#else void dds_openssl_init (void) { // nothing needed for OpenSSL 1.1.0 and later } -#endif void DDS_Security_Exception_set_with_openssl_error (DDS_Security_SecurityException *ex, const char *context, int code, int minor_code, const char *error_area) { From 840c1ffc5225460ba9c4965a69c49ca37a0489f7 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 26 Mar 2024 11:11:48 +0100 Subject: [PATCH 038/207] Add build-time option for TCP+TLS support ENABLE_SSL did two things: * Enable the built-in plugins (if ENABLE_SECURITY) * Enable TCP+TLS support TCP support is rarely used and has some problems, TCP+TLS support is even more rarely used and we recommend using DDS Security instead. If TCP+TLS is not recommended, it makes sense to support builds that leave it out. This also has the advantage of being able to include support for DDS Security with the built-in plugins but without introducing a dependency on OpenSSL for the core library. Signed-off-by: Erik Boasson --- docs/manual/config/config_file_reference.rst | 6 +-- docs/manual/options.md | 6 +-- etc/cyclonedds.rnc | 6 +-- etc/cyclonedds.xsd | 6 +-- src/CMakeLists.txt | 10 +++++ src/core/CMakeLists.txt | 2 +- src/core/ddsi/defconfig.c | 10 ++--- src/core/ddsi/include/dds/ddsi/ddsi_config.h | 4 +- src/core/ddsi/src/ddsi__cfgelems.h | 8 ++-- src/core/ddsi/src/ddsi__ssl.h | 4 +- src/core/ddsi/src/ddsi_config.c | 4 +- src/core/ddsi/src/ddsi_ssl.c | 4 +- src/core/ddsi/src/ddsi_tcp.c | 40 ++++++++++---------- src/ddsrt/CMakeLists.txt | 2 +- src/ddsrt/include/dds/features.h.in | 2 +- 15 files changed, 62 insertions(+), 52 deletions(-) diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index 8f9b08018c..6280f1ed75 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -2699,10 +2699,10 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: ``none`` .. - generated from ddsi_config.h[9f834d377bdea61bea6507feed2fc4a8924dc02e] + generated from ddsi_config.h[eaf2059de5eccc422ae9ebd9bb3c40fd1d7545d3] generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] - generated from ddsi__cfgelems.h[f10059d775cf2e4961a2e9520bb1a4da6a124778] - generated from ddsi_config.c[0a59324bd889637ea7d04765da9b76bbe74997c1] + generated from ddsi__cfgelems.h[fc5746cc2e55b4ab9daf9bd51bc263cf30ece564] + generated from ddsi_config.c[2d3406ce4db09358597689d7382f80185634eb69] generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] diff --git a/docs/manual/options.md b/docs/manual/options.md index 1c0571abd7..2c80765dd3 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -1889,10 +1889,10 @@ While none prevents any message from being written to a DDSI2 log file. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest. The default value is: `none` - + - - + + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index e8cc343f05..8ff2bcb582 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -1310,10 +1310,10 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
    duration_inf = xsd:token { pattern = "inf|0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)" } memsize = xsd:token { pattern = "0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B" } } -# generated from ddsi_config.h[9f834d377bdea61bea6507feed2fc4a8924dc02e] +# generated from ddsi_config.h[eaf2059de5eccc422ae9ebd9bb3c40fd1d7545d3] # generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] -# generated from ddsi__cfgelems.h[f10059d775cf2e4961a2e9520bb1a4da6a124778] -# generated from ddsi_config.c[0a59324bd889637ea7d04765da9b76bbe74997c1] +# generated from ddsi__cfgelems.h[fc5746cc2e55b4ab9daf9bd51bc263cf30ece564] +# generated from ddsi_config.c[2d3406ce4db09358597689d7382f80185634eb69] # generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] # generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] # generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index 893b41d8a7..8b3ceb9ecc 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -1970,10 +1970,10 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - + - - + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ae00de44c6..da328a2ea2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -70,6 +70,16 @@ if(ENABLE_SSL) endif() endif() +set(ENABLE_TCP_TLS "AUTO" CACHE STRING "Enable TCP+TLS support (depends on ENABLE_SSL)") +set_property(CACHE ENABLE_TCP_TLS PROPERTY STRINGS ON OFF AUTO) +if(ENABLE_TCP_TLS) + if(ENABLE_TCP_TLS STREQUAL "AUTO") + set(ENABLE_TCP_TLS "${ENABLE_SSL}") + elseif(ENABLE_TCP_TLS AND NOT ENABLE_SSL) + message(FATAL "ENABLE_TCP_TLS requires ENABLE_SSL") + endif() +endif() + if(NOT ENABLE_SECURITY) message(STATUS "Building without OMG DDS Security support") endif() diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 0db30e1fe8..2c5761e36b 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -23,7 +23,7 @@ if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") target_link_libraries(ddsc PRIVATE dbghelp) endif() -if(ENABLE_SSL AND OPENSSL_FOUND) +if(ENABLE_TCP_TLS AND OPENSSL_FOUND) target_link_libraries(ddsc PRIVATE OpenSSL::SSL) if(CMAKE_GENERATOR MATCHES "Visual Studio") set_target_properties(ddsc PROPERTIES LINK_FLAGS "/ignore:4099") diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index b1e7c1e663..082bca3bed 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -89,7 +89,7 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->tcp_port = INT32_C (-1); cfg->tcp_read_timeout = INT64_C (2000000000); cfg->tcp_write_timeout = INT64_C (2000000000); -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS cfg->ssl_verify = INT32_C (1); cfg->ssl_verify_client = INT32_C (1); cfg->ssl_keystore = "keystore"; @@ -98,12 +98,12 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->ssl_rand_file = ""; cfg->ssl_min_version.major = 1; cfg->ssl_min_version.minor = 3; -#endif /* DDS_HAS_SSL */ +#endif /* DDS_HAS_TCP_TLS */ } -/* generated from ddsi_config.h[9f834d377bdea61bea6507feed2fc4a8924dc02e] */ +/* generated from ddsi_config.h[eaf2059de5eccc422ae9ebd9bb3c40fd1d7545d3] */ /* generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] */ -/* generated from ddsi__cfgelems.h[f10059d775cf2e4961a2e9520bb1a4da6a124778] */ -/* generated from ddsi_config.c[0a59324bd889637ea7d04765da9b76bbe74997c1] */ +/* generated from ddsi__cfgelems.h[fc5746cc2e55b4ab9daf9bd51bc263cf30ece564] */ +/* generated from ddsi_config.c[2d3406ce4db09358597689d7382f80185634eb69] */ /* generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] */ /* generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] */ /* generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] */ diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_config.h b/src/core/ddsi/include/dds/ddsi/ddsi_config.h index 334032089c..1b7295eb70 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_config.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_config.h @@ -205,7 +205,7 @@ struct ddsi_config_omg_security_listelem { }; #endif /* DDS_HAS_SECURITY */ -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS struct ddsi_config_ssl_min_version { int major; int minor; @@ -340,7 +340,7 @@ struct ddsi_config int64_t tcp_write_timeout; int tcp_use_peeraddr_for_unicast; -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS /* SSL support for TCP */ int ssl_enable; int ssl_verify; diff --git a/src/core/ddsi/src/ddsi__cfgelems.h b/src/core/ddsi/src/ddsi__cfgelems.h index 8204f5541c..5b3b453c0d 100644 --- a/src/core/ddsi/src/ddsi__cfgelems.h +++ b/src/core/ddsi/src/ddsi__cfgelems.h @@ -1737,7 +1737,7 @@ static struct cfgelem tcp_cfgelems[] = { END_MARKER }; -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS static struct cfgelem ssl_cfgelems[] = { BOOL("Enable", NULL, 1, "false", MEMBER(ssl_enable), @@ -2189,7 +2189,7 @@ static struct cfgelem domain_cfgelems[] = { "

    The TCP element allows you to specify various parameters related to " "running DDSI over TCP.

    " )), -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS GROUP("SSL", ssl_cfgelems, NULL, 1, NOMEMBER, NOFUNCTIONS, @@ -2197,7 +2197,7 @@ static struct cfgelem domain_cfgelems[] = { "

    The SSL element allows specifying various parameters related to " "using SSL/TLS for DDSI over TCP.

    " ), - BEHIND_FLAG("DDS_HAS_SSL") + BEHIND_FLAG("DDS_HAS_TCP_TLS") ), #endif GROUP("SharedMemory", shmem_cfgelems, NULL, 1, @@ -2232,7 +2232,7 @@ static struct cfgelem root_cfgelems[] = { MOVED("DDSSecurity", "CycloneDDS/Domain/Security"), #endif MOVED("SharedMemory", "CycloneDDS/Domain/SharedMemory"), -#if DDS_HAS_SSL +#if DDS_HAS_TCP_TLS MOVED("SSL", "CycloneDDS/Domain/SSL"), #endif MOVED("DDSI2E|DDSI2", "CycloneDDS/Domain"), diff --git a/src/core/ddsi/src/ddsi__ssl.h b/src/core/ddsi/src/ddsi__ssl.h index 766fb6eb3a..46c5783a39 100644 --- a/src/core/ddsi/src/ddsi__ssl.h +++ b/src/core/ddsi/src/ddsi__ssl.h @@ -13,7 +13,7 @@ #include "dds/features.h" -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS #ifdef _WIN32 /* supposedly WinSock2 must be included before openssl headers otherwise winsock will be used */ @@ -45,5 +45,5 @@ void ddsi_ssl_config_plugin (struct ddsi_ssl_plugins *plugin); } #endif -#endif /* DDS_HAS_SSL */ +#endif /* DDS_HAS_TCP_TLS */ #endif /* DDSI__SSL_H */ diff --git a/src/core/ddsi/src/ddsi_config.c b/src/core/ddsi/src/ddsi_config.c index 18617573ef..73eeacbac8 100644 --- a/src/core/ddsi/src/ddsi_config.c +++ b/src/core/ddsi/src/ddsi_config.c @@ -188,7 +188,7 @@ DUPF(domainId); DUPF(transport_selector); DUPF(many_sockets_mode); DU(deaf_mute); -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS DUPF(min_tls_version); #endif DUPF(shm_loglevel); @@ -1073,7 +1073,7 @@ static void pf_xcheck (struct ddsi_cfgst *cfgst, void *parent, struct cfgelem co do_print_uint32_bitset (cfgst, *p, sizeof (xcheck_codes) / sizeof (*xcheck_codes), xcheck_names, xcheck_codes, sources, suffix); } -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS static enum update_result uf_min_tls_version (struct ddsi_cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) { static const char *vs[] = { diff --git a/src/core/ddsi/src/ddsi_ssl.c b/src/core/ddsi/src/ddsi_ssl.c index e43f8e53fb..2b3928d345 100644 --- a/src/core/ddsi/src/ddsi_ssl.c +++ b/src/core/ddsi/src/ddsi_ssl.c @@ -13,7 +13,7 @@ #include "ddsi__tcp.h" #include "ddsi__ssl.h" -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS #include #include @@ -339,4 +339,4 @@ void ddsi_ssl_config_plugin (struct ddsi_ssl_plugins *plugin) plugin->accept = ddsi_ssl_accept; } -#endif /* DDS_HAS_SSL */ +#endif /* DDS_HAS_TCP_TLS */ diff --git a/src/core/ddsi/src/ddsi_tcp.c b/src/core/ddsi/src/ddsi_tcp.c index 1f7d90d373..8f7ef47fbb 100644 --- a/src/core/ddsi/src/ddsi_tcp.c +++ b/src/core/ddsi/src/ddsi_tcp.c @@ -56,7 +56,7 @@ typedef struct ddsi_tcp_conn { uint32_t m_peer_port; ddsrt_mutex_t m_mutex; ddsrt_socket_t m_sock; -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS SSL * m_ssl; #endif } *ddsi_tcp_conn_t; @@ -64,7 +64,7 @@ typedef struct ddsi_tcp_conn { typedef struct ddsi_tcp_listener { struct ddsi_tran_listener m_base; ddsrt_socket_t m_sock; -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS BIO * m_bio; #endif } *ddsi_tcp_listener_t; @@ -75,7 +75,7 @@ struct ddsi_tran_factory_tcp { ddsrt_mutex_t ddsi_tcp_cache_lock_g; ddsrt_avl_tree_t ddsi_tcp_cache_g; struct ddsi_tcp_conn ddsi_tcp_conn_client; -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS struct ddsi_ssl_plugins ddsi_tcp_ssl_plugin; #endif }; @@ -280,7 +280,7 @@ static void ddsi_tcp_conn_connect (ddsi_tcp_conn_t conn, const ddsrt_msghdr_t * goto fail_w_socket; ddsi_tcp_conn_set_socket (conn, sock); -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS if (fact->ddsi_tcp_ssl_plugin.connect) { conn->m_ssl = (fact->ddsi_tcp_ssl_plugin.connect) (conn->m_base.m_base.gv, sock); @@ -420,7 +420,7 @@ static ssize_t ddsi_tcp_conn_read_plain (ddsi_tcp_conn_t tcp, void * buf, size_t return (*rc == DDS_RETCODE_OK ? rcvd : -1); } -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS static ssize_t ddsi_tcp_conn_read_ssl (ddsi_tcp_conn_t tcp, void * buf, size_t len, dds_return_t *rc) { struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) tcp->m_base.m_factory; @@ -474,7 +474,7 @@ static ssize_t ddsi_tcp_conn_read (struct ddsi_tran_conn * conn, unsigned char * size_t pos = 0; ssize_t n; -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS if (fact->ddsi_tcp_ssl_plugin.read) { rd = ddsi_tcp_conn_read_ssl; @@ -542,7 +542,7 @@ static ssize_t ddsi_tcp_conn_write_plain (ddsi_tcp_conn_t conn, const void * buf return (*rc == DDS_RETCODE_OK ? sent : -1); } -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS static ssize_t ddsi_tcp_conn_write_ssl (ddsi_tcp_conn_t conn, const void * buf, size_t len, dds_return_t *rc) { struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_base.m_factory; @@ -608,7 +608,7 @@ static ssize_t ddsi_tcp_conn_write (struct ddsi_tran_conn * base, const ddsi_loc { struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) base->m_factory; struct ddsi_domaingv const * const gv = fact->fact.gv; -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS char msgbuf[4096]; /* stack buffer for merging smallish writes without requiring allocations */ ddsrt_iovec_t iovec; /* iovec used for msgbuf */ #endif @@ -665,7 +665,7 @@ static ssize_t ddsi_tcp_conn_write (struct ddsi_tran_conn * base, const ddsi_loc return (ssize_t) len; } -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS if (gv->config.ssl_enable) { /* SSL doesn't have sendmsg, ret = 0 so writing starts at first byte. @@ -742,7 +742,7 @@ static ssize_t ddsi_tcp_conn_write (struct ddsi_tran_conn * base, const ddsi_loc { ssize_t (*wr) (ddsi_tcp_conn_t, const void *, size_t, dds_return_t *) = ddsi_tcp_conn_write_plain; int i = 0; -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS if (fact->ddsi_tcp_ssl_plugin.write) { wr = ddsi_tcp_conn_write_ssl; @@ -762,7 +762,7 @@ static ssize_t ddsi_tcp_conn_write (struct ddsi_tran_conn * base, const ddsi_loc } } -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS /* If allocated memory for merging original fragments into a single buffer, free it */ DDSRT_WARNING_MSVC_OFF(28199) if (msg.msg_iov == &iovec && iovec.iov_base != msgbuf) @@ -818,13 +818,13 @@ static dds_return_t ddsi_tcp_create_conn (struct ddsi_tran_conn **conn_out, stru static int ddsi_tcp_listen (struct ddsi_tran_listener * listener) { -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) listener->m_factory; #endif ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) listener; int ret = listen (tl->m_sock, 4); -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS if ((ret == 0) && fact->ddsi_tcp_ssl_plugin.listen) { tl->m_bio = (fact->ddsi_tcp_ssl_plugin.listen) (tl->m_sock); @@ -845,13 +845,13 @@ static struct ddsi_tran_conn * ddsi_tcp_accept (struct ddsi_tran_listener * list socklen_t addrlen = sizeof (addr); char buff[DDSI_LOCSTRLEN]; dds_return_t rc = DDS_RETCODE_OK; -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS SSL * ssl = NULL; #endif memset (&addr, 0, sizeof(addr)); do { -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS if (fact->ddsi_tcp_ssl_plugin.accept) { ssl = (fact->ddsi_tcp_ssl_plugin.accept) (listener->m_base.gv, tl->m_bio, &sock); @@ -890,7 +890,7 @@ static struct ddsi_tran_conn * ddsi_tcp_accept (struct ddsi_tran_listener * list (void)ddsrt_setsocknonblocking (sock, true); tcp = ddsi_tcp_new_conn (fact, NULL, sock, true, &addr.a); -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS tcp->m_ssl = ssl; #endif tcp->m_base.m_listener = listener; @@ -1011,7 +1011,7 @@ static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn) sockaddr_to_string_with_port(buff, sizeof(buff), &conn->m_peer_addr.a); GVLOG (DDS_LC_TCP, "tcp free %s connection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff); -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS if (fact->ddsi_tcp_ssl_plugin.ssl_free) { (fact->ddsi_tcp_ssl_plugin.ssl_free) (conn->m_ssl); @@ -1106,7 +1106,7 @@ static void ddsi_tcp_release_listener (struct ddsi_tran_listener * listener) { ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) listener; struct ddsi_domaingv const * const gv = tl->m_base.m_base.gv; -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) listener->m_factory; if (fact->ddsi_tcp_ssl_plugin.bio_vfree) { @@ -1123,7 +1123,7 @@ static void ddsi_tcp_release_factory (struct ddsi_tran_factory *fact_cmn) struct ddsi_domaingv const * const gv = fact->fact.gv; ddsrt_avl_free (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, ddsi_tcp_node_free); ddsrt_mutex_destroy (&fact->ddsi_tcp_cache_lock_g); -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS if (fact->ddsi_tcp_ssl_plugin.fini) { (fact->ddsi_tcp_ssl_plugin.fini) (); @@ -1258,7 +1258,7 @@ int ddsi_tcp_init (struct ddsi_domaingv *gv) memset (&fact->ddsi_tcp_conn_client, 0, sizeof (fact->ddsi_tcp_conn_client)); ddsi_tcp_base_init (fact, NULL, &fact->ddsi_tcp_conn_client.m_base); -#ifdef DDS_HAS_SSL +#ifdef DDS_HAS_TCP_TLS if (gv->config.ssl_enable) { ddsi_ssl_config_plugin (&fact->ddsi_tcp_ssl_plugin); diff --git a/src/ddsrt/CMakeLists.txt b/src/ddsrt/CMakeLists.txt index b3d38e67e0..94a724760b 100644 --- a/src/ddsrt/CMakeLists.txt +++ b/src/ddsrt/CMakeLists.txt @@ -310,7 +310,7 @@ endif() set(DDSRT_WITH_LWIP ${WITH_LWIP}) set(DDSRT_WITH_FREERTOS ${WITH_FREERTOS}) -foreach(feature SSL SECURITY LIFESPAN DEADLINE_MISSED NETWORK_PARTITIONS +foreach(feature TCP_TLS SECURITY LIFESPAN DEADLINE_MISSED NETWORK_PARTITIONS SSM TYPELIB TYPE_DISCOVERY TOPIC_DISCOVERY) set(DDS_HAS_${feature} ${ENABLE_${feature}}) endforeach() diff --git a/src/ddsrt/include/dds/features.h.in b/src/ddsrt/include/dds/features.h.in index 28ac452333..9f687d405d 100644 --- a/src/ddsrt/include/dds/features.h.in +++ b/src/ddsrt/include/dds/features.h.in @@ -27,7 +27,7 @@ #cmakedefine DDS_HAS_SSM 1 /* Whether or not features dependent on OpenSSL are included */ -#cmakedefine DDS_HAS_SSL 1 +#cmakedefine DDS_HAS_TCP_TLS 1 /* Whether or not support for type library is included */ #cmakedefine DDS_HAS_TYPELIB 1 From 54ec204fe3c4a3a16696c462d34e2a463e401073 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Wed, 20 Mar 2024 10:55:34 +0100 Subject: [PATCH 039/207] Update CI platform selection - Windows 2022 - GCC 13 - macOS 13 Signed-off-by: Erik Boasson --- .azure/templates/build-test.yml | 7 +++ azure-pipelines.yml | 75 ++++++++++++++++----------------- 2 files changed, 43 insertions(+), 39 deletions(-) diff --git a/.azure/templates/build-test.yml b/.azure/templates/build-test.yml index 0d767796ff..c6a4f17765 100644 --- a/.azure/templates/build-test.yml +++ b/.azure/templates/build-test.yml @@ -19,6 +19,13 @@ steps: inputs: versionSpec: '3.8' name: install_python + - bash: | + # Asan in llvm 14 provided in ubuntu 22.04 is incompatible with + # high-entropy ASLR in much newer kernels that GitHub runners are + # using leading to random crashes: https://reviews.llvm.org/D148280 + sudo sysctl vm.mmap_rnd_bits=28 + condition: eq(variables['Agent.OS'], 'Linux') + name: fix_kernel_mmap_rnd_bits # Set defaults from steps to share them among pipelines - bash: | [[ -n "${ARCH}" ]] || \ diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f2b46f94ac..88e76ab3d5 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -40,19 +40,23 @@ jobs: build_type: Release sanitizer: undefined cc: gcc-10 - 'Ubuntu 22.04 LTS with GCC 10 (Debug, x86_64, Iceoryx)': + 'Ubuntu 22.04 LTS with GCC 13 (Debug, x86_64, Iceoryx)': image: ubuntu-22.04 - #analyzer: on # disabled for now because of warnings - sanitizer: address,undefined + # No address sanitizer because of this in test run: + # Shadow memory range interleaves with an existing memory mapping. + # ASan cannot proceed correctly. ABORTING. + # ASan shadow was supposed to be located in the [0x00007fff7000-0x10007fff7fff] + # range. + sanitizer: undefined iceoryx: on - cc: gcc-10 + cc: gcc-13 coverage: on - 'Ubuntu 22.04 LTS with GCC 10 (Release, x86_64)': + 'Ubuntu 22.04 LTS with GCC 13 (Release, x86_64)': image: ubuntu-22.04 build_type: Release sanitizer: undefined - cc: gcc-10 - 'Ubuntu 22.04 LTS with GCC 10 (Debug, x86_64, security only)': + cc: gcc-13 + 'Ubuntu 22.04 LTS with GCC 12 (Debug, x86_64, security only)': image: ubuntu-22.04 sanitizer: address,undefined ssl: off @@ -61,72 +65,65 @@ jobs: type_discovery: off topic_discovery: off idlc_xtests: off # temporary disabled because of passing -t option to idlc in this test for recursive types - cc: gcc-10 - 'Ubuntu 22.04 LTS with GCC 10 (Debug, x86_64, no tests)': + cc: gcc-12 + 'Ubuntu 22.04 LTS with GCC 12 (Debug, x86_64, no tests)': image: ubuntu-22.04 - cc: gcc-10 + cc: gcc-12 testing: off idlc_xtests: off - 'Ubuntu 22.04 LTS with Clang 13 (Debug, x86_64)': + 'Ubuntu 22.04 LTS with Clang 15 (Debug, x86_64)': image: ubuntu-22.04 analyzer: on sanitizer: address,undefined - cc: clang-13 - 'Ubuntu 22.04 LTS with Clang 13 (Debug, x86_64, no security)': + cc: clang-15 + 'Ubuntu 22.04 LTS with Clang 15 (Debug, x86_64, no security)': image: ubuntu-22.04 sanitizer: address,undefined security: off - cc: clang-13 - 'Ubuntu 22.04 LTS with Clang 13 (Release, x86_64, no topic discovery)': + cc: clang-15 + 'Ubuntu 22.04 LTS with Clang 15 (Release, x86_64, no topic discovery)': image: ubuntu-22.04 build_type: Release sanitizer: undefined topic_discovery: off idlc_xtests: off # temporary disabled because of passing -t option to idlc in this test for recursive types - cc: clang-13 - 'macOS 11 with Clang 12 (Debug, x86_64)': - image: macOS-11 + cc: clang-15 + 'macOS 13 with Clang 15 (Debug, x86_64)': + image: macos-13 sanitizer: address,undefined deadline_update_skip: on cc: clang - 'macOS 11 with Clang 12 (Release, x86_64)': - image: macOS-11 - build_type: Release - sanitizer: undefined - deadline_update_skip: on - cc: clang - 'macOS 11 with Clang 13 (Release, x86_64)': - image: macOS-11 + 'macOS 13 with Clang 15 (Release, x86_64)': + image: macos-13 build_type: Release sanitizer: undefined deadline_update_skip: on cc: clang coverage: on - 'macOS 12 with gcc 12 (Debug, analyzer, x86_64)': - image: macOS-12 - sanitizer: undefined + 'macOS 13 with gcc 13 (Debug, analyzer, x86_64)': + image: macos-13 deadline_update_skip: on - cc: gcc-12 + cc: gcc-13 analyzer: on # 32-bit Windows: without SSL/security because Chocolateley only provides 64-bit OpenSSL - 'Windows 2019 with Visual Studio 2019 (Visual Studio 2017, Debug, x86, no security)': + 'Windows 2022 with Visual Studio 2022 (Debug, x86, no security)': arch: x86 - image: windows-2019 + image: windows-2022 ssl: off security: off idlc_xtests: off - generator: 'Visual Studio 16 2019' + generator: 'Visual Studio 17 2022' toolset: v141 - 'Windows 2019 with Visual Studio 2019 (Debug, x86_64)': - image: windows-2019 + 'Windows 2022 with Visual Studio 2022 (Debug, x86_64)': + image: windows-2022 idlc_xtests: off - generator: 'Visual Studio 16 2019' - 'Windows 2019 with Visual Studio 2019 (Release, x86_64, no tests)': - image: windows-2019 + generator: 'Visual Studio 17 2022' + 'Windows 2022 with Visual Studio 2022 (Release, x86_64, no tests)': + image: windows-2022 build_type: Release testing: off idlc_xtests: off - generator: 'Visual Studio 16 2019' + generator: 'Visual Studio 17 2022' 'Windows 2019 with Visual Studio 2019 (RelWithDebInfo, x86_64)': image: windows-2019 build_type: RelWithDebInfo From d22e750139e76504c87df95fcf7e8df770700858 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 18 Jul 2023 09:01:34 +0200 Subject: [PATCH 040/207] Fix false pos on null deref in serdata_from_ser Leaving out a lot of details in the actual code, this: serdata_x_from_ser (... const struct ddsi_rdata *fragchain ...) { (1) assert (fragchain->min == 0); (2) while (fragchain) fragchain = fragchain->nextfrag; triggered a warning from the gcc 13.1 static analyzer that fragchain was tested for a null pointer at (2) after having dereferenced it already at (1). Clearly this is because the function is not annotated as required a non-null fragchain on input. This commit adds these non-null annotation (and some "warn unused result" ones) on the ddsi_serdata_... functions. The cases where this resulted in new warnings have also been updated. Signed-off-by: Erik Boasson --- src/core/ddsc/src/dds_instance.c | 30 ++-- src/core/ddsc/src/dds_rhc_default.c | 53 ++++--- src/core/ddsc/src/dds_serdata_default.c | 18 ++- src/core/ddsc/tests/readcollect.c | 12 +- src/core/ddsi/include/dds/ddsi/ddsi_serdata.h | 145 +++++++++++++----- src/core/ddsi/src/ddsi_security_msg.c | 4 +- src/core/ddsi/src/ddsi_serdata_cdr.c | 3 + src/core/ddsi/src/ddsi_serdata_plist.c | 20 +-- src/core/ddsi/src/ddsi_serdata_pserop.c | 20 +-- src/core/ddsi/src/ddsi_typelookup.c | 13 +- src/core/xtests/rhc_torture/rhc_torture.c | 3 +- src/core/xtests/symbol_export/symbol_export.c | 2 + 12 files changed, 220 insertions(+), 103 deletions(-) diff --git a/src/core/ddsc/src/dds_instance.c b/src/core/ddsc/src/dds_instance.c index c2143d79b9..cff08e07a2 100644 --- a/src/core/ddsc/src/dds_instance.c +++ b/src/core/ddsc/src/dds_instance.c @@ -159,9 +159,13 @@ dds_return_t dds_unregister_instance_ih_ts (dds_entity_t writer, dds_instance_ha { struct ddsi_sertype *tp = wr->m_topic->m_stype; void *sample = ddsi_sertype_alloc_sample (tp); - ddsi_serdata_untyped_to_sample (tp, tk->m_sample, sample, NULL, NULL); - ddsi_tkmap_instance_unref (wr->m_entity.m_domain->gv.m_tkmap, tk); - ret = dds_write_impl (wr, sample, timestamp, action); + if (!ddsi_serdata_untyped_to_sample (tp, tk->m_sample, sample, NULL, NULL)) + ret = DDS_RETCODE_ERROR; + else + { + ddsi_tkmap_instance_unref (wr->m_entity.m_domain->gv.m_tkmap, tk); + ret = dds_write_impl (wr, sample, timestamp, action); + } ddsi_sertype_free_sample (tp, sample, DDS_FREE_ALL); } ddsi_thread_state_asleep (thrst); @@ -239,9 +243,13 @@ dds_return_t dds_dispose_ih_ts (dds_entity_t writer, dds_instance_handle_t handl { const struct ddsi_sertype *tp = wr->m_wr->type; void *sample = ddsi_sertype_alloc_sample (tp); - ddsi_serdata_untyped_to_sample (tp, tk->m_sample, sample, NULL, NULL); - ddsi_tkmap_instance_unref (wr->m_entity.m_domain->gv.m_tkmap, tk); - ret = dds_dispose_impl (wr, sample, handle, timestamp); + if (!ddsi_serdata_untyped_to_sample (tp, tk->m_sample, sample, NULL, NULL)) + ret = DDS_RETCODE_ERROR; + else + { + ddsi_tkmap_instance_unref (wr->m_entity.m_domain->gv.m_tkmap, tk); + ret = dds_dispose_impl (wr, sample, handle, timestamp); + } ddsi_sertype_free_sample (tp, sample, DDS_FREE_ALL); } ddsi_thread_state_asleep (thrst); @@ -327,9 +335,13 @@ dds_return_t dds_instance_get_key (dds_entity_t entity, dds_instance_handle_t ih /* Use sertype from topic, as the zero_sample and untyped_to_sample functions are identical for the derived sertype that is stored in the endpoint. */ ddsi_sertype_zero_sample (topic->m_stype, data); - ddsi_serdata_untyped_to_sample (topic->m_stype, tk->m_sample, data, NULL, NULL); - ddsi_tkmap_instance_unref (e->m_domain->gv.m_tkmap, tk); - ret = DDS_RETCODE_OK; + if (!ddsi_serdata_untyped_to_sample (topic->m_stype, tk->m_sample, data, NULL, NULL)) + ret = DDS_RETCODE_ERROR; + else + { + ddsi_tkmap_instance_unref (e->m_domain->gv.m_tkmap, tk); + ret = DDS_RETCODE_OK; + } } ddsi_thread_state_asleep (thrst); dds_entity_unlock (e); diff --git a/src/core/ddsc/src/dds_rhc_default.c b/src/core/ddsc/src/dds_rhc_default.c index c397b3c0a0..42ed2378bc 100644 --- a/src/core/ddsc/src/dds_rhc_default.c +++ b/src/core/ddsc/src/dds_rhc_default.c @@ -621,7 +621,14 @@ static void dds_rhc_default_set_qos (struct ddsi_rhc *rhc_common, const dds_qos_ static bool eval_predicate_sample (const struct dds_rhc_default *rhc, const struct ddsi_serdata *sample, bool (*pred) (const void *sample)) { - ddsi_serdata_to_sample (sample, rhc->qcond_eval_samplebuf, NULL, NULL); + // What to do if deserialization fails? Consider it matching or not? + // + // This is used in query evaluation, so claiming it matches at least allows taking it, + // and at least it allows the application to detect something is amiss. Always + // returning false would likely lead to endless loops in the application because some + // read condition remains triggered. + if (!ddsi_serdata_to_sample (sample, rhc->qcond_eval_samplebuf, NULL, NULL)) + return true; bool ret = pred (rhc->qcond_eval_samplebuf); return ret; } @@ -989,23 +996,30 @@ static bool content_filter_accepts (const dds_reader *reader, const struct ddsi_ case DDS_TOPIC_FILTER_SAMPLE_SAMPLEINFO_ARG: { char *tmp; tmp = ddsi_sertype_alloc_sample (tp->m_stype); - ddsi_serdata_to_sample (sample, tmp, NULL, NULL); - switch (tp->m_filter.mode) + if (!ddsi_serdata_to_sample (sample, tmp, NULL, NULL)) + { + // Samples we can't deserialize are (presumably) best never inserted + ret = false; + } + else { - case DDS_TOPIC_FILTER_NONE: - case DDS_TOPIC_FILTER_SAMPLEINFO_ARG: - assert (0); - case DDS_TOPIC_FILTER_SAMPLE: - ret = (tp->m_filter.f.sample) (tmp); - break; - case DDS_TOPIC_FILTER_SAMPLE_ARG: - ret = (tp->m_filter.f.sample_arg) (tmp, tp->m_filter.arg); - break; - case DDS_TOPIC_FILTER_SAMPLE_SAMPLEINFO_ARG: { - struct dds_sample_info si; - content_filter_make_sampleinfo (&si, sample, inst, wr_iid, iid); - ret = tp->m_filter.f.sample_sampleinfo_arg (tmp, &si, tp->m_filter.arg); - break; + switch (tp->m_filter.mode) + { + case DDS_TOPIC_FILTER_NONE: + case DDS_TOPIC_FILTER_SAMPLEINFO_ARG: + assert (0); + case DDS_TOPIC_FILTER_SAMPLE: + ret = (tp->m_filter.f.sample) (tmp); + break; + case DDS_TOPIC_FILTER_SAMPLE_ARG: + ret = (tp->m_filter.f.sample_arg) (tmp, tp->m_filter.arg); + break; + case DDS_TOPIC_FILTER_SAMPLE_SAMPLEINFO_ARG: { + struct dds_sample_info si; + content_filter_make_sampleinfo (&si, sample, inst, wr_iid, iid); + ret = tp->m_filter.f.sample_sampleinfo_arg (tmp, &si, tp->m_filter.arg); + break; + } } } ddsi_sertype_free_sample (tp->m_stype, tmp, DDS_FREE_ALL); @@ -2922,10 +2936,11 @@ static bool rhc_check_counts_locked (struct dds_rhc_default *rhc, bool check_con { struct rhc_sample *sample = inst->latest->next, * const end = sample; do { - ddsi_serdata_to_sample (sample->sample, rhc->qcond_eval_samplebuf, NULL, NULL); + // Follow error handling choices made in eval_predicate_sample() + const bool asifmatch = !ddsi_serdata_to_sample (sample->sample, rhc->qcond_eval_samplebuf, NULL, NULL); qcmask = 0; for (rciter = rhc->conds; rciter; rciter = rciter->m_next) - if (rciter->m_query.m_filter != 0 && rciter->m_query.m_filter (rhc->qcond_eval_samplebuf)) + if (rciter->m_query.m_filter != 0 && (asifmatch || rciter->m_query.m_filter (rhc->qcond_eval_samplebuf))) qcmask |= rciter->m_query.m_qcmask; assert ((sample->conds & enabled_qcmask) == qcmask); sample = sample->next; diff --git a/src/core/ddsc/src/dds_serdata_default.c b/src/core/ddsc/src/dds_serdata_default.c index a812721158..79bee52841 100644 --- a/src/core/ddsc/src/dds_serdata_default.c +++ b/src/core/ddsc/src/dds_serdata_default.c @@ -343,6 +343,9 @@ static bool gen_serdata_key_from_cdr (dds_istream_t * __restrict is, struct dds_ } /* Construct a serdata from a fragchain received over the network */ +static struct dds_serdata_default *serdata_default_from_ser_common (const struct ddsi_sertype *tpcmn, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size) + ddsrt_nonnull_all; + static struct dds_serdata_default *serdata_default_from_ser_common (const struct ddsi_sertype *tpcmn, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size) { const struct dds_sertype_default *tp = (const struct dds_sertype_default *)tpcmn; @@ -366,18 +369,17 @@ static struct dds_serdata_default *serdata_default_from_ser_common (const struct if (!is_valid_xcdr_id (d->hdr.identifier)) goto err; - while (fragchain) + for (const struct ddsi_rdata *frag = fragchain; frag != NULL; frag = frag->nextfrag) { - assert (fragchain->min <= off); - assert (fragchain->maxp1 <= size); - if (fragchain->maxp1 > off) + assert (frag->min <= off); + assert (frag->maxp1 <= size); + if (frag->maxp1 > off) { /* only copy if this fragment adds data */ - const unsigned char *payload = DDSI_RMSG_PAYLOADOFF (fragchain->rmsg, DDSI_RDATA_PAYLOAD_OFF (fragchain)); - serdata_default_append_blob (&d, fragchain->maxp1 - off, payload + off - fragchain->min); - off = fragchain->maxp1; + const unsigned char *payload = DDSI_RMSG_PAYLOADOFF (frag->rmsg, DDSI_RDATA_PAYLOAD_OFF (frag)); + serdata_default_append_blob (&d, frag->maxp1 - off, payload + off - frag->min); + off = frag->maxp1; } - fragchain = fragchain->nextfrag; } const bool needs_bswap = !DDSI_RTPS_CDR_ENC_IS_NATIVE (d->hdr.identifier); diff --git a/src/core/ddsc/tests/readcollect.c b/src/core/ddsc/tests/readcollect.c index a15d819978..eb5e41f7fc 100644 --- a/src/core/ddsc/tests/readcollect.c +++ b/src/core/ddsc/tests/readcollect.c @@ -29,10 +29,12 @@ typedef dds_return_t (*read_op) (dds_entity_t rd_or_cnd, uint32_t maxs, dds_inst static Space_Type1 getdata (const dds_sample_info_t *si, const struct ddsi_sertype *st, struct ddsi_serdata *sd) { Space_Type1 s; + bool ok; if (si->valid_data) - ddsi_serdata_to_sample (sd, &s, NULL, NULL); + ok = ddsi_serdata_to_sample (sd, &s, NULL, NULL); else - ddsi_serdata_untyped_to_sample (st, sd, &s, NULL, NULL); + ok = ddsi_serdata_untyped_to_sample (st, sd, &s, NULL, NULL); + CU_ASSERT_FATAL (ok); return s; } @@ -96,7 +98,7 @@ static void dotest (read_op op) rc = op (rd, INT32_MAX, 0, 0, coll_fail_after_1, &arg1); CU_ASSERT_FATAL (rc == 1); CU_ASSERT_FATAL (arg1.k >= 0 && arg1.k <= 2); - + // same should be true if instance handle is provided, use a different instance just because we can dds_instance_handle_t ih; rc = dds_register_instance (wr, &ih, &(Space_Type1){ .long_1 = (1+arg1.k)%3, .long_2 = 0, .long_3 = 0 }); @@ -107,11 +109,11 @@ static void dotest (read_op op) rc = op (rd, INT32_MAX, ih, 0, coll_fail_after_1, &arg2); CU_ASSERT_FATAL (rc == 1); CU_ASSERT_FATAL (arg2.k == (1+arg1.k)%3); - + assert (op == dds_peek_with_collector || op == dds_read_with_collector || op == dds_take_with_collector); bool isread = (op == dds_read_with_collector); bool isnew = (op == dds_peek_with_collector); - + // check that the remainder is as we expect it Space_Type1 xs[10]; dds_sample_info_t si[10]; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h index 6c3eca6d1e..c75607d6c4 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h @@ -51,10 +51,12 @@ struct ddsi_serdata { /* Serialised size of sample inclusive of DDSI encoding header - uint32_t because the protocol can't handle samples larger than 4GB anyway - FIXME: get the encoding header out of the serialised data */ -typedef uint32_t (*ddsi_serdata_size_t) (const struct ddsi_serdata *d); +typedef uint32_t (*ddsi_serdata_size_t) (const struct ddsi_serdata *d) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; /* Free a serdata (called by unref when refcount goes to 0) */ -typedef void (*ddsi_serdata_free_t) (struct ddsi_serdata *d); +typedef void (*ddsi_serdata_free_t) (struct ddsi_serdata *d) + ddsrt_nonnull_all; /* Construct a serdata from a fragchain received over the network - "kind" is KEY or DATA depending on the type of payload @@ -63,20 +65,24 @@ typedef void (*ddsi_serdata_free_t) (struct ddsi_serdata *d); - fragchains may overlap, though I have never seen any DDS implementation actually send such nasty fragments - FIXME: get the encoding header out of the serialised data */ -typedef struct ddsi_serdata * (*ddsi_serdata_from_ser_t) (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size); +typedef struct ddsi_serdata * (*ddsi_serdata_from_ser_t) (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; /* Exactly like ddsi_serdata_from_ser_t, but with the data in an iovec and guaranteed absence of overlap */ -typedef struct ddsi_serdata * (*ddsi_serdata_from_ser_iov_t) (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, ddsrt_msg_iovlen_t niov, const ddsrt_iovec_t *iov, size_t size); +typedef struct ddsi_serdata * (*ddsi_serdata_from_ser_iov_t) (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, ddsrt_msg_iovlen_t niov, const ddsrt_iovec_t *iov, size_t size) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; /* Construct a serdata from a keyhash (an SDK_KEY by definition) */ -typedef struct ddsi_serdata * (*ddsi_serdata_from_keyhash_t) (const struct ddsi_sertype *type, const struct ddsi_keyhash *keyhash); +typedef struct ddsi_serdata * (*ddsi_serdata_from_keyhash_t) (const struct ddsi_sertype *type, const struct ddsi_keyhash *keyhash) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; /* Construct a serdata from an application sample - "kind" is KEY or DATA depending on the operation invoked by the application; e.g., write results in kind = DATA, dispose in kind = KEY. The important bit is to not assume anything of the contents of non-key fields if kind = KEY unless additional application knowledge is available */ -typedef struct ddsi_serdata * (*ddsi_serdata_from_sample_t) (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const void *sample); +typedef struct ddsi_serdata * (*ddsi_serdata_from_sample_t) (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const void *sample) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; /* Construct a untyped serdata with just a keyvalue given a normal serdata (either key or data) - used for mapping key values to instance ids in tkmap @@ -86,7 +92,8 @@ typedef struct ddsi_serdata * (*ddsi_serdata_from_sample_t) (const struct ddsi_s field may have any value for a untyped serdata (so in some cases, one can simply do "return ddsi_serdata_ref(d);" */ -typedef struct ddsi_serdata * (*ddsi_serdata_to_untyped_t) (const struct ddsi_serdata *d); +typedef struct ddsi_serdata * (*ddsi_serdata_to_untyped_t) (const struct ddsi_serdata *d) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; /* Fill buffer with 'size' bytes of serialised data, starting from 'off' - 0 <= off < off+sz <= alignup4(size(d)) @@ -94,7 +101,8 @@ typedef struct ddsi_serdata * (*ddsi_serdata_to_untyped_t) (const struct ddsi_se - what to copy for bytes in [size(d), alignup4(size(d))) depends on the serdata implementation, the protocol treats them as undefined - FIXME: get the encoding header out of the serialised data */ -typedef void (*ddsi_serdata_to_ser_t) (const struct ddsi_serdata *d, size_t off, size_t sz, void *buf); +typedef void (*ddsi_serdata_to_ser_t) (const struct ddsi_serdata *d, size_t off, size_t sz, void *buf) + ddsrt_nonnull_all; /* Provide a pointer to 'size' bytes of serialised data, starting from 'off' - see ddsi_serdata_to_ser_t above @@ -103,11 +111,13 @@ typedef void (*ddsi_serdata_to_ser_t) (const struct ddsi_serdata *d, size_t off, - multiple calls to to_ser_ref() may be issued in parallel - lazily creating the serialised representation is allowed (though I'm not sure how that would work with knowing the serialised size beforehand ...) */ -typedef struct ddsi_serdata * (*ddsi_serdata_to_ser_ref_t) (const struct ddsi_serdata *d, size_t off, size_t sz, ddsrt_iovec_t *ref); +typedef struct ddsi_serdata * (*ddsi_serdata_to_ser_ref_t) (const struct ddsi_serdata *d, size_t off, size_t sz, ddsrt_iovec_t *ref) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; /* Release a lock on serialised data - ref was previousy filled by ddsi_serdata_to_ser_ref_t */ -typedef void (*ddsi_serdata_to_ser_unref_t) (struct ddsi_serdata *d, const ddsrt_iovec_t *ref); +typedef void (*ddsi_serdata_to_ser_unref_t) (struct ddsi_serdata *d, const ddsrt_iovec_t *ref) + ddsrt_nonnull_all; /* Turn serdata into an application sample (or just the key values if only key values are available); return false on error (typically out-of-memory, but if from_ser doesn't do any @@ -117,18 +127,21 @@ typedef void (*ddsi_serdata_to_ser_unref_t) (struct ddsi_serdata *d, const ddsrt padding) for any data in the sample that needs to be allocated (e.g., strings, sequences); otherwise malloc() is to be used for those. (This allows read/take to be given a block of memory by the caller.) */ -typedef bool (*ddsi_serdata_to_sample_t) (const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim); +typedef bool (*ddsi_serdata_to_sample_t) (const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim) + ddsrt_nonnull ((1, 2)) ddsrt_attribute_warn_unused_result; /* Create a sample from a untyped serdata, as returned by serdata_to_untyped. This sample obviously has just the key fields filled in and is used for generating invalid samples. */ -typedef bool (*ddsi_serdata_untyped_to_sample_t) (const struct ddsi_sertype *type, const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim); +typedef bool (*ddsi_serdata_untyped_to_sample_t) (const struct ddsi_sertype *type, const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim) + ddsrt_nonnull ((1, 2, 3)) ddsrt_attribute_warn_unused_result; /* Test key values of two serdatas for equality. The two will have the same ddsi_serdata_ops, but are not necessarily of the same topic (one can decide to never consider them equal if they are of different topics, of course; but the nice thing about _not_ doing that is that all instances with a certain key value with have the same instance id, and that in turn makes computing equijoins across topics much simpler). */ -typedef bool (*ddsi_serdata_eqkey_t) (const struct ddsi_serdata *a, const struct ddsi_serdata *b); +typedef bool (*ddsi_serdata_eqkey_t) (const struct ddsi_serdata *a, const struct ddsi_serdata *b) + ddsrt_nonnull_all; /* Print a serdata into the provided buffer (truncating as necessary) - topic is present for supporting printing of "untyped" samples @@ -137,20 +150,23 @@ typedef bool (*ddsi_serdata_eqkey_t) (const struct ddsi_serdata *a, const struct - returns the number of characters (excluding the terminating 0) needed to print it in full (or, as an optimization, it may pretend that it has printed it in full, returning bufsize-1) if it had to truncate) */ -typedef size_t (*ddsi_serdata_print_t) (const struct ddsi_sertype *type, const struct ddsi_serdata *d, char *buf, size_t size); +typedef size_t (*ddsi_serdata_print_t) (const struct ddsi_sertype *type, const struct ddsi_serdata *d, char *buf, size_t size) + ddsrt_nonnull_all; /* Add keyhash (from serdata) to buffer (forcing md5 when necessary). - key needs to be set within serdata (can already be md5) - buf needs to be at least 16 bytes large */ -typedef void (*ddsi_serdata_get_keyhash_t) (const struct ddsi_serdata *d, struct ddsi_keyhash *buf, bool force_md5); +typedef void (*ddsi_serdata_get_keyhash_t) (const struct ddsi_serdata *d, struct ddsi_keyhash *buf, bool force_md5) + ddsrt_nonnull_all; // Used for taking a loaned sample and constructing a serdata around this // takes over ownership of loan on success (leaves it unchanged on failure) -typedef struct ddsi_serdata* (*ddsi_serdata_from_loan_t) (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const char *sample, struct dds_loaned_sample *loaned_sample, bool will_require_cdr); +typedef struct ddsi_serdata* (*ddsi_serdata_from_loan_t) (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const char *sample, struct dds_loaned_sample *loaned_sample, bool will_require_cdr) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; // Used for constructing a serdata from data received on a PSMX -typedef struct ddsi_serdata* (*ddsi_serdata_from_psmx_t) (const struct ddsi_sertype *type, struct dds_loaned_sample *loaned_sample); - +typedef struct ddsi_serdata* (*ddsi_serdata_from_psmx_t) (const struct ddsi_sertype *type, struct dds_loaned_sample *loaned_sample) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; struct ddsi_serdata_ops { ddsi_serdata_eqkey_t eqkey; @@ -177,7 +193,8 @@ struct ddsi_serdata_ops { #define DDSI_SERDATA_HAS_GET_KEYHASH 1 /** @component typesupport_if */ -DDS_EXPORT void ddsi_serdata_init (struct ddsi_serdata *d, const struct ddsi_sertype *tp, enum ddsi_serdata_kind kind); +DDS_EXPORT void ddsi_serdata_init (struct ddsi_serdata *d, const struct ddsi_sertype *tp, enum ddsi_serdata_kind kind) + ddsrt_nonnull_all; /** * @brief Return a pointer to the keyhash in the message fragchain if it was present, or else NULL. @@ -224,7 +241,10 @@ struct ddsi_serdata *ddsi_serdata_ref_as_type (const struct ddsi_sertype *type, ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; /** @component typesupport_if */ -DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_ref (const struct ddsi_serdata *serdata_const) { +DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_ref (const struct ddsi_serdata *serdata_const) + ddsrt_nonnull_all; + +inline struct ddsi_serdata *ddsi_serdata_ref (const struct ddsi_serdata *serdata_const) { #if defined (__cplusplus) DDSRT_WARNING_GNUC_OFF(old-style-cast) DDSRT_WARNING_CLANG_OFF(old-style-cast) @@ -239,80 +259,125 @@ DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_ref (const struct dds } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline void ddsi_serdata_unref (struct ddsi_serdata *serdata) { +DDS_INLINE_EXPORT inline void ddsi_serdata_unref (struct ddsi_serdata *serdata) + ddsrt_nonnull_all; + +inline void ddsi_serdata_unref (struct ddsi_serdata *serdata) { if (ddsrt_atomic_dec32_ov (&serdata->refc) == 1) serdata->ops->free (serdata); } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline uint32_t ddsi_serdata_size (const struct ddsi_serdata *d) { +DDS_INLINE_EXPORT inline uint32_t ddsi_serdata_size (const struct ddsi_serdata *d) + ddsrt_nonnull_all; + +inline uint32_t ddsi_serdata_size (const struct ddsi_serdata *d) { return d->ops->get_size (d); } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_ser (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size) { +DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_ser (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; + +inline struct ddsi_serdata *ddsi_serdata_from_ser (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size) { return type->serdata_ops->from_ser (type, kind, fragchain, size); } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_ser_iov (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, ddsrt_msg_iovlen_t niov, const ddsrt_iovec_t *iov, size_t size) { +DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_ser_iov (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, ddsrt_msg_iovlen_t niov, const ddsrt_iovec_t *iov, size_t size) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; + +inline struct ddsi_serdata *ddsi_serdata_from_ser_iov (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, ddsrt_msg_iovlen_t niov, const ddsrt_iovec_t *iov, size_t size) { return type->serdata_ops->from_ser_iov (type, kind, niov, iov, size); } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_keyhash (const struct ddsi_sertype *type, const struct ddsi_keyhash *keyhash) { +DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_keyhash (const struct ddsi_sertype *type, const struct ddsi_keyhash *keyhash) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; + +inline struct ddsi_serdata *ddsi_serdata_from_keyhash (const struct ddsi_sertype *type, const struct ddsi_keyhash *keyhash) { return type->serdata_ops->from_keyhash (type, keyhash); } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_sample (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const void *sample) { +DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_sample (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const void *sample) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; + +inline struct ddsi_serdata *ddsi_serdata_from_sample (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const void *sample) { return type->serdata_ops->from_sample (type, kind, sample); } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_to_untyped (const struct ddsi_serdata *d) { +DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_to_untyped (const struct ddsi_serdata *d) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; + +inline struct ddsi_serdata *ddsi_serdata_to_untyped (const struct ddsi_serdata *d) { struct ddsi_serdata * const d1 = d->ops->to_untyped (d); assert (d1->loan == NULL); return d1; } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline void ddsi_serdata_to_ser (const struct ddsi_serdata *d, size_t off, size_t sz, void *buf) { +DDS_INLINE_EXPORT inline void ddsi_serdata_to_ser (const struct ddsi_serdata *d, size_t off, size_t sz, void *buf) + ddsrt_nonnull_all; + +inline void ddsi_serdata_to_ser (const struct ddsi_serdata *d, size_t off, size_t sz, void *buf) { d->ops->to_ser (d, off, sz, buf); } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_to_ser_ref (const struct ddsi_serdata *d, size_t off, size_t sz, ddsrt_iovec_t *ref) { +DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_to_ser_ref (const struct ddsi_serdata *d, size_t off, size_t sz, ddsrt_iovec_t *ref) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; + +inline struct ddsi_serdata *ddsi_serdata_to_ser_ref (const struct ddsi_serdata *d, size_t off, size_t sz, ddsrt_iovec_t *ref) { return d->ops->to_ser_ref (d, off, sz, ref); } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline void ddsi_serdata_to_ser_unref (struct ddsi_serdata *d, const ddsrt_iovec_t *ref) { +DDS_INLINE_EXPORT inline void ddsi_serdata_to_ser_unref (struct ddsi_serdata *d, const ddsrt_iovec_t *ref) + ddsrt_nonnull_all; + +inline void ddsi_serdata_to_ser_unref (struct ddsi_serdata *d, const ddsrt_iovec_t *ref) { d->ops->to_ser_unref (d, ref); } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline bool ddsi_serdata_to_sample (const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim) { +DDS_INLINE_EXPORT inline bool ddsi_serdata_to_sample (const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim) + ddsrt_nonnull ((1, 2)) ddsrt_attribute_warn_unused_result; + +inline bool ddsi_serdata_to_sample (const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim) { return d->ops->to_sample (d, sample, bufptr, buflim); } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline bool ddsi_serdata_untyped_to_sample (const struct ddsi_sertype *type, const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim) { +DDS_INLINE_EXPORT inline bool ddsi_serdata_untyped_to_sample (const struct ddsi_sertype *type, const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim) + ddsrt_nonnull ((1, 2, 3)) ddsrt_attribute_warn_unused_result; + +inline bool ddsi_serdata_untyped_to_sample (const struct ddsi_sertype *type, const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim) { return d->ops->untyped_to_sample (type, d, sample, bufptr, buflim); } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline bool ddsi_serdata_eqkey (const struct ddsi_serdata *a, const struct ddsi_serdata *b) { +DDS_INLINE_EXPORT inline bool ddsi_serdata_eqkey (const struct ddsi_serdata *a, const struct ddsi_serdata *b) + ddsrt_nonnull_all; + +inline bool ddsi_serdata_eqkey (const struct ddsi_serdata *a, const struct ddsi_serdata *b) { return a->ops->eqkey (a, b); } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline size_t ddsi_serdata_print (const struct ddsi_serdata *d, char *buf, size_t size) { +DDS_INLINE_EXPORT inline size_t ddsi_serdata_print (const struct ddsi_serdata *d, char *buf, size_t size) + ddsrt_nonnull_all; + +inline size_t ddsi_serdata_print (const struct ddsi_serdata *d, char *buf, size_t size) { return d->ops->print (d->type, d, buf, size); } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline size_t ddsi_serdata_print_untyped (const struct ddsi_sertype *type, const struct ddsi_serdata *d, char *buf, size_t size) { +DDS_INLINE_EXPORT inline size_t ddsi_serdata_print_untyped (const struct ddsi_sertype *type, const struct ddsi_serdata *d, char *buf, size_t size) + ddsrt_nonnull_all; + +inline size_t ddsi_serdata_print_untyped (const struct ddsi_sertype *type, const struct ddsi_serdata *d, char *buf, size_t size) { if (d->ops->print) return d->ops->print (type, d, buf, size); else @@ -323,22 +388,24 @@ DDS_INLINE_EXPORT inline size_t ddsi_serdata_print_untyped (const struct ddsi_se } /** @component typesupport_if */ -DDS_INLINE_EXPORT inline void ddsi_serdata_get_keyhash (const struct ddsi_serdata *d, struct ddsi_keyhash *buf, bool force_md5) { +DDS_INLINE_EXPORT inline void ddsi_serdata_get_keyhash (const struct ddsi_serdata *d, struct ddsi_keyhash *buf, bool force_md5) + ddsrt_nonnull_all; + +inline void ddsi_serdata_get_keyhash (const struct ddsi_serdata *d, struct ddsi_keyhash *buf, bool force_md5) { d->ops->get_keyhash (d, buf, force_md5); } DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_loaned_sample(const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const char *sample, struct dds_loaned_sample *loan, bool will_require_cdr) ddsrt_nonnull_all; /** @component typesupport_if */ -DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_loaned_sample(const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const char *sample, struct dds_loaned_sample *loan, bool will_require_cdr) +inline struct ddsi_serdata *ddsi_serdata_from_loaned_sample(const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const char *sample, struct dds_loaned_sample *loan, bool will_require_cdr) { return type->serdata_ops->from_loaned_sample(type, kind, sample, loan, will_require_cdr); } DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_psmx(const struct ddsi_sertype *type, struct dds_loaned_sample *data) ddsrt_nonnull_all; -/** @component typesupport_if */ -DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_psmx(const struct ddsi_sertype *type, struct dds_loaned_sample *data) +inline struct ddsi_serdata *ddsi_serdata_from_psmx(const struct ddsi_sertype *type, struct dds_loaned_sample *data) { return type->serdata_ops->from_psmx(type, data); } diff --git a/src/core/ddsi/src/ddsi_security_msg.c b/src/core/ddsi/src/ddsi_security_msg.c index ec00b336f3..807b3a6f21 100644 --- a/src/core/ddsi/src/ddsi_security_msg.c +++ b/src/core/ddsi/src/ddsi_security_msg.c @@ -175,7 +175,7 @@ int ddsi_volatile_secure_data_filter(struct ddsi_writer *wr, struct ddsi_proxy_r assert(serdata); /* guid_offset + 4 because 4 bytes header is at 0 */ - (void)ddsi_serdata_to_ser_ref(serdata, guid_offset + 4, sizeof(ddsi_guid_t), &guid_ref); + struct ddsi_serdata *serdata_ref = ddsi_serdata_to_ser_ref(serdata, guid_offset + 4, sizeof(ddsi_guid_t), &guid_ref); assert(guid_ref.iov_len == sizeof(ddsi_guid_t)); assert(guid_ref.iov_base); msg_guid = (ddsi_guid_t*)guid_ref.iov_base; @@ -187,7 +187,7 @@ int ddsi_volatile_secure_data_filter(struct ddsi_writer *wr, struct ddsi_proxy_r pass = ddsi_guid_eq(msg_guid, &pp_guid); } - ddsi_serdata_to_ser_unref(serdata, &guid_ref); + ddsi_serdata_to_ser_unref(serdata_ref, &guid_ref); return pass; } diff --git a/src/core/ddsi/src/ddsi_serdata_cdr.c b/src/core/ddsi/src/ddsi_serdata_cdr.c index e809130057..13645dcd68 100644 --- a/src/core/ddsi/src/ddsi_serdata_cdr.c +++ b/src/core/ddsi/src/ddsi_serdata_cdr.c @@ -128,6 +128,9 @@ static inline bool is_valid_xcdr_id (unsigned short cdr_identifier) } /* Construct a serdata from a fragchain received over the network */ +static struct ddsi_serdata_cdr *serdata_cdr_from_ser_common (const struct ddsi_sertype *tpcmn, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size) + ddsrt_nonnull_all; + static struct ddsi_serdata_cdr *serdata_cdr_from_ser_common (const struct ddsi_sertype *tpcmn, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size) { assert (kind == SDK_DATA); diff --git a/src/core/ddsi/src/ddsi_serdata_plist.c b/src/core/ddsi/src/ddsi_serdata_plist.c index 911618b5f5..34c3869d15 100644 --- a/src/core/ddsi/src/ddsi_serdata_plist.c +++ b/src/core/ddsi/src/ddsi_serdata_plist.c @@ -99,6 +99,9 @@ static struct ddsi_serdata *serdata_plist_fix (const struct ddsi_sertype_plist * return &d->c; } +static struct ddsi_serdata *serdata_plist_from_ser (const struct ddsi_sertype *tpcmn, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size) + ddsrt_nonnull_all; + static struct ddsi_serdata *serdata_plist_from_ser (const struct ddsi_sertype *tpcmn, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size) { const struct ddsi_sertype_plist *tp = (const struct ddsi_sertype_plist *) tpcmn; @@ -108,20 +111,19 @@ static struct ddsi_serdata *serdata_plist_from_ser (const struct ddsi_sertype *t uint32_t off = 4; /* must skip the CDR header */ assert (fragchain->min == 0); assert (fragchain->maxp1 >= off); /* CDR header must be in first fragment */ - while (fragchain) + for (const struct ddsi_rdata *frag = fragchain; frag != NULL; frag = frag->nextfrag) { - assert (fragchain->min <= off); - assert (fragchain->maxp1 <= size); - if (fragchain->maxp1 > off) + assert (frag->min <= off); + assert (frag->maxp1 <= size); + if (frag->maxp1 > off) { /* only copy if this fragment adds data */ - const unsigned char *payload = DDSI_RMSG_PAYLOADOFF (fragchain->rmsg, DDSI_RDATA_PAYLOAD_OFF (fragchain)); - uint32_t n = fragchain->maxp1 - off; - memcpy (d->data + d->pos, payload + off - fragchain->min, n); + const unsigned char *payload = DDSI_RMSG_PAYLOADOFF (frag->rmsg, DDSI_RDATA_PAYLOAD_OFF (frag)); + uint32_t n = frag->maxp1 - off; + memcpy (d->data + d->pos, payload + off - frag->min, n); d->pos += n; - off = fragchain->maxp1; + off = frag->maxp1; } - fragchain = fragchain->nextfrag; } return serdata_plist_fix (tp, d); } diff --git a/src/core/ddsi/src/ddsi_serdata_pserop.c b/src/core/ddsi/src/ddsi_serdata_pserop.c index 1241e66feb..3bee78e371 100644 --- a/src/core/ddsi/src/ddsi_serdata_pserop.c +++ b/src/core/ddsi/src/ddsi_serdata_pserop.c @@ -106,6 +106,9 @@ static struct ddsi_serdata *serdata_pserop_fix (const struct ddsi_sertype_pserop return &d->c; } +static struct ddsi_serdata *serdata_pserop_from_ser (const struct ddsi_sertype *tpcmn, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size) + ddsrt_nonnull_all; + static struct ddsi_serdata *serdata_pserop_from_ser (const struct ddsi_sertype *tpcmn, enum ddsi_serdata_kind kind, const struct ddsi_rdata *fragchain, size_t size) { const struct ddsi_sertype_pserop *tp = (const struct ddsi_sertype_pserop *)tpcmn; @@ -115,20 +118,19 @@ static struct ddsi_serdata *serdata_pserop_from_ser (const struct ddsi_sertype * uint32_t off = 4; /* must skip the CDR header */ assert (fragchain->min == 0); assert (fragchain->maxp1 >= off); /* CDR header must be in first fragment */ - while (fragchain) + for (const struct ddsi_rdata *frag = fragchain; frag != NULL; frag = frag->nextfrag) { - assert (fragchain->min <= off); - assert (fragchain->maxp1 <= size); - if (fragchain->maxp1 > off) + assert (frag->min <= off); + assert (frag->maxp1 <= size); + if (frag->maxp1 > off) { /* only copy if this fragment adds data */ - const unsigned char *payload = DDSI_RMSG_PAYLOADOFF (fragchain->rmsg, DDSI_RDATA_PAYLOAD_OFF (fragchain)); - uint32_t n = fragchain->maxp1 - off; - memcpy (d->data + d->pos, payload + off - fragchain->min, n); + const unsigned char *payload = DDSI_RMSG_PAYLOADOFF (frag->rmsg, DDSI_RDATA_PAYLOAD_OFF (frag)); + uint32_t n = frag->maxp1 - off; + memcpy (d->data + d->pos, payload + off - frag->min, n); d->pos += n; - off = fragchain->maxp1; + off = frag->maxp1; } - fragchain = fragchain->nextfrag; } return serdata_pserop_fix (tp, d); } diff --git a/src/core/ddsi/src/ddsi_typelookup.c b/src/core/ddsi/src/ddsi_typelookup.c index 1bea696983..552610c186 100644 --- a/src/core/ddsi/src/ddsi_typelookup.c +++ b/src/core/ddsi/src/ddsi_typelookup.c @@ -276,7 +276,12 @@ void ddsi_tl_handle_request (struct ddsi_domaingv *gv, struct ddsi_serdata *d) DDS_Builtin_TypeLookup_Request req; memset (&req, 0, sizeof (req)); - ddsi_serdata_to_sample (d, &req, NULL, NULL); + if (!ddsi_serdata_to_sample (d, &req, NULL, NULL)) + { + GVTRACE (" handle-tl-req deserialization failed"); + return; + } + if (req.data._d != DDS_Builtin_TypeLookup_getTypes_HashId) { GVTRACE (" handle-tl-req wr "PGUIDFMT " unknown req-type %"PRIi32, PGUID (from_guid (&req.header.requestId.writer_guid)), req.data._d); @@ -384,7 +389,11 @@ void ddsi_tl_handle_reply (struct ddsi_domaingv *gv, struct ddsi_serdata *d) DDS_Builtin_TypeLookup_Reply reply; memset (&reply, 0, sizeof (reply)); - ddsi_serdata_to_sample (d, &reply, NULL, NULL); + if (!ddsi_serdata_to_sample (d, &reply, NULL, NULL)) + { + GVTRACE (" handle-tl-req deserialization failed"); + return; + } if (reply.return_data._d != DDS_Builtin_TypeLookup_getTypes_HashId) { GVTRACE (" handle-tl-reply wr "PGUIDFMT " unknown reply-type %"PRIi32, PGUID (from_guid (&reply.header.relatedRequestId.writer_guid)), reply.return_data._d); diff --git a/src/core/xtests/rhc_torture/rhc_torture.c b/src/core/xtests/rhc_torture/rhc_torture.c index dc865eb048..8d4f0b8605 100644 --- a/src/core/xtests/rhc_torture/rhc_torture.c +++ b/src/core/xtests/rhc_torture/rhc_torture.c @@ -145,7 +145,8 @@ static uint64_t store (struct ddsi_tkmap *tkmap, struct dds_rhc *rhc, struct dds char si_d = (sd->statusinfo & DDSI_STATUSINFO_DISPOSE) ? 'D' : '.'; char si_u = (sd->statusinfo & DDSI_STATUSINFO_UNREGISTER) ? 'U' : '.'; memset (&d, 0, sizeof (d)); - ddsi_serdata_to_sample (sd, &d, NULL, NULL); + if (!ddsi_serdata_to_sample (sd, &d, NULL, NULL)) + abort (); (void) print_tstamp (buf, sizeof (buf), sd->timestamp.v); if (sd->kind == SDK_KEY) printf ("STORE %c%c %16"PRIx64" %16"PRIx64" %2"PRId32" %6s %s\n", si_u, si_d, iid, wr->e.iid, d.k, "_", buf); diff --git a/src/core/xtests/symbol_export/symbol_export.c b/src/core/xtests/symbol_export/symbol_export.c index bcc880f3c1..c425a740d5 100644 --- a/src/core/xtests/symbol_export/symbol_export.c +++ b/src/core/xtests/symbol_export/symbol_export.c @@ -74,6 +74,8 @@ #include "dds__write.h" // dds_write_impl, dds_writecdr_impl DDSRT_WARNING_DEPRECATED_OFF +DDSRT_WARNING_GNUC_OFF (unused-result) +DDSRT_WARNING_CLANG_OFF (unused-result) DDSRT_WARNING_CLANG_OFF(unused-result) DDSRT_WARNING_GNUC_OFF(unused-result) From 91b446c5f257b1bda73f16f7dc29b4f84c81530d Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 18 Jul 2023 09:05:56 +0200 Subject: [PATCH 041/207] Minor changes for gcc analyzer * We don't care about malloc failures in "dynsub", asserting the result is not a null pointer pacifies the analyzer * The roundtrip example had an "interesting" way of updating the statistics object that caused a false-positive leak warning from the analyzer. The warning disappears by simply eliminating the interesting bit * Some false positives on leaking file descriptors in TCP support code * Ouput buffer size in snprintf that was flagged as potentially too small (which it is true if the integer being printed can have any valid value, but it can't) * Some warnings related to possible malloc failures in ucunit Signed-off-by: Erik Boasson --- examples/dynsub/dynsub.c | 1 + examples/dynsub/type_cache.c | 7 +++++++ examples/roundtrip/ping.c | 17 +++++++---------- src/core/ddsi/src/ddsi_tcp.c | 6 ++++++ src/core/xtests/rhc_torture/rhc_torture.c | 2 +- src/idl/src/file.c | 3 ++- src/ucunit/src/ucunit.c | 8 ++++++++ 7 files changed, 32 insertions(+), 12 deletions(-) diff --git a/examples/dynsub/dynsub.c b/examples/dynsub/dynsub.c index 8de1b843ea..a224209c52 100644 --- a/examples/dynsub/dynsub.c +++ b/examples/dynsub/dynsub.c @@ -121,6 +121,7 @@ static dds_return_t get_topic_and_typeobj (const char *topic_name, dds_duration_ { // not sure whether this is at all possible info = malloc (sizeof (*info)); + assert (info); *info = (struct typeinfo){ .key = { .key = (uintptr_t) *xtypeobj }, .typeobj = &(*xtypeobj)->_u.complete, .release = *xtypeobj, .align = align, .size = size }; type_cache_add (info); } diff --git a/examples/dynsub/type_cache.c b/examples/dynsub/type_cache.c index da845709d0..d755eefe82 100644 --- a/examples/dynsub/type_cache.c +++ b/examples/dynsub/type_cache.c @@ -252,6 +252,7 @@ static void build_typecache_ti (const DDS_XTypes_TypeIdentifier *typeid, size_t const DDS_XTypes_CompleteTypeObject *tobj = get_complete_typeobj_for_hashid (typeid->_u.equivalence_hash); build_typecache_to (tobj, align, size); info = malloc (sizeof (*info)); + assert (info); *info = (struct typeinfo){ .key = { .key = (uintptr_t) typeid }, .typeobj = tobj, .release = NULL, .align = *align, .size = *size }; type_cache_add (info); } @@ -289,6 +290,7 @@ void build_typecache_to (const DDS_XTypes_CompleteTypeObject *typeobj, size_t *a *align = sizeof (int); *size = sizeof (int); info = malloc (sizeof (*info)); + assert (info); *info = (struct typeinfo){ .key = { .key = (uintptr_t) typeobj }, .typeobj = typeobj, .release = NULL, .align = *align, .size = *size }; ddsrt_hh_add (typecache, info); } @@ -310,6 +312,7 @@ void build_typecache_to (const DDS_XTypes_CompleteTypeObject *typeobj, size_t *a else *align = *size = 1; info = malloc (sizeof (*info)); + assert (info); *info = (struct typeinfo){ .key = { .key = (uintptr_t) typeobj }, .typeobj = typeobj, .release = NULL, .align = *align, .size = *size }; ddsrt_hh_add (typecache, info); } @@ -327,6 +330,7 @@ void build_typecache_to (const DDS_XTypes_CompleteTypeObject *typeobj, size_t *a *align = a; *size = s; info = malloc (sizeof (*info)); + assert (info); *info = (struct typeinfo){ .key = { .key = (uintptr_t) typeobj }, .typeobj = typeobj, .release = NULL, .align = *align, .size = *size }; ddsrt_hh_add (typecache, info); } @@ -354,6 +358,7 @@ void build_typecache_to (const DDS_XTypes_CompleteTypeObject *typeobj, size_t *a if (*size % *align) *size += *align - (*size % *align); info = malloc (sizeof (*info)); + assert (info); *info = (struct typeinfo){ .key = { .key = (uintptr_t) typeobj }, .typeobj = typeobj, .release = NULL, .align = *align, .size = *size }; ddsrt_hh_add (typecache, info); } @@ -391,6 +396,7 @@ void build_typecache_to (const DDS_XTypes_CompleteTypeObject *typeobj, size_t *a if (*size % *align) *size += *align - (*size % *align); info = malloc (sizeof (*info)); + assert (info); *info = (struct typeinfo){ .key = { .key = (uintptr_t) typeobj }, .typeobj = typeobj, .release = NULL, .align = *align, .size = *size }; ddsrt_hh_add (typecache, info); } @@ -468,6 +474,7 @@ static bool load_deps_ti (dds_entity_t participant, const DDS_XTypes_TypeIdentif return load_deps_failed (); DDS_XTypes_TypeObject * const xtypeobj = (DDS_XTypes_TypeObject *) typeobj; info = malloc (sizeof (*info)); + assert (info); memcpy (info->id, typeid->_u.equivalence_hash, sizeof (info->id)); info->typeobj = xtypeobj; info->lineno = 0; diff --git a/examples/roundtrip/ping.c b/examples/roundtrip/ping.c index 1c58801247..244c4470df 100644 --- a/examples/roundtrip/ping.c +++ b/examples/roundtrip/ping.c @@ -53,8 +53,7 @@ static void exampleDeleteTimeStats (ExampleTimeStats *stats) free (stats->values); } -static ExampleTimeStats *exampleAddTimingToTimeStats - (ExampleTimeStats *stats, dds_time_t timing) +static void exampleAddTimingToTimeStats (ExampleTimeStats *stats, dds_time_t timing) { if (stats->valuesSize > stats->valuesMax) { @@ -70,8 +69,6 @@ static ExampleTimeStats *exampleAddTimingToTimeStats stats->min = (stats->count == 0 || timing < stats->min) ? timing : stats->min; stats->max = (stats->count == 0 || timing > stats->max) ? timing : stats->max; stats->count++; - - return stats; } static int exampleCompareul (const void* a, const void* b) @@ -166,16 +163,16 @@ static void data_available(dds_entity_t rd, void *arg) /* Update stats */ difference = (postWriteTime - preWriteTime)/DDS_NSECS_IN_USEC; - writeAccess = *exampleAddTimingToTimeStats (&writeAccess, difference); - writeAccessOverall = *exampleAddTimingToTimeStats (&writeAccessOverall, difference); + exampleAddTimingToTimeStats (&writeAccess, difference); + exampleAddTimingToTimeStats (&writeAccessOverall, difference); difference = (postTakeTime - preTakeTime)/DDS_NSECS_IN_USEC; - readAccess = *exampleAddTimingToTimeStats (&readAccess, difference); - readAccessOverall = *exampleAddTimingToTimeStats (&readAccessOverall, difference); + exampleAddTimingToTimeStats (&readAccess, difference); + exampleAddTimingToTimeStats (&readAccessOverall, difference); difference = (postTakeTime - info[0].source_timestamp)/DDS_NSECS_IN_USEC; - roundTrip = *exampleAddTimingToTimeStats (&roundTrip, difference); - roundTripOverall = *exampleAddTimingToTimeStats (&roundTripOverall, difference); + exampleAddTimingToTimeStats (&roundTrip, difference); + exampleAddTimingToTimeStats (&roundTripOverall, difference); if (!warmUp) { /* Print stats each second */ diff --git a/src/core/ddsi/src/ddsi_tcp.c b/src/core/ddsi/src/ddsi_tcp.c index 8f7ef47fbb..676f2c6293 100644 --- a/src/core/ddsi/src/ddsi_tcp.c +++ b/src/core/ddsi/src/ddsi_tcp.c @@ -816,6 +816,9 @@ static dds_return_t ddsi_tcp_create_conn (struct ddsi_tran_conn **conn_out, stru return DDS_RETCODE_OK; } +#if defined __GNUC__ && __GNUC__ >= 13 +DDSRT_WARNING_GNUC_OFF (analyzer-fd-leak) +#endif static int ddsi_tcp_listen (struct ddsi_tran_listener * listener) { #ifdef DDS_HAS_TCP_TLS @@ -833,6 +836,9 @@ static int ddsi_tcp_listen (struct ddsi_tran_listener * listener) return ret; } +#if defined __GNUC__ && __GNUC__ >= 13 +DDSRT_WARNING_GNUC_ON (analyzer-fd-leak) +#endif static struct ddsi_tran_conn * ddsi_tcp_accept (struct ddsi_tran_listener * listener) { diff --git a/src/core/xtests/rhc_torture/rhc_torture.c b/src/core/xtests/rhc_torture/rhc_torture.c index 8d4f0b8605..738c537ea1 100644 --- a/src/core/xtests/rhc_torture/rhc_torture.c +++ b/src/core/xtests/rhc_torture/rhc_torture.c @@ -652,7 +652,7 @@ static void test_conditions (dds_entity_t pp, dds_entity_t tp, const int count, if (conds[ci] <= 0) abort (); rhcconds[ci] = get_condaddr (conds[ci]); if (print) { - char buf[18]; + char buf[19]; snprintf (buf, sizeof (buf), "conds[%d]", ci); print_cond_w_addr (buf, conds[ci]); } diff --git a/src/idl/src/file.c b/src/idl/src/file.c index 79e97d846e..982d97edad 100644 --- a/src/idl/src/file.c +++ b/src/idl/src/file.c @@ -477,7 +477,8 @@ idl_retcode_t idl_generate_out_file(const char *path, const char *output_dir, co if (!(basename = idl_strndup(file, ext ? (size_t)(ext-file) : strlen(file)))) goto err_basename; - /* replace backslashes by forward slashes */ + /* replace backslashes by forward slashes; assert for gcc 13 static analyzer */ + assert (dir != empty || *dir == '\0'); for (char *ptr = dir; *ptr; ptr++) { if (*ptr == '\\') *ptr = '/'; diff --git a/src/ucunit/src/ucunit.c b/src/ucunit/src/ucunit.c index 3f547ec149..ee6a3783da 100644 --- a/src/ucunit/src/ucunit.c +++ b/src/ucunit/src/ucunit.c @@ -53,6 +53,8 @@ void CU_assertImplementation (bool value, int line, const char *expr, const char failure_count++; cur_test->nfailures++; struct CU_FailureRecord *fr = malloc (sizeof (*fr)); + if (fr == NULL) + abort (); fr->file = file; fr->line = line; fr->expr = expr; @@ -93,6 +95,8 @@ static char *ucunit_strdup (const char *s) { size_t l = strlen (s) + 1; char *n = malloc (l); + if (n == NULL) + abort (); memcpy (n, s, l); return n; } @@ -105,6 +109,8 @@ CU_pSuite CU_add_suite (const char *strName, CU_InitializeFunc pInit, CU_Cleanup if (cur != NULL) return cur; cur = malloc (sizeof (*cur)); + if (cur == NULL) + abort (); cur->name = ucunit_strdup (strName); cur->init = pInit; cur->cleanup = pClean; @@ -145,6 +151,8 @@ CU_pTest CU_add_test (CU_pSuite pSuite, const char *strName, CU_TestFunc pTestFu if (cur != NULL) return cur; cur = malloc (sizeof (*cur)); + if (cur == NULL) + abort (); cur->name = ucunit_strdup (strName); cur->testfunc = pTestFunc; cur->next = NULL; From 32f3139e9df711323a129df5968d4575451af542 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Wed, 20 Mar 2024 12:29:03 +0100 Subject: [PATCH 042/207] GCC analyzer dislikes non-null arg as loop var This despite the variable getting reassigned by a potentially null pointer. Using a separete variable solves the problem and is arguably better style. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_gc.c | 7 ++++--- src/core/ddsi/src/ddsi_serdata_cdr.c | 15 +++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/ddsi/src/ddsi_gc.c b/src/core/ddsi/src/ddsi_gc.c index 5be145ac69..4df45d7564 100644 --- a/src/core/ddsi/src/ddsi_gc.c +++ b/src/core/ddsi/src/ddsi_gc.c @@ -35,14 +35,15 @@ struct ddsi_gcreq_queue { struct ddsi_thread_state *thrst; }; -static void threads_vtime_gather_for_wait (const struct ddsi_domaingv *gv, uint32_t *nivs, struct ddsi_idx_vtime *ivs, struct ddsi_thread_states_list *cur) +static void threads_vtime_gather_for_wait (const struct ddsi_domaingv *gv, uint32_t *nivs, struct ddsi_idx_vtime *ivs, struct ddsi_thread_states_list *tslist) { /* copy vtimes of threads, skipping those that are sleeping */ #ifndef NDEBUG - const uint32_t nthreads = cur->nthreads; + const uint32_t nthreads = tslist->nthreads; #endif + struct ddsi_thread_states_list *cur; uint32_t dstidx; - for (dstidx = 0; cur; cur = cur->next) + for (dstidx = 0, cur = tslist; cur; cur = cur->next) { for (uint32_t i = 0; i < DDSI_THREAD_STATE_BATCH; i++) { diff --git a/src/core/ddsi/src/ddsi_serdata_cdr.c b/src/core/ddsi/src/ddsi_serdata_cdr.c index 13645dcd68..64df0aac46 100644 --- a/src/core/ddsi/src/ddsi_serdata_cdr.c +++ b/src/core/ddsi/src/ddsi_serdata_cdr.c @@ -155,18 +155,17 @@ static struct ddsi_serdata_cdr *serdata_cdr_from_ser_common (const struct ddsi_s if (!is_valid_xcdr_id (d->hdr.identifier)) goto err; - while (fragchain) + for (const struct ddsi_rdata *frag = fragchain; frag != NULL; frag = frag->nextfrag) { - assert (fragchain->min <= off); - assert (fragchain->maxp1 <= size); - if (fragchain->maxp1 > off) + assert (frag->min <= off); + assert (frag->maxp1 <= size); + if (frag->maxp1 > off) { /* only copy if this fragment adds data */ - const unsigned char *payload = DDSI_RMSG_PAYLOADOFF (fragchain->rmsg, DDSI_RDATA_PAYLOAD_OFF (fragchain)); - serdata_cdr_append_blob (&d, fragchain->maxp1 - off, payload + off - fragchain->min); - off = fragchain->maxp1; + const unsigned char *payload = DDSI_RMSG_PAYLOADOFF (frag->rmsg, DDSI_RDATA_PAYLOAD_OFF (frag)); + serdata_cdr_append_blob (&d, frag->maxp1 - off, payload + off - frag->min); + off = frag->maxp1; } - fragchain = fragchain->nextfrag; } const bool needs_bswap = !DDSI_RTPS_CDR_ENC_IS_NATIVE (d->hdr.identifier); From 0f07fe76a5c2f5822faaf3a0bf28ba1421ea2e31 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 21 Mar 2024 11:59:18 +0100 Subject: [PATCH 043/207] Suppress some warnings in mcpp --- src/tools/idlpp/src/expand.c | 8 ++++++++ src/tools/idlpp/src/system.c | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/tools/idlpp/src/expand.c b/src/tools/idlpp/src/expand.c index 27b6b157f0..30c4e1ffad 100644 --- a/src/tools/idlpp/src/expand.c +++ b/src/tools/idlpp/src/expand.c @@ -479,6 +479,11 @@ static char * print_macro_arg( * This routine is only called from above print_macro_inf(). */ { +#if defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 1300 && ((__GNUC__ * 100) + __GNUC_MINOR__) < 1302 +_Pragma("GCC diagnostic push") +_Pragma("GCC diagnostic ignored \"-Wformat-overflow\"") +_Pragma("GCC diagnostic ignored \"-Warray-bounds\"") +#endif LOCATION * loc = m_inf->loc_args + argn; out += sprintf( out, "/*%s%s:%d-%d", real_arg ? "!" : (start ? "<" : "") @@ -495,6 +500,9 @@ static char * print_macro_arg( out = stpcpy( out, "*/"); return out; +#if defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 1300 && ((__GNUC__ * 100) + __GNUC_MINOR__) < 1302 +_Pragma("GCC diagnostic pop") +#endif } static char * chk_magic_balance( diff --git a/src/tools/idlpp/src/system.c b/src/tools/idlpp/src/system.c index ba3e7654d6..9c55fc3abe 100644 --- a/src/tools/idlpp/src/system.c +++ b/src/tools/idlpp/src/system.c @@ -2517,6 +2517,10 @@ static char * norm_path( * open_file(). */ { +#if !defined (__clang__) && defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 1300 && ((__GNUC__ * 100) + __GNUC_MINOR__) < 1302 +_Pragma("GCC diagnostic push") +_Pragma("GCC diagnostic ignored \"-Wstringop-overread\"") +#endif char * norm_name; /* The path-list converted */ char * start; char * cp1; @@ -2771,6 +2775,9 @@ static char * norm_path( } return norm_name; +#if !defined (__clang__) && defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 1300 && ((__GNUC__ * 100) + __GNUC_MINOR__) < 1302 +_Pragma("GCC diagnostic pop") +#endif } #if SYS_FAMILY == SYS_UNIX @@ -4669,6 +4676,12 @@ static void do_preprocessed( void) * Install macros according the #define directives. */ { +#if !defined (__clang__) && defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 1300 && ((__GNUC__ * 100) + __GNUC_MINOR__) < 1302 +_Pragma("GCC diagnostic push") +_Pragma("GCC diagnostic ignored \"-Wnonnull\"") +_Pragma("GCC diagnostic ignored \"-Warray-bounds\"") +_Pragma("GCC diagnostic ignored \"-Wstringop-overread\"") +#endif const char * corrupted = "This preprocessed file is corrupted"; /* _F_ */ FILEINFO * file; @@ -4753,6 +4766,9 @@ static void do_preprocessed( void) unget_ch(); /* infile == file */ } file->bptr = file->buffer + strlen( file->buffer); +#if !defined (__clang__) && defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 1300 && ((__GNUC__ * 100) + __GNUC_MINOR__) < 1302 +_Pragma("GCC diagnostic pop") +#endif } static int do_debug( From 1c073c191e5e88c3db7afe1daf08d7785d0bcbc3 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 21 Mar 2024 11:59:36 +0100 Subject: [PATCH 044/207] Allow some warnings for gcc 13.0 and 13.1 There are false positive warnings for - stringop-overflow - array-bounds that don't seem to be suppressible using Pragmas. From what I can tell, they occur on gcc 13.1 but not gcc 13.2. Sadly, gcc 13.1 is the latest version of gcc that is available on Ubuntu 22.04, so this would imply being stuck on a really old gcc version in the CI where we use -Werror. This commit prevents these two warnings from being treated as errors, but only if it is gcc 13.0 or gcc 13.1. That way the risk of not treating them as errors should be minimized. Signed-off-by: Erik Boasson --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c02059129..fa04d62b6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -134,6 +134,10 @@ elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") if(${WERROR}) add_compile_options(-Werror) add_link_options(-Werror) + if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0 AND CMAKE_C_COMPILER_VERSION VERSION_LESS 13.2) + add_compile_options(-Wno-error=stringop-overflow -Wno-error=array-bounds) + add_link_options(-Wno-error=stringop-overflow -Wno-error=array-bounds) + endif() endif() if("${CMAKE_GENERATOR}" STREQUAL "Ninja") add_compile_options(-fdiagnostics-color=always) From dfdbaf1578756dd63046ad76ed7c7d725034e7f1 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 21 Mar 2024 10:15:09 +0100 Subject: [PATCH 045/207] Add -rpath to macOS idlc/xtests build flags --- src/tools/idlc/xtests/Compile.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/idlc/xtests/Compile.cmake b/src/tools/idlc/xtests/Compile.cmake index a3bd5c1237..17f939b594 100644 --- a/src/tools/idlc/xtests/Compile.cmake +++ b/src/tools/idlc/xtests/Compile.cmake @@ -52,6 +52,9 @@ else() set(ENV{LIBRARY_PATH} "$ENV{LIBRARY_PATH}:$ENV{CDDS_LIB_PATH}") set(_output_flag "-o") set(_lib_path "") + if(APPLE) + list(APPEND _lib_path "-rpath" "$ENV{CDDS_LIB_PATH}") + endif() set(_lib "-lddsc") set(_fdbg "-g") set(_fwarn "-Wall") @@ -141,4 +144,4 @@ foreach(_source ${_sources}) message(FATAL_ERROR "Test failed ${_source}: ${_result} ${_error}") endif() -endforeach() \ No newline at end of file +endforeach() From 8a16a76b27569b2d5c30f0b4c1de3205fdf4a1ee Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 10 Aug 2023 10:04:13 +0200 Subject: [PATCH 046/207] Add non-null, &c attributes to xmsg.h Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi__xmsg.h | 136 +++++++++++++++++---------- src/core/ddsi/src/ddsi_xmsg.c | 25 +++-- src/core/ddsi/tests/plist_leasedur.c | 6 +- 3 files changed, 110 insertions(+), 57 deletions(-) diff --git a/src/core/ddsi/src/ddsi__xmsg.h b/src/core/ddsi/src/ddsi__xmsg.h index 9b1c8c2220..9bcab56391 100644 --- a/src/core/ddsi/src/ddsi__xmsg.h +++ b/src/core/ddsi/src/ddsi__xmsg.h @@ -47,10 +47,12 @@ enum ddsi_xmsg_kind { }; /** @component rtps_submsg */ -struct ddsi_xmsgpool *ddsi_xmsgpool_new (void); +struct ddsi_xmsgpool *ddsi_xmsgpool_new (void) + ddsrt_attribute_warn_unused_result; /** @component rtps_submsg */ -void ddsi_xmsgpool_free (struct ddsi_xmsgpool *pool); +void ddsi_xmsgpool_free (struct ddsi_xmsgpool *pool) + ddsrt_nonnull_all; /** * @brief Allocates a new xmsg from the pool @@ -67,7 +69,8 @@ void ddsi_xmsgpool_free (struct ddsi_xmsgpool *pool); * @param kind the xmsg kind * @return struct ddsi_xmsg* */ -struct ddsi_xmsg *ddsi_xmsg_new (struct ddsi_xmsgpool *pool, const ddsi_guid_t *src_guid, struct ddsi_participant *pp, size_t expected_size, enum ddsi_xmsg_kind kind); +struct ddsi_xmsg *ddsi_xmsg_new (struct ddsi_xmsgpool *pool, const ddsi_guid_t *src_guid, struct ddsi_participant *pp, size_t expected_size, enum ddsi_xmsg_kind kind) + ddsrt_nonnull ((1, 2)) ddsrt_attribute_warn_unused_result; /** * @brief For sending to a particular destination (participant) @@ -76,12 +79,13 @@ struct ddsi_xmsg *ddsi_xmsg_new (struct ddsi_xmsgpool *pool, const ddsi_guid_t * * @param gv domain globals * @param m xmsg * @param gp guid prefix - * @param addr destination locator + * @param loc destination locator */ -void ddsi_xmsg_setdst1 (struct ddsi_domaingv *gv, struct ddsi_xmsg *m, const ddsi_guid_prefix_t *gp, const ddsi_xlocator_t *addr); +void ddsi_xmsg_setdst1 (struct ddsi_domaingv *gv, struct ddsi_xmsg *m, const ddsi_guid_prefix_t *gp, const ddsi_xlocator_t *loc); /** @component rtps_submsg */ -bool ddsi_xmsg_getdst1_prefix (struct ddsi_xmsg *m, ddsi_guid_prefix_t *gp); +bool ddsi_xmsg_getdst1_prefix (struct ddsi_xmsg *m, ddsi_guid_prefix_t *gp) + ddsrt_nonnull_all; /** * @brief For sending to a particular proxy reader @@ -93,7 +97,8 @@ bool ddsi_xmsg_getdst1_prefix (struct ddsi_xmsg *m, ddsi_guid_prefix_t *gp); * @param m xmsg * @param prd destination proxy reader */ -void ddsi_xmsg_setdst_prd (struct ddsi_xmsg *m, const struct ddsi_proxy_reader *prd); +void ddsi_xmsg_setdst_prd (struct ddsi_xmsg *m, const struct ddsi_proxy_reader *prd) + ddsrt_nonnull_all; /** @component rtps_submsg */ void ddsi_xmsg_setdst_pwr (struct ddsi_xmsg *m, const struct ddsi_proxy_writer *pwr); @@ -107,10 +112,12 @@ void ddsi_xmsg_setdst_pwr (struct ddsi_xmsg *m, const struct ddsi_proxy_writer * * @param msg xmsg * @param as address set */ -void ddsi_xmsg_setdst_addrset (struct ddsi_xmsg *msg, struct ddsi_addrset *as); +void ddsi_xmsg_setdst_addrset (struct ddsi_xmsg *msg, struct ddsi_addrset *as) + ddsrt_nonnull_all; /** @component rtps_submsg */ -int ddsi_xmsg_setmaxdelay (struct ddsi_xmsg *msg, int64_t maxdelay); +int ddsi_xmsg_setmaxdelay (struct ddsi_xmsg *msg, int64_t maxdelay) + ddsrt_nonnull_all; /** * @brief Sets the location of the destination readerId within the message @@ -124,7 +131,8 @@ int ddsi_xmsg_setmaxdelay (struct ddsi_xmsg *msg, int64_t maxdelay); * @param m xmsg * @param readerId reader entity id */ -void ddsi_xmsg_set_data_reader_id (struct ddsi_xmsg *m, ddsi_entityid_t *readerId); +void ddsi_xmsg_set_data_reader_id (struct ddsi_xmsg *m, ddsi_entityid_t *readerId) + ddsrt_nonnull_all; /** * @component rtps_submsg @@ -143,7 +151,8 @@ void ddsi_xmsg_set_data_reader_id (struct ddsi_xmsg *m, ddsi_entityid_t *readerI * @param madd xmsg to add * @returns Returns 1 if merge was successful, else 0. */ -int ddsi_xmsg_merge_rexmit_destinations_wrlock_held (struct ddsi_domaingv *gv, struct ddsi_xmsg *m, const struct ddsi_xmsg *madd); +int ddsi_xmsg_merge_rexmit_destinations_wrlock_held (struct ddsi_domaingv *gv, struct ddsi_xmsg *m, const struct ddsi_xmsg *madd) + ddsrt_nonnull_all; /** * @brief To set writer ids for updating last transmitted sequence number @@ -156,10 +165,12 @@ int ddsi_xmsg_merge_rexmit_destinations_wrlock_held (struct ddsi_domaingv *gv, s * @param wrguid writer guid * @param wrseq write sequence number */ -void ddsi_xmsg_setwriterseq (struct ddsi_xmsg *msg, const ddsi_guid_t *wrguid, ddsi_seqno_t wrseq); +void ddsi_xmsg_setwriterseq (struct ddsi_xmsg *msg, const ddsi_guid_t *wrguid, ddsi_seqno_t wrseq) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void ddsi_xmsg_setwriterseq_fragid (struct ddsi_xmsg *msg, const ddsi_guid_t *wrguid, ddsi_seqno_t wrseq, ddsi_fragment_number_t wrfragid); +void ddsi_xmsg_setwriterseq_fragid (struct ddsi_xmsg *msg, const ddsi_guid_t *wrguid, ddsi_seqno_t wrseq, ddsi_fragment_number_t wrfragid) + ddsrt_nonnull_all; /** * @brief Comparison function for retransmits @@ -171,104 +182,131 @@ void ddsi_xmsg_setwriterseq_fragid (struct ddsi_xmsg *msg, const ddsi_guid_t *wr * @param b xmsg to compare with * @return int */ -int ddsi_xmsg_compare_fragid (const struct ddsi_xmsg *a, const struct ddsi_xmsg *b); +int ddsi_xmsg_compare_fragid (const struct ddsi_xmsg *a, const struct ddsi_xmsg *b) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void ddsi_xmsg_free (struct ddsi_xmsg *msg); +void ddsi_xmsg_free (struct ddsi_xmsg *msg) + ddsrt_nonnull_all; /** @component rtps_submsg */ -size_t ddsi_xmsg_size (const struct ddsi_xmsg *m); +size_t ddsi_xmsg_size (const struct ddsi_xmsg *m) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void *ddsi_xmsg_payload (size_t *sz, struct ddsi_xmsg *m); +void *ddsi_xmsg_payload (size_t *sz, struct ddsi_xmsg *m) + ddsrt_nonnull_all ddsrt_attribute_returns_nonnull; /** @component rtps_submsg */ -void ddsi_xmsg_payload_to_plistsample (struct ddsi_plist_sample *dst, ddsi_parameterid_t keyparam, const struct ddsi_xmsg *m); +void ddsi_xmsg_payload_to_plistsample (struct ddsi_plist_sample *dst, ddsi_parameterid_t keyparam, const struct ddsi_xmsg *m) + ddsrt_nonnull_all; /** @component rtps_submsg */ -enum ddsi_xmsg_kind ddsi_xmsg_kind (const struct ddsi_xmsg *m); +enum ddsi_xmsg_kind ddsi_xmsg_kind (const struct ddsi_xmsg *m) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void ddsi_xmsg_guid_seq_fragid (const struct ddsi_xmsg *m, ddsi_guid_t *wrguid, ddsi_seqno_t *wrseq, ddsi_fragment_number_t *wrfragid); - +void ddsi_xmsg_guid_seq_fragid (const struct ddsi_xmsg *m, ddsi_guid_t *wrguid, ddsi_seqno_t *wrseq, ddsi_fragment_number_t *wrfragid) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void *ddsi_xmsg_submsg_from_marker (struct ddsi_xmsg *msg, struct ddsi_xmsg_marker marker); +void *ddsi_xmsg_submsg_from_marker (struct ddsi_xmsg *msg, struct ddsi_xmsg_marker marker) + ddsrt_nonnull_all ddsrt_attribute_returns_nonnull; /** @component rtps_submsg */ -void *ddsi_xmsg_append (struct ddsi_xmsg *m, struct ddsi_xmsg_marker *marker, size_t sz); +void *ddsi_xmsg_append (struct ddsi_xmsg *m, struct ddsi_xmsg_marker *marker, size_t sz) + ddsrt_nonnull ((1)) ddsrt_attribute_warn_unused_result; /** @component rtps_submsg */ -void ddsi_xmsg_shrink (struct ddsi_xmsg *m, struct ddsi_xmsg_marker marker, size_t sz); +void ddsi_xmsg_shrink (struct ddsi_xmsg *m, struct ddsi_xmsg_marker marker, size_t sz) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void ddsi_xmsg_serdata (struct ddsi_xmsg *m, struct ddsi_serdata *serdata, size_t off, size_t len, struct ddsi_writer *wr); - +void ddsi_xmsg_serdata (struct ddsi_xmsg *m, struct ddsi_serdata *serdata, size_t off, size_t len, struct ddsi_writer *wr) + ddsrt_nonnull_all; #ifdef DDS_HAS_SECURITY /** @component rtps_submsg */ -size_t ddsi_xmsg_submsg_size (struct ddsi_xmsg *msg, struct ddsi_xmsg_marker marker); +size_t ddsi_xmsg_submsg_size (struct ddsi_xmsg *msg, struct ddsi_xmsg_marker marker) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void ddsi_xmsg_submsg_remove (struct ddsi_xmsg *msg, struct ddsi_xmsg_marker sm_marker); +void ddsi_xmsg_submsg_remove (struct ddsi_xmsg *msg, struct ddsi_xmsg_marker sm_marker) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void ddsi_xmsg_submsg_replace (struct ddsi_xmsg *msg, struct ddsi_xmsg_marker sm_marker, unsigned char *new_submsg, size_t new_len); +void ddsi_xmsg_submsg_replace (struct ddsi_xmsg *msg, struct ddsi_xmsg_marker sm_marker, unsigned char *new_submsg, size_t new_len) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void ddsi_xmsg_submsg_append_refd_payload (struct ddsi_xmsg *msg, struct ddsi_xmsg_marker sm_marker); +void ddsi_xmsg_submsg_append_refd_payload (struct ddsi_xmsg *msg, struct ddsi_xmsg_marker sm_marker) + ddsrt_nonnull_all; #endif /* DDS_HAS_SECURITY */ - /** @component rtps_submsg */ -void ddsi_xmsg_submsg_setnext (struct ddsi_xmsg *msg, struct ddsi_xmsg_marker marker); +void ddsi_xmsg_submsg_setnext (struct ddsi_xmsg *msg, struct ddsi_xmsg_marker marker) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void ddsi_xmsg_submsg_init (struct ddsi_xmsg *msg, struct ddsi_xmsg_marker marker, ddsi_rtps_submessage_kind_t smkind); +void ddsi_xmsg_submsg_init (struct ddsi_xmsg *msg, struct ddsi_xmsg_marker marker, ddsi_rtps_submessage_kind_t smkind) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void ddsi_xmsg_add_timestamp (struct ddsi_xmsg *m, ddsrt_wctime_t t); +void ddsi_xmsg_add_timestamp (struct ddsi_xmsg *m, ddsrt_wctime_t t) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void ddsi_xmsg_add_entityid (struct ddsi_xmsg * m); +void ddsi_xmsg_add_entityid (struct ddsi_xmsg * m) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void *ddsi_xmsg_addpar_bo (struct ddsi_xmsg *m, ddsi_parameterid_t pid, size_t len, enum ddsrt_byte_order_selector bo); +void *ddsi_xmsg_addpar_bo (struct ddsi_xmsg *m, ddsi_parameterid_t pid, size_t len, enum ddsrt_byte_order_selector bo) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; /** @component rtps_submsg */ -void *ddsi_xmsg_addpar (struct ddsi_xmsg *m, ddsi_parameterid_t pid, size_t len); +void *ddsi_xmsg_addpar (struct ddsi_xmsg *m, ddsi_parameterid_t pid, size_t len) + ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; /** @component rtps_submsg */ -void ddsi_xmsg_addpar_keyhash (struct ddsi_xmsg *m, const struct ddsi_serdata *serdata, bool force_md5); +void ddsi_xmsg_addpar_keyhash (struct ddsi_xmsg *m, const struct ddsi_serdata *serdata, bool force_md5) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void ddsi_xmsg_addpar_statusinfo (struct ddsi_xmsg *m, unsigned statusinfo); +void ddsi_xmsg_addpar_statusinfo (struct ddsi_xmsg *m, unsigned statusinfo) + ddsrt_nonnull_all; /** @component rtps_submsg */ -void ddsi_xmsg_addpar_sentinel (struct ddsi_xmsg *m); -/** @component rtps_submsg */ -void ddsi_xmsg_addpar_sentinel_bo (struct ddsi_xmsg * m, enum ddsrt_byte_order_selector bo); +void ddsi_xmsg_addpar_sentinel (struct ddsi_xmsg *m) + ddsrt_nonnull_all; /** @component rtps_submsg */ -int ddsi_xmsg_addpar_sentinel_ifparam (struct ddsi_xmsg *m); - +void ddsi_xmsg_addpar_sentinel_bo (struct ddsi_xmsg * m, enum ddsrt_byte_order_selector bo) + ddsrt_nonnull_all; +/** @component rtps_submsg */ +int ddsi_xmsg_addpar_sentinel_ifparam (struct ddsi_xmsg *m) + ddsrt_nonnull_all; /** @component rtps_msg */ -int ddsi_xpack_addmsg (struct ddsi_xpack *xp, struct ddsi_xmsg *m, const uint32_t flags); +int ddsi_xpack_addmsg (struct ddsi_xpack *xp, struct ddsi_xmsg *m, const uint32_t flags) + ddsrt_nonnull_all; /** @component rtps_msg */ -int64_t ddsi_xpack_maxdelay (const struct ddsi_xpack *xp); +int64_t ddsi_xpack_maxdelay (const struct ddsi_xpack *xp) + ddsrt_nonnull_all; /** @component rtps_msg */ -unsigned ddsi_xpack_packetid (const struct ddsi_xpack *xp); +unsigned ddsi_xpack_packetid (const struct ddsi_xpack *xp) + ddsrt_nonnull_all; /** @component rtps_msg */ -void ddsi_xpack_sendq_stop (struct ddsi_domaingv *gv); +void ddsi_xpack_sendq_stop (struct ddsi_domaingv *gv) + ddsrt_nonnull_all; /** @component rtps_msg */ -void ddsi_xpack_sendq_fini (struct ddsi_domaingv *gv); +void ddsi_xpack_sendq_fini (struct ddsi_domaingv *gv) + ddsrt_nonnull_all; #if defined (__cplusplus) } diff --git a/src/core/ddsi/src/ddsi_xmsg.c b/src/core/ddsi/src/ddsi_xmsg.c index c63d937041..e0ae5a2fb6 100644 --- a/src/core/ddsi/src/ddsi_xmsg.c +++ b/src/core/ddsi/src/ddsi_xmsg.c @@ -225,6 +225,9 @@ void ddsi_xmsgpool_free (struct ddsi_xmsgpool *pool) (see below), transmits them, and releases them. */ +static void *ddsi_xmsg_append_impl (struct ddsi_xmsg *m, struct ddsi_xmsg_marker *marker, size_t sz) + ddsrt_nonnull ((1)) ddsrt_attribute_returns_nonnull; + static void ddsi_xmsg_reinit (struct ddsi_xmsg *m, enum ddsi_xmsg_kind kind) { m->sz = 0; @@ -513,7 +516,7 @@ void ddsi_xmsg_submsg_replace(struct ddsi_xmsg *msg, struct ddsi_xmsg_marker sm_ /* Adjust the message size to the new sub-message. */ if (old_len < new_len) { - ddsi_xmsg_append(msg, NULL, new_len - old_len); + (void) ddsi_xmsg_append_impl (msg, NULL, new_len - old_len); } else if (old_len > new_len) { @@ -581,7 +584,7 @@ void *ddsi_xmsg_submsg_from_marker (struct ddsi_xmsg *msg, struct ddsi_xmsg_mark return msg->data->payload + marker.offset; } -void *ddsi_xmsg_append (struct ddsi_xmsg *m, struct ddsi_xmsg_marker *marker, size_t sz) +static void *ddsi_xmsg_append_impl (struct ddsi_xmsg *m, struct ddsi_xmsg_marker *marker, size_t sz) { static const size_t a = 4; @@ -612,6 +615,11 @@ void *ddsi_xmsg_append (struct ddsi_xmsg *m, struct ddsi_xmsg_marker *marker, si return p; } +void *ddsi_xmsg_append (struct ddsi_xmsg *m, struct ddsi_xmsg_marker *marker, size_t sz) +{ + return ddsi_xmsg_append_impl (m, marker, sz); +} + void ddsi_xmsg_shrink (struct ddsi_xmsg *m, struct ddsi_xmsg_marker marker, size_t sz) { assert (m != NULL); @@ -898,7 +906,7 @@ void ddsi_xmsg_setwriterseq_fragid (struct ddsi_xmsg *msg, const ddsi_guid_t *wr msg->kindspecific.data.wrfragid = wrfragid; } -void *ddsi_xmsg_addpar_bo (struct ddsi_xmsg *m, ddsi_parameterid_t pid, size_t len, enum ddsrt_byte_order_selector bo) +static void *ddsi_xmsg_addpar_bo_impl (struct ddsi_xmsg *m, ddsi_parameterid_t pid, size_t len, enum ddsrt_byte_order_selector bo) { const size_t len4 = (len + 3) & ~(size_t)3; /* must alloc a multiple of 4 */ ddsi_parameter_t *phdr; @@ -916,9 +924,14 @@ void *ddsi_xmsg_addpar_bo (struct ddsi_xmsg *m, ddsi_parameterid_t pid, size_t l return p; } +void *ddsi_xmsg_addpar_bo (struct ddsi_xmsg *m, ddsi_parameterid_t pid, size_t len, enum ddsrt_byte_order_selector bo) +{ + return ddsi_xmsg_addpar_bo_impl (m, pid, len, bo); +} + void *ddsi_xmsg_addpar (struct ddsi_xmsg *m, ddsi_parameterid_t pid, size_t len) { - return ddsi_xmsg_addpar_bo(m, pid, len, DDSRT_BOSEL_NATIVE); + return ddsi_xmsg_addpar_bo_impl (m, pid, len, DDSRT_BOSEL_NATIVE); } void ddsi_xmsg_addpar_keyhash (struct ddsi_xmsg *m, const struct ddsi_serdata *serdata, bool force_md5) @@ -954,12 +967,12 @@ void ddsi_xmsg_addpar_statusinfo (struct ddsi_xmsg *m, unsigned statusinfo) void ddsi_xmsg_addpar_sentinel (struct ddsi_xmsg * m) { - ddsi_xmsg_addpar (m, DDSI_PID_SENTINEL, 0); + ddsi_xmsg_addpar_bo_impl (m, DDSI_PID_SENTINEL, 0, DDSRT_BOSEL_NATIVE); } void ddsi_xmsg_addpar_sentinel_bo (struct ddsi_xmsg * m, enum ddsrt_byte_order_selector bo) { - ddsi_xmsg_addpar_bo (m, DDSI_PID_SENTINEL, 0, bo); + ddsi_xmsg_addpar_bo_impl (m, DDSI_PID_SENTINEL, 0, bo); } int ddsi_xmsg_addpar_sentinel_ifparam (struct ddsi_xmsg * m) diff --git a/src/core/ddsi/tests/plist_leasedur.c b/src/core/ddsi/tests/plist_leasedur.c index e970efec70..b56711010c 100644 --- a/src/core/ddsi/tests/plist_leasedur.c +++ b/src/core/ddsi/tests/plist_leasedur.c @@ -168,7 +168,8 @@ CU_Test (ddsi_plist_leasedur, ser_spdp, .init = setup, .fini = teardown) struct ddsi_xmsg *m = ddsi_xmsg_new (gv.xmsgpool, &guid, NULL, 64, DDSI_XMSG_KIND_DATA); CU_ASSERT_FATAL (m != NULL); struct ddsi_xmsg_marker marker; - (void) ddsi_xmsg_append (m, &marker, 0); + void *x = ddsi_xmsg_append (m, &marker, 0); + (void) x; ddsi_plist_t plist; ddsi_plist_init_empty (&plist); @@ -199,7 +200,8 @@ CU_Test (ddsi_plist_leasedur, ser_others, .init = setup, .fini = teardown) struct ddsi_xmsg *m = ddsi_xmsg_new (gv.xmsgpool, &guid, NULL, 64, DDSI_XMSG_KIND_DATA); CU_ASSERT_FATAL (m != NULL); struct ddsi_xmsg_marker marker; - (void) ddsi_xmsg_append (m, &marker, 0); + void *x = ddsi_xmsg_append (m, &marker, 0); + (void) x; ddsi_plist_t plist; ddsi_plist_init_empty (&plist); From 69a7e8b8e0c3fb20f2047d39a2b7c0769c8d0194 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 31 Oct 2023 09:47:56 +0100 Subject: [PATCH 047/207] Delete UnicastResponseToSPDPMessages option This was a bit of weird option with both common sense and the documentation agreeing that "there is no known benefit to setting this to false". Deleting altogether therefore seems more sensible then marking it deprecated and ignoring it. Signed-off-by: Erik Boasson --- docs/manual/config/config_file_reference.rst | 18 +++--------------- docs/manual/options.md | 14 +++----------- etc/cyclonedds.rnc | 10 ++-------- etc/cyclonedds.xsd | 12 ++---------- src/core/ddsi/defconfig.c | 5 ++--- src/core/ddsi/include/dds/ddsi/ddsi_config.h | 1 - src/core/ddsi/src/ddsi__cfgelems.h | 8 -------- src/core/ddsi/src/ddsi_discovery_spdp.c | 16 +++++----------- 8 files changed, 17 insertions(+), 67 deletions(-) diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index 6280f1ed75..7433fbe8d9 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -818,7 +818,7 @@ The default value is: ``default`` //CycloneDDS/Domain/Internal ============================ -Children: :ref:`AccelerateRexmitBlockSize`, :ref:`AckDelay`, :ref:`AutoReschedNackDelay`, :ref:`BuiltinEndpointSet`, :ref:`BurstSize`, :ref:`ControlTopic`, :ref:`DefragReliableMaxSamples`, :ref:`DefragUnreliableMaxSamples`, :ref:`DeliveryQueueMaxSamples`, :ref:`EnableExpensiveChecks`, :ref:`ExtendedPacketInfo`, :ref:`GenerateKeyhash`, :ref:`HeartbeatInterval`, :ref:`LateAckMode`, :ref:`LivelinessMonitoring`, :ref:`MaxParticipants`, :ref:`MaxQueuedRexmitBytes`, :ref:`MaxQueuedRexmitMessages`, :ref:`MaxSampleSize`, :ref:`MeasureHbToAckLatency`, :ref:`MonitorPort`, :ref:`MultipleReceiveThreads`, :ref:`NackDelay`, :ref:`PreEmptiveAckDelay`, :ref:`PrimaryReorderMaxSamples`, :ref:`PrioritizeRetransmit`, :ref:`RediscoveryBlacklistDuration`, :ref:`RetransmitMerging`, :ref:`RetransmitMergingPeriod`, :ref:`RetryOnRejectBestEffort`, :ref:`SPDPResponseMaxDelay`, :ref:`SecondaryReorderMaxSamples`, :ref:`SocketReceiveBufferSize`, :ref:`SocketSendBufferSize`, :ref:`SquashParticipants`, :ref:`SynchronousDeliveryLatencyBound`, :ref:`SynchronousDeliveryPriorityThreshold`, :ref:`Test`, :ref:`UnicastResponseToSPDPMessages`, :ref:`UseMulticastIfMreqn`, :ref:`Watermarks`, :ref:`WriterLingerDuration` +Children: :ref:`AccelerateRexmitBlockSize`, :ref:`AckDelay`, :ref:`AutoReschedNackDelay`, :ref:`BuiltinEndpointSet`, :ref:`BurstSize`, :ref:`ControlTopic`, :ref:`DefragReliableMaxSamples`, :ref:`DefragUnreliableMaxSamples`, :ref:`DeliveryQueueMaxSamples`, :ref:`EnableExpensiveChecks`, :ref:`ExtendedPacketInfo`, :ref:`GenerateKeyhash`, :ref:`HeartbeatInterval`, :ref:`LateAckMode`, :ref:`LivelinessMonitoring`, :ref:`MaxParticipants`, :ref:`MaxQueuedRexmitBytes`, :ref:`MaxQueuedRexmitMessages`, :ref:`MaxSampleSize`, :ref:`MeasureHbToAckLatency`, :ref:`MonitorPort`, :ref:`MultipleReceiveThreads`, :ref:`NackDelay`, :ref:`PreEmptiveAckDelay`, :ref:`PrimaryReorderMaxSamples`, :ref:`PrioritizeRetransmit`, :ref:`RediscoveryBlacklistDuration`, :ref:`RetransmitMerging`, :ref:`RetransmitMergingPeriod`, :ref:`RetryOnRejectBestEffort`, :ref:`SPDPResponseMaxDelay`, :ref:`SecondaryReorderMaxSamples`, :ref:`SocketReceiveBufferSize`, :ref:`SocketSendBufferSize`, :ref:`SquashParticipants`, :ref:`SynchronousDeliveryLatencyBound`, :ref:`SynchronousDeliveryPriorityThreshold`, :ref:`Test`, :ref:`UseMulticastIfMreqn`, :ref:`Watermarks`, :ref:`WriterLingerDuration` The Internal elements deal with a variety of settings that are evolving and that are not necessarily fully supported. For the majority of the Internal settings the functionality is supported, but the right to change the way the options control the functionality is reserved. This includes renaming or moving options. @@ -1531,18 +1531,6 @@ This element controls the fraction of outgoing packets to drop, specified as sam The default value is: ``0`` -.. _`//CycloneDDS/Domain/Internal/UnicastResponseToSPDPMessages`: - -//CycloneDDS/Domain/Internal/UnicastResponseToSPDPMessages ----------------------------------------------------------- - -Boolean - -This element controls whether the response to a newly discovered participant is sent as a unicasted SPDP packet instead of rescheduling the periodic multicasted one. There is no known benefit to setting this to false. - -The default value is: ``true`` - - .. _`//CycloneDDS/Domain/Internal/UseMulticastIfMreqn`: //CycloneDDS/Domain/Internal/UseMulticastIfMreqn @@ -2699,9 +2687,9 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: ``none`` .. - generated from ddsi_config.h[eaf2059de5eccc422ae9ebd9bb3c40fd1d7545d3] + generated from ddsi_config.h[007a7968df8cbc42a122109bd139ac85bab0f6c9] generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] - generated from ddsi__cfgelems.h[fc5746cc2e55b4ab9daf9bd51bc263cf30ece564] + generated from ddsi__cfgelems.h[4549945443af9c1fe8014d973d4b1cff52a7acdb] generated from ddsi_config.c[2d3406ce4db09358597689d7382f80185634eb69] generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] diff --git a/docs/manual/options.md b/docs/manual/options.md index 2c80765dd3..332b4129dd 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -552,7 +552,7 @@ The default value is: `default` ### //CycloneDDS/Domain/Internal -Children: [AccelerateRexmitBlockSize](#cycloneddsdomaininternalacceleraterexmitblocksize), [AckDelay](#cycloneddsdomaininternalackdelay), [AutoReschedNackDelay](#cycloneddsdomaininternalautoreschednackdelay), [BuiltinEndpointSet](#cycloneddsdomaininternalbuiltinendpointset), [BurstSize](#cycloneddsdomaininternalburstsize), [ControlTopic](#cycloneddsdomaininternalcontroltopic), [DefragReliableMaxSamples](#cycloneddsdomaininternaldefragreliablemaxsamples), [DefragUnreliableMaxSamples](#cycloneddsdomaininternaldefragunreliablemaxsamples), [DeliveryQueueMaxSamples](#cycloneddsdomaininternaldeliveryqueuemaxsamples), [EnableExpensiveChecks](#cycloneddsdomaininternalenableexpensivechecks), [ExtendedPacketInfo](#cycloneddsdomaininternalextendedpacketinfo), [GenerateKeyhash](#cycloneddsdomaininternalgeneratekeyhash), [HeartbeatInterval](#cycloneddsdomaininternalheartbeatinterval), [LateAckMode](#cycloneddsdomaininternallateackmode), [LivelinessMonitoring](#cycloneddsdomaininternallivelinessmonitoring), [MaxParticipants](#cycloneddsdomaininternalmaxparticipants), [MaxQueuedRexmitBytes](#cycloneddsdomaininternalmaxqueuedrexmitbytes), [MaxQueuedRexmitMessages](#cycloneddsdomaininternalmaxqueuedrexmitmessages), [MaxSampleSize](#cycloneddsdomaininternalmaxsamplesize), [MeasureHbToAckLatency](#cycloneddsdomaininternalmeasurehbtoacklatency), [MonitorPort](#cycloneddsdomaininternalmonitorport), [MultipleReceiveThreads](#cycloneddsdomaininternalmultiplereceivethreads), [NackDelay](#cycloneddsdomaininternalnackdelay), [PreEmptiveAckDelay](#cycloneddsdomaininternalpreemptiveackdelay), [PrimaryReorderMaxSamples](#cycloneddsdomaininternalprimaryreordermaxsamples), [PrioritizeRetransmit](#cycloneddsdomaininternalprioritizeretransmit), [RediscoveryBlacklistDuration](#cycloneddsdomaininternalrediscoveryblacklistduration), [RetransmitMerging](#cycloneddsdomaininternalretransmitmerging), [RetransmitMergingPeriod](#cycloneddsdomaininternalretransmitmergingperiod), [RetryOnRejectBestEffort](#cycloneddsdomaininternalretryonrejectbesteffort), [SPDPResponseMaxDelay](#cycloneddsdomaininternalspdpresponsemaxdelay), [SecondaryReorderMaxSamples](#cycloneddsdomaininternalsecondaryreordermaxsamples), [SocketReceiveBufferSize](#cycloneddsdomaininternalsocketreceivebuffersize), [SocketSendBufferSize](#cycloneddsdomaininternalsocketsendbuffersize), [SquashParticipants](#cycloneddsdomaininternalsquashparticipants), [SynchronousDeliveryLatencyBound](#cycloneddsdomaininternalsynchronousdeliverylatencybound), [SynchronousDeliveryPriorityThreshold](#cycloneddsdomaininternalsynchronousdeliveryprioritythreshold), [Test](#cycloneddsdomaininternaltest), [UnicastResponseToSPDPMessages](#cycloneddsdomaininternalunicastresponsetospdpmessages), [UseMulticastIfMreqn](#cycloneddsdomaininternalusemulticastifmreqn), [Watermarks](#cycloneddsdomaininternalwatermarks), [WriterLingerDuration](#cycloneddsdomaininternalwriterlingerduration) +Children: [AccelerateRexmitBlockSize](#cycloneddsdomaininternalacceleraterexmitblocksize), [AckDelay](#cycloneddsdomaininternalackdelay), [AutoReschedNackDelay](#cycloneddsdomaininternalautoreschednackdelay), [BuiltinEndpointSet](#cycloneddsdomaininternalbuiltinendpointset), [BurstSize](#cycloneddsdomaininternalburstsize), [ControlTopic](#cycloneddsdomaininternalcontroltopic), [DefragReliableMaxSamples](#cycloneddsdomaininternaldefragreliablemaxsamples), [DefragUnreliableMaxSamples](#cycloneddsdomaininternaldefragunreliablemaxsamples), [DeliveryQueueMaxSamples](#cycloneddsdomaininternaldeliveryqueuemaxsamples), [EnableExpensiveChecks](#cycloneddsdomaininternalenableexpensivechecks), [ExtendedPacketInfo](#cycloneddsdomaininternalextendedpacketinfo), [GenerateKeyhash](#cycloneddsdomaininternalgeneratekeyhash), [HeartbeatInterval](#cycloneddsdomaininternalheartbeatinterval), [LateAckMode](#cycloneddsdomaininternallateackmode), [LivelinessMonitoring](#cycloneddsdomaininternallivelinessmonitoring), [MaxParticipants](#cycloneddsdomaininternalmaxparticipants), [MaxQueuedRexmitBytes](#cycloneddsdomaininternalmaxqueuedrexmitbytes), [MaxQueuedRexmitMessages](#cycloneddsdomaininternalmaxqueuedrexmitmessages), [MaxSampleSize](#cycloneddsdomaininternalmaxsamplesize), [MeasureHbToAckLatency](#cycloneddsdomaininternalmeasurehbtoacklatency), [MonitorPort](#cycloneddsdomaininternalmonitorport), [MultipleReceiveThreads](#cycloneddsdomaininternalmultiplereceivethreads), [NackDelay](#cycloneddsdomaininternalnackdelay), [PreEmptiveAckDelay](#cycloneddsdomaininternalpreemptiveackdelay), [PrimaryReorderMaxSamples](#cycloneddsdomaininternalprimaryreordermaxsamples), [PrioritizeRetransmit](#cycloneddsdomaininternalprioritizeretransmit), [RediscoveryBlacklistDuration](#cycloneddsdomaininternalrediscoveryblacklistduration), [RetransmitMerging](#cycloneddsdomaininternalretransmitmerging), [RetransmitMergingPeriod](#cycloneddsdomaininternalretransmitmergingperiod), [RetryOnRejectBestEffort](#cycloneddsdomaininternalretryonrejectbesteffort), [SPDPResponseMaxDelay](#cycloneddsdomaininternalspdpresponsemaxdelay), [SecondaryReorderMaxSamples](#cycloneddsdomaininternalsecondaryreordermaxsamples), [SocketReceiveBufferSize](#cycloneddsdomaininternalsocketreceivebuffersize), [SocketSendBufferSize](#cycloneddsdomaininternalsocketsendbuffersize), [SquashParticipants](#cycloneddsdomaininternalsquashparticipants), [SynchronousDeliveryLatencyBound](#cycloneddsdomaininternalsynchronousdeliverylatencybound), [SynchronousDeliveryPriorityThreshold](#cycloneddsdomaininternalsynchronousdeliveryprioritythreshold), [Test](#cycloneddsdomaininternaltest), [UseMulticastIfMreqn](#cycloneddsdomaininternalusemulticastifmreqn), [Watermarks](#cycloneddsdomaininternalwatermarks), [WriterLingerDuration](#cycloneddsdomaininternalwriterlingerduration) The Internal elements deal with a variety of settings that are evolving and that are not necessarily fully supported. For the majority of the Internal settings the functionality is supported, but the right to change the way the options control the functionality is reserved. This includes renaming or moving options. @@ -1051,14 +1051,6 @@ This element controls the fraction of outgoing packets to drop, specified as sam The default value is: `0` -#### //CycloneDDS/Domain/Internal/UnicastResponseToSPDPMessages -Boolean - -This element controls whether the response to a newly discovered participant is sent as a unicasted SPDP packet instead of rescheduling the periodic multicasted one. There is no known benefit to setting this to false. - -The default value is: `true` - - #### //CycloneDDS/Domain/Internal/UseMulticastIfMreqn Integer @@ -1889,9 +1881,9 @@ While none prevents any message from being written to a DDSI2 log file. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest. The default value is: `none` - + - + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index 8ff2bcb582..6722c13915 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -741,12 +741,6 @@ CycloneDDS configuration""" ] ] }? }? & [ a:documentation [ xml:lang="en" """ -

    This element controls whether the response to a newly discovered participant is sent as a unicasted SPDP packet instead of rescheduling the periodic multicasted one. There is no known benefit to setting this to false.

    -

    The default value is: true

    """ ] ] - element UnicastResponseToSPDPMessages { - xsd:boolean - }? - & [ a:documentation [ xml:lang="en" """

    Do not use.

    The default value is: 0

    """ ] ] element UseMulticastIfMreqn { @@ -1310,9 +1304,9 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
    duration_inf = xsd:token { pattern = "inf|0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)" } memsize = xsd:token { pattern = "0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B" } } -# generated from ddsi_config.h[eaf2059de5eccc422ae9ebd9bb3c40fd1d7545d3] +# generated from ddsi_config.h[007a7968df8cbc42a122109bd139ac85bab0f6c9] # generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] -# generated from ddsi__cfgelems.h[fc5746cc2e55b4ab9daf9bd51bc263cf30ece564] +# generated from ddsi__cfgelems.h[4549945443af9c1fe8014d973d4b1cff52a7acdb] # generated from ddsi_config.c[2d3406ce4db09358597689d7382f80185634eb69] # generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] # generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index 8b3ceb9ecc..5b813bba9c 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -651,7 +651,6 @@ CycloneDDS configuration
    - @@ -1128,13 +1127,6 @@ CycloneDDS configuration <p>The default value is: <code>0</code></p>
    - - - -<p>This element controls whether the response to a newly discovered participant is sent as a unicasted SPDP packet instead of rescheduling the periodic multicasted one. There is no known benefit to setting this to <i>false</i>.</p> -<p>The default value is: <code>true</code></p> - - @@ -1970,9 +1962,9 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - + - + diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index 082bca3bed..e4e76d9613 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -51,7 +51,6 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->defrag_unreliable_maxsamples = UINT32_C (4); cfg->defrag_reliable_maxsamples = UINT32_C (16); cfg->besmode = INT32_C (1); - cfg->unicast_response_to_spdp_messages = INT32_C (1); cfg->synchronous_delivery_latency_bound = INT64_C (9223372036854775807); cfg->retransmit_merging_period = INT64_C (5000000); cfg->const_hb_intv_sched = INT64_C (100000000); @@ -100,9 +99,9 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->ssl_min_version.minor = 3; #endif /* DDS_HAS_TCP_TLS */ } -/* generated from ddsi_config.h[eaf2059de5eccc422ae9ebd9bb3c40fd1d7545d3] */ +/* generated from ddsi_config.h[007a7968df8cbc42a122109bd139ac85bab0f6c9] */ /* generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] */ -/* generated from ddsi__cfgelems.h[fc5746cc2e55b4ab9daf9bd51bc263cf30ece564] */ +/* generated from ddsi__cfgelems.h[4549945443af9c1fe8014d973d4b1cff52a7acdb] */ /* generated from ddsi_config.c[2d3406ce4db09358597689d7382f80185634eb69] */ /* generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] */ /* generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] */ diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_config.h b/src/core/ddsi/include/dds/ddsi/ddsi_config.h index 1b7295eb70..dad2180000 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_config.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_config.h @@ -369,7 +369,6 @@ struct ddsi_config uint32_t rbuf_size; /* << size of a single receiver buffer */ enum ddsi_besmode besmode; int meas_hb_to_ack_latency; - int unicast_response_to_spdp_messages; int synchronous_delivery_priority_threshold; int64_t synchronous_delivery_latency_bound; diff --git a/src/core/ddsi/src/ddsi__cfgelems.h b/src/core/ddsi/src/ddsi__cfgelems.h index 5b3b453c0d..cb8f9a83f3 100644 --- a/src/core/ddsi/src/ddsi__cfgelems.h +++ b/src/core/ddsi/src/ddsi__cfgelems.h @@ -1262,14 +1262,6 @@ static struct cfgelem internal_cfgelems[] = { "and calculating round trip times. This is non-standard behaviour. The " "measured latencies are quite noisy and are currently not used " "anywhere.

    ")), - BOOL("UnicastResponseToSPDPMessages", NULL, 1, "true", - MEMBER(unicast_response_to_spdp_messages), - FUNCTIONS(0, uf_boolean, 0, pf_boolean), - DESCRIPTION( - "

    This element controls whether the response to a newly discovered " - "participant is sent as a unicasted SPDP packet instead of " - "rescheduling the periodic multicasted one. There is no known benefit " - "to setting this to false.

    ")), INT("SynchronousDeliveryPriorityThreshold", NULL, 1, "0", MEMBER(synchronous_delivery_priority_threshold), FUNCTIONS(0, uf_int, 0, pf_int), diff --git a/src/core/ddsi/src/ddsi_discovery_spdp.c b/src/core/ddsi/src/ddsi_discovery_spdp.c index 699974e596..caa1f12e73 100644 --- a/src/core/ddsi/src/ddsi_discovery_spdp.c +++ b/src/core/ddsi/src/ddsi_discovery_spdp.c @@ -486,17 +486,11 @@ static void respond_to_spdp (const struct ddsi_domaingv *gv, const ddsi_guid_t * int64_t delay = (int64_t) delay_norm * delay_max_ms / 1000; ddsrt_mtime_t tsched = ddsrt_mtime_add_duration (tnow, delay); GVTRACE (" %"PRId64, delay); - if (!pp->e.gv->config.unicast_response_to_spdp_messages) - /* pp can't reach gc_delete_participant => can safely reschedule */ - (void) ddsi_resched_xevent_if_earlier (pp->spdp_xevent, tsched); - else - { - struct ddsi_spdp_directed_xevent_cb_arg arg = { - .pp_guid = pp->e.guid, - .nrepeats = 4, .dest_proxypp_guid_prefix = dest_proxypp_guid->prefix - }; - ddsi_qxev_callback (gv->xevents, tsched, ddsi_spdp_directed_xevent_cb, &arg, sizeof (arg), false); - } + struct ddsi_spdp_directed_xevent_cb_arg arg = { + .pp_guid = pp->e.guid, + .nrepeats = 4, .dest_proxypp_guid_prefix = dest_proxypp_guid->prefix + }; + ddsi_qxev_callback (gv->xevents, tsched, ddsi_spdp_directed_xevent_cb, &arg, sizeof (arg), false); } ddsi_entidx_enum_participant_fini (&est); } From 3991b45acb59740549830383e57adc407fea7ca3 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 29 Jan 2024 13:46:29 +0100 Subject: [PATCH 048/207] Dump malformed packets to trace, optionally to log Signed-off-by: Erik Boasson --- docs/manual/config/config_file_reference.rst | 17 ++++-- docs/manual/options.md | 17 ++++-- etc/cyclonedds.rnc | 15 +++-- etc/cyclonedds.xsd | 15 +++-- src/core/ddsi/defconfig.c | 4 +- src/core/ddsi/src/ddsi__cfgelems.h | 14 +++-- src/core/ddsi/src/ddsi_config.c | 4 +- src/core/ddsi/src/ddsi_receive.c | 62 ++++++++++++++++---- src/ddsrt/include/dds/ddsrt/log.h | 2 + 9 files changed, 114 insertions(+), 36 deletions(-) diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index 7433fbe8d9..f006338727 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -2591,7 +2591,7 @@ The default value is: ``false`` ------------------------------------ One of: -* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, content, shm, trace +* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, content, malformed, trace * Or empty This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are: @@ -2616,16 +2616,25 @@ This element enables individual logging categories. These are enabled in additio * traffic: periodic reporting of total outgoing data + * throttle: tracing of throttling events + * whc: tracing of writer history cache changes + * rhc: tracing of reader history cache changes + * tcp: tracing of TCP-specific activity * topic: tracing of topic definitions * plist: tracing of discovery parameter list interpretation + * content: tracing of sample contents + + * malformed: dump malformed full packet as warning + + -In addition, there is the keyword trace that enables all but radmin, topic, plist and whc. +In addition, there is the keyword trace that enables: fatal, error, warning, info, config, discovery, data, trace, timing, traffic, tcp, throttle, content.. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is trace. The default value is: ```` @@ -2689,8 +2698,8 @@ The default value is: ``none`` .. generated from ddsi_config.h[007a7968df8cbc42a122109bd139ac85bab0f6c9] generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] - generated from ddsi__cfgelems.h[4549945443af9c1fe8014d973d4b1cff52a7acdb] - generated from ddsi_config.c[2d3406ce4db09358597689d7382f80185634eb69] + generated from ddsi__cfgelems.h[607a8f573eb5d87d6f93b1d9bce2947f29da56dc] + generated from ddsi_config.c[d4ef67f90737b1bf8ae94ad932774fa015e3a2cf] generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] diff --git a/docs/manual/options.md b/docs/manual/options.md index 332b4129dd..756ef31c67 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -1801,7 +1801,7 @@ The default value is: `false` #### //CycloneDDS/Domain/Tracing/Category One of: -* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, content, shm, trace +* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, content, malformed, trace * Or empty This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are: @@ -1826,15 +1826,24 @@ This element enables individual logging categories. These are enabled in additio * traffic: periodic reporting of total outgoing data + * throttle: tracing of throttling events + * whc: tracing of writer history cache changes + * rhc: tracing of reader history cache changes + * tcp: tracing of TCP-specific activity * topic: tracing of topic definitions * plist: tracing of discovery parameter list interpretation -In addition, there is the keyword trace that enables all but radmin, topic, plist and whc. + * content: tracing of sample contents + + * malformed: dump malformed full packet as warning + + +In addition, there is the keyword trace that enables: fatal, error, warning, info, config, discovery, data, trace, timing, traffic, tcp, throttle, content.. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is trace. The default value is: `` @@ -1883,8 +1892,8 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: `none` - - + + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index 6722c13915..13525d3680 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -1258,15 +1258,20 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
  • radmin: receive buffer administration
  • timing: periodic reporting of CPU loads per thread
  • traffic: periodic reporting of total outgoing data
  • +
  • throttle: tracing of throttling events
  • whc: tracing of writer history cache changes
  • +
  • rhc: tracing of reader history cache changes
  • tcp: tracing of TCP-specific activity
  • topic: tracing of topic definitions
  • -
  • plist: tracing of discovery parameter list interpretation
  • -

    In addition, there is the keyword trace that enables all but radmin, topic, plist and whc

    . +
  • plist: tracing of discovery parameter list interpretation
  • +
  • content: tracing of sample contents
  • +
  • malformed: dump malformed full packet as warning
  • + +

    In addition, there is the keyword trace that enables: fatal, error, warning, info, config, discovery, data, trace, timing, traffic, tcp, throttle, content.

    .

    The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is trace.

    The default value is: <empty>

    """ ] ] element Category { - xsd:token { pattern = "((fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|shm|trace)(,(fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|shm|trace))*)|" } + xsd:token { pattern = "((fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|malformed|trace)(,(fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|malformed|trace))*)|" } }? & [ a:documentation [ xml:lang="en" """

    This option specifies where the logging is printed to. Note that stdout and stderr are treated as special values, representing "standard out" and "standard error" respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings.

    @@ -1306,8 +1311,8 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
    } # generated from ddsi_config.h[007a7968df8cbc42a122109bd139ac85bab0f6c9] # generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] -# generated from ddsi__cfgelems.h[4549945443af9c1fe8014d973d4b1cff52a7acdb] -# generated from ddsi_config.c[2d3406ce4db09358597689d7382f80185634eb69] +# generated from ddsi__cfgelems.h[607a8f573eb5d87d6f93b1d9bce2947f29da56dc] +# generated from ddsi_config.c[d4ef67f90737b1bf8ae94ad932774fa015e3a2cf] # generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] # generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] # generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index 5b813bba9c..7bb7f013b2 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -1884,17 +1884,22 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> <li><i>radmin</i>: receive buffer administration</li> <li><i>timing</i>: periodic reporting of CPU loads per thread</li> <li><i>traffic</i>: periodic reporting of total outgoing data</li> +<li><i>throttle</i>: tracing of throttling events</li> <li><i>whc</i>: tracing of writer history cache changes</li> +<li><i>rhc</i>: tracing of reader history cache changes</li> <li><i>tcp</i>: tracing of TCP-specific activity</li> <li><i>topic</i>: tracing of topic definitions</li> -<li><i>plist</i>: tracing of discovery parameter list interpretation</li></ul> -<p>In addition, there is the keyword <i>trace</i> that enables all but <i>radmin</i>, <i>topic</i>, <i>plist</i> and <i>whc</i></p>. +<li><i>plist</i>: tracing of discovery parameter list interpretation</li> +<li><i>content</i>: tracing of sample contents</li> +<li><i>malformed</i>: dump malformed full packet as warning</li> +</ul> +<p>In addition, there is the keyword <i>trace</i> that enables: <i>fatal</i>, <i>error</i>, <i>warning</i>, <i>info</i>, <i>config</i>, <i>discovery</i>, <i>data</i>, <i>trace</i>, <i>timing</i>, <i>traffic</i>, <i>tcp</i>, <i>throttle</i>, <i>content</i>.</p>. <p>The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is <i>trace</i>.</p> <p>The default value is: <code>&lt;empty&gt;</code></p>
    - +
    @@ -1964,8 +1969,8 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - - + + diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index e4e76d9613..f268c3b5ac 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -101,8 +101,8 @@ void ddsi_config_init_default (struct ddsi_config *cfg) } /* generated from ddsi_config.h[007a7968df8cbc42a122109bd139ac85bab0f6c9] */ /* generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] */ -/* generated from ddsi__cfgelems.h[4549945443af9c1fe8014d973d4b1cff52a7acdb] */ -/* generated from ddsi_config.c[2d3406ce4db09358597689d7382f80185634eb69] */ +/* generated from ddsi__cfgelems.h[607a8f573eb5d87d6f93b1d9bce2947f29da56dc] */ +/* generated from ddsi_config.c[d4ef67f90737b1bf8ae94ad932774fa015e3a2cf] */ /* generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] */ /* generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] */ /* generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] */ diff --git a/src/core/ddsi/src/ddsi__cfgelems.h b/src/core/ddsi/src/ddsi__cfgelems.h index cb8f9a83f3..f6d08f5b9d 100644 --- a/src/core/ddsi/src/ddsi__cfgelems.h +++ b/src/core/ddsi/src/ddsi__cfgelems.h @@ -2005,13 +2005,19 @@ static struct cfgelem tracing_cfgelems[] = { "
  • radmin: receive buffer administration
  • \n" "
  • timing: periodic reporting of CPU loads per thread
  • \n" "
  • traffic: periodic reporting of total outgoing data
  • \n" + "
  • throttle: tracing of throttling events
  • \n" "
  • whc: tracing of writer history cache changes
  • \n" + "
  • rhc: tracing of reader history cache changes
  • \n" "
  • tcp: tracing of TCP-specific activity
  • \n" "
  • topic: tracing of topic definitions
  • \n" - "
  • plist: tracing of discovery parameter list interpretation
  • " + "
  • plist: tracing of discovery parameter list interpretation
  • \n" + "
  • content: tracing of sample contents
  • \n" + "
  • malformed: dump malformed full packet as warning
  • \n" "\n" - "

    In addition, there is the keyword trace that enables all " - "but radmin, topic, plist and whc

    .\n" + "

    In addition, there is the keyword trace that enables: " + "fatal, error, warning, info, config, " + "discovery, data, trace, timing, traffic, " + "tcp, throttle, content.

    .\n" "

    The categorisation of tracing output is incomplete and hence most " "of the verbosity levels and categories are not of much use in the " "current release. This is an ongoing process and here we describe the " @@ -2020,7 +2026,7 @@ static struct cfgelem tracing_cfgelems[] = { VALUES( "fatal","error","warning","info","config","discovery","data","radmin", "timing","traffic","topic","tcp","plist","whc","throttle","rhc", - "content","shm","trace" + "content","malformed","trace" )), ENUM("Verbosity", NULL, 1, "none", NOMEMBER, diff --git a/src/core/ddsi/src/ddsi_config.c b/src/core/ddsi/src/ddsi_config.c index 73eeacbac8..0ee326451e 100644 --- a/src/core/ddsi/src/ddsi_config.c +++ b/src/core/ddsi/src/ddsi_config.c @@ -1007,10 +1007,10 @@ GENERIC_ENUM_CTYPE (shm_loglevel, enum ddsi_shm_loglevel) /* "trace" is special: it enables (nearly) everything */ static const char *tracemask_names[] = { - "fatal", "error", "warning", "info", "config", "discovery", "data", "radmin", "timing", "traffic", "topic", "tcp", "plist", "whc", "throttle", "rhc", "content", "trace", NULL + "fatal", "error", "warning", "info", "config", "discovery", "data", "radmin", "timing", "traffic", "topic", "tcp", "plist", "whc", "throttle", "rhc", "content", "malformed", "trace", NULL }; static const uint32_t tracemask_codes[] = { - DDS_LC_FATAL, DDS_LC_ERROR, DDS_LC_WARNING, DDS_LC_INFO, DDS_LC_CONFIG, DDS_LC_DISCOVERY, DDS_LC_DATA, DDS_LC_RADMIN, DDS_LC_TIMING, DDS_LC_TRAFFIC, DDS_LC_TOPIC, DDS_LC_TCP, DDS_LC_PLIST, DDS_LC_WHC, DDS_LC_THROTTLE, DDS_LC_RHC, DDS_LC_CONTENT, DDS_LC_ALL + DDS_LC_FATAL, DDS_LC_ERROR, DDS_LC_WARNING, DDS_LC_INFO, DDS_LC_CONFIG, DDS_LC_DISCOVERY, DDS_LC_DATA, DDS_LC_RADMIN, DDS_LC_TIMING, DDS_LC_TRAFFIC, DDS_LC_TOPIC, DDS_LC_TCP, DDS_LC_PLIST, DDS_LC_WHC, DDS_LC_THROTTLE, DDS_LC_RHC, DDS_LC_CONTENT, DDS_LC_MALFORMED, DDS_LC_ALL }; static enum update_result uf_tracemask (struct ddsi_cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) diff --git a/src/core/ddsi/src/ddsi_receive.c b/src/core/ddsi/src/ddsi_receive.c index c4206c381f..d4e46219b4 100644 --- a/src/core/ddsi/src/ddsi_receive.c +++ b/src/core/ddsi/src/ddsi_receive.c @@ -2793,16 +2793,19 @@ static const char *submsg_name (ddsi_rtps_submessage_kind_t id, struct submsg_na return buffer->x; } -static void malformed_packet_received (const struct ddsi_domaingv *gv, const unsigned char *msg, const unsigned char *submsg, size_t len, ddsi_vendorid_t vendorid) +static void malformed_packet_received_shortmsg (const struct ddsi_domaingv *gv, const unsigned char *msg, const unsigned char *submsg, size_t len, ddsi_vendorid_t vendorid) { char tmp[1024]; size_t i, pos, smsize; - + struct submsg_name submsg_name_buffer; ddsi_rtps_submessage_kind_t smkind; const char *state0; const char *state1; - if (submsg == NULL || (submsg < msg || submsg >= msg + len)) { + // can safely subtract the two pointers after casting to uintptr_t, on all practical platforms + // this'll just give us a useful offset as long as submsg isn't a null pointer + const intptr_t offset = (intptr_t) ((uintptr_t) submsg - (uintptr_t) msg); + if (submsg == NULL || (submsg < msg || submsg > msg + len)) { // outside buffer shouldn't happen, but this is for dealing with junk, so better be careful smkind = DDSI_RTPS_SMID_PAD; state0 = ""; @@ -2818,19 +2821,20 @@ static void malformed_packet_received (const struct ddsi_domaingv *gv, const uns state1 = submsg_name (smkind, &submsg_name_buffer); } assert (submsg >= msg && submsg <= msg + len); - + const size_t clamped_offset = (offset < 0) ? 0 : ((size_t) offset > len) ? len : (size_t) offset; + /* Show beginning of message and of submessage (as hex dumps) */ - pos = (size_t) snprintf (tmp, sizeof (tmp), "malformed packet received from vendor %u.%u state %s%s <", vendorid.id[0], vendorid.id[1], state0, state1); - for (i = 0; i < 32 && i < len && msg + i < submsg && pos < sizeof (tmp); i++) + pos = (size_t) snprintf (tmp, sizeof (tmp), "malformed packet received from vendor %u.%u length %" PRIuSIZE " state %s%s <", vendorid.id[0], vendorid.id[1], len, state0, state1); + for (i = 0; i < 32 && i < len && i < clamped_offset && pos < sizeof (tmp); i++) pos += (size_t) snprintf (tmp + pos, sizeof (tmp) - pos, "%s%02x", (i > 0 && (i%4) == 0) ? " " : "", msg[i]); if (pos < sizeof (tmp)) - pos += (size_t) snprintf (tmp + pos, sizeof (tmp) - pos, " @0x%x ", (int) (submsg - msg)); - for (i = 0; i < 64 && i < len - (size_t) (submsg - msg) && pos < sizeof (tmp); i++) - pos += (size_t) snprintf (tmp + pos, sizeof (tmp) - pos, "%s%02x", (i > 0 && (i%4) == 0) ? " " : "", submsg[i]); + pos += (size_t) snprintf (tmp + pos, sizeof (tmp) - pos, " @%" PRIdPTR " ", offset); + for (i = 0; i < 64 && i < len - clamped_offset && pos < sizeof (tmp); i++) + pos += (size_t) snprintf (tmp + pos, sizeof (tmp) - pos, "%s%02x", (i > 0 && (i%4) == 0) ? " " : "", msg[clamped_offset + i]); if (pos < sizeof (tmp)) pos += (size_t) snprintf (tmp + pos, sizeof (tmp) - pos, "> (note: maybe partially bswap'd)"); assert (pos < (int) sizeof (tmp)); - + /* Partially decode header if we have enough bytes available */ smsize = len - (size_t) (submsg - msg); if (smsize >= DDSI_RTPS_SUBMESSAGE_HEADER_SIZE && pos < sizeof (tmp)) { @@ -2902,6 +2906,44 @@ static void malformed_packet_received (const struct ddsi_domaingv *gv, const uns GVWARNING ("%s\n", tmp); } +static void malformed_packet_received_fulldump (const struct ddsi_domaingv *gv, const unsigned char *msg, const unsigned char *submsg, size_t len, ddsi_vendorid_t vendorid, uint32_t logmask) +{ + GVLOG (logmask, "malformed packet: vendor %u.%u msg %p submsg %p length %" PRIuSIZE " contents:\n", vendorid.id[0], vendorid.id[1], (void *) msg, (void *) submsg, len); + for (size_t off16 = 0; off16 < len; off16 += 16) + { + GVLOG (logmask, "%c%04" PRIxSIZE " ", (msg + off16 <= submsg && (size_t) (submsg - (msg + off16)) < 16) ? '*' : ' ', off16); + char sep = ' '; + size_t off1; + for (off1 = 0; off1 < 16 && off16 + off1 < len; off1++) { + if (msg + off16 + off1 == submsg) + sep = '['; + else if (sep == '[') + sep = ']'; + else + sep =' '; + GVLOG (logmask, "%s%c%02x", (off1 == 8) ? " " : "", sep, msg[off16 + off1]); + } + for (; off1 < 16; off1++) { + GVLOG (logmask, "%s%c ", (off1 == 8) ? " " : "", (sep == '[') ? ']' : sep); + sep = ' '; + } + GVLOG (logmask, " |"); + for (off1 = 0; off1 < 16 && off16 + off1 < len; off1++) { + GVLOG (logmask, "%c", isprint (msg[off16 + off1]) ? msg[off16 + off1] : '.'); + } + GVLOG (logmask, "|\n"); + } +} + +static void malformed_packet_received (const struct ddsi_domaingv *gv, const unsigned char *msg, const unsigned char *submsg, size_t len, ddsi_vendorid_t vendorid) +{ + malformed_packet_received_shortmsg (gv, msg, submsg, len, vendorid); + if (gv->logconfig.c.mask & DDS_LC_MALFORMED) + malformed_packet_received_fulldump (gv, msg, submsg, len, vendorid, DDS_LC_WARNING); + else // dump it if we're writing a trace file, no matter the tracing options + malformed_packet_received_fulldump (gv, msg, submsg, len, vendorid, DDS_TRACE_MASK); +} + static struct ddsi_receiver_state *rst_cow_if_needed (int *rst_live, struct ddsi_rmsg *rmsg, struct ddsi_receiver_state *rst) { if (! *rst_live) diff --git a/src/ddsrt/include/dds/ddsrt/log.h b/src/ddsrt/include/dds/ddsrt/log.h index 53730aa12d..42f905f508 100644 --- a/src/ddsrt/include/dds/ddsrt/log.h +++ b/src/ddsrt/include/dds/ddsrt/log.h @@ -76,6 +76,8 @@ extern "C" { #define DDS_LC_RHC (65536u) /** Include content in traces. */ #define DDS_LC_CONTENT (131072u) +/** Output full dump of malformed messages as warnings */ +#define DDS_LC_MALFORMED (262144u) /** All common trace categories. */ #define DDS_LC_ALL \ (DDS_LC_FATAL | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_INFO | \ From ff00abe4e6bf4a462e051ec62006709fa52d6468 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 22 Feb 2024 16:57:17 +0100 Subject: [PATCH 049/207] Add support for optional members in dynsub Signed-off-by: Erik Boasson --- examples/dynsub/print_sample.c | 16 ++++++++++++++-- examples/dynsub/type_cache.c | 3 +++ examples/dynsub/variouspub.c | 16 ++++++++++++++-- examples/dynsub/variouspub_types.idl | 7 +++++++ 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/examples/dynsub/print_sample.c b/examples/dynsub/print_sample.c index 2a5ab79228..8b0600d75c 100644 --- a/examples/dynsub/print_sample.c +++ b/examples/dynsub/print_sample.c @@ -180,8 +180,20 @@ static void print_sample1_to (const unsigned char *sample, const DDS_XTypes_Comp for (uint32_t i = 0; i < t->member_seq._length; i++) { const DDS_XTypes_CompleteStructMember *m = &t->member_seq._buffer[i]; - c1.key = c->key && m->common.member_flags & DDS_XTypes_IS_KEY; - print_sample1_ti (p, &m->common.member_type_id, &c1, sep, *m->detail.name ? m->detail.name : NULL, false); + if (m->common.member_flags & DDS_XTypes_IS_OPTIONAL) { + void const * const *p1 = (const void *) align (p, &c1, _Alignof (void *), sizeof (void *)); + if (*p1 == NULL) { + printf ("%s", sep); + if (*m->detail.name) printf ("\"%s\":", m->detail.name); + printf ("(nothing)"); + } else { + struct context c2 = { .valid_data = c->valid_data, .key = false, .offset = 0, .maxalign = 1 }; + print_sample1_ti (*p1, &m->common.member_type_id, &c2, sep, *m->detail.name ? m->detail.name : NULL, false); + } + } else { + c1.key = c->key && m->common.member_flags & DDS_XTypes_IS_KEY; + print_sample1_ti (p, &m->common.member_type_id, &c1, sep, *m->detail.name ? m->detail.name : NULL, false); + } sep = ","; } if (!is_base_type) printf ("}"); diff --git a/examples/dynsub/type_cache.c b/examples/dynsub/type_cache.c index d755eefe82..43c3eca1fc 100644 --- a/examples/dynsub/type_cache.c +++ b/examples/dynsub/type_cache.c @@ -349,6 +349,9 @@ void build_typecache_to (const DDS_XTypes_CompleteTypeObject *typeobj, size_t *a const DDS_XTypes_CompleteStructMember *m = &t->member_seq._buffer[i]; size_t a, s; build_typecache_ti (&m->common.member_type_id, &a, &s); + if (m->common.member_flags & DDS_XTypes_IS_OPTIONAL) { + a = _Alignof (void *); s = sizeof (void *); + } if (a > *align) *align = a; if (*size % a) diff --git a/examples/dynsub/variouspub.c b/examples/dynsub/variouspub.c index d5398d6b5e..e1773bcf31 100644 --- a/examples/dynsub/variouspub.c +++ b/examples/dynsub/variouspub.c @@ -85,6 +85,13 @@ static void *samples_c[] = { NULL }; +static int32_t long_4 = 4; +static void *samples_M1_O[] = { + &(M1_O){ .x = NULL }, + &(M1_O){ .x = &long_4 }, + NULL +}; + static struct tpentry { const char *name; const dds_topic_descriptor_t *descr; @@ -94,6 +101,7 @@ static struct tpentry { { "A", &A_desc, samples_a, offsetof (A, count) }, { "B", &B_desc, samples_b, offsetof (B, a.count) }, { "C", &C_desc, samples_c, offsetof (C, b.a.count) }, + { "M1::O", &M1_O_desc, samples_M1_O, SIZE_MAX }, { NULL, NULL, NULL, 0 } }; @@ -145,8 +153,12 @@ int main (int argc, char **argv) { dds_return_t ret = 0; void *sample = tpentry->samples[sample_idx]; - uint32_t *countp = (uint32_t *) ((unsigned char *) sample + tpentry->count_offset); - *countp = count++; + uint32_t * const countp = + (tpentry->count_offset != SIZE_MAX) + ? (uint32_t *) ((unsigned char *) sample + tpentry->count_offset) + : 0; + if (countp) + *countp = count++; if ((ret = dds_write (writer, sample)) < 0) { fprintf (stderr, "dds_write: %s\n", dds_strretcode (ret)); diff --git a/examples/dynsub/variouspub_types.idl b/examples/dynsub/variouspub_types.idl index 1cf5baba74..b9f79c4c16 100644 --- a/examples/dynsub/variouspub_types.idl +++ b/examples/dynsub/variouspub_types.idl @@ -20,3 +20,10 @@ struct C { @key short k; }; + +module M1 { + @appendable + struct O { + @optional long x; + }; +}; From 0118042cb454303a6dbcc3b9e27e45932fa67f41 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 26 Mar 2024 14:42:49 +0100 Subject: [PATCH 050/207] Fix race condition in security FSM unit test Signed-off-by: Erik Boasson --- src/security/core/tests/fsm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/security/core/tests/fsm.c b/src/security/core/tests/fsm.c index 28ac31336b..384dbabf8c 100644 --- a/src/security/core/tests/fsm.c +++ b/src/security/core/tests/fsm.c @@ -424,12 +424,12 @@ CU_Test(ddssec_fsm, create, .init = fsm_control_init, .fini = fsm_control_fini) CU_ASSERT (visited_auth == 0xff); ddsrt_mutex_unlock (&g_lock); - /* Check correct callback parameter passing (from fsm to user defined methods) */ - CU_ASSERT(correct_arg && correct_fsm); dds_security_fsm_free (fsm_auth); /* Check whether timeout callback has NOT been invoked */ + /* Check correct callback parameter passing (from fsm to user defined methods) */ ddsrt_mutex_lock (&g_lock); + CU_ASSERT (correct_arg && correct_fsm); CU_ASSERT (visited_timeout == 0); ddsrt_mutex_unlock (&g_lock); } From fa9f1a7d457f585aa3fc6eb1da5879dc80495c1d Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 28 Mar 2024 14:59:12 +0100 Subject: [PATCH 051/207] Correctly initialize defaulted external sequence An external mutable struct containing a sequence member that for which no value is provided by the CDR was not initialized correctly: only the length field was set to 0, not the other fields. If the _release field happens to be false, this is harmless; if not it results in freeing of unallocated memory. Signed-off-by: Erik Boasson --- src/core/cdr/src/dds_cdrstream.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/core/cdr/src/dds_cdrstream.c b/src/core/cdr/src/dds_cdrstream.c index 31873a807f..8367f3e1aa 100644 --- a/src/core/cdr/src/dds_cdrstream.c +++ b/src/core/cdr/src/dds_cdrstream.c @@ -1579,6 +1579,18 @@ static bool stream_is_member_present (uint32_t insn, dds_istream_t * __restrict return !op_type_optional (insn) || is_mutable_member || dds_is_get1 (is); } +static const uint32_t *initialize_and_skip_sequence (dds_sequence_t *seq, uint32_t insn, const uint32_t * __restrict ops, enum sample_data_state sample_state) +{ + if (sample_state == SAMPLE_DATA_UNINITIALIZED) + { + seq->_buffer = NULL; + seq->_maximum = 0; + seq->_release = true; + } + seq->_length = 0; + return skip_sequence_insns (insn, ops); +} + static const uint32_t *dds_stream_read_seq (dds_istream_t * __restrict is, char * __restrict addr, const struct dds_cdrstream_allocator * __restrict allocator, const uint32_t * __restrict ops, uint32_t insn, enum cdr_data_kind cdr_kind, enum sample_data_state sample_state) { dds_sequence_t * const seq = (dds_sequence_t *) addr; @@ -1592,16 +1604,7 @@ static const uint32_t *dds_stream_read_seq (dds_istream_t * __restrict is, char const uint32_t num = dds_is_get4 (is); if (num == 0) - { - if (sample_state == SAMPLE_DATA_UNINITIALIZED) - { - seq->_buffer = NULL; - seq->_maximum = 0; - seq->_release = true; - } - seq->_length = 0; - return skip_sequence_insns (insn, ops); - } + return initialize_and_skip_sequence (seq, insn, ops, sample_state); switch (subtype) { @@ -1954,8 +1957,7 @@ static const uint32_t *dds_stream_skip_adr_default (uint32_t insn, char * __rest return ops + 4; case DDS_OP_VAL_SEQ: case DDS_OP_VAL_BSQ: { dds_sequence_t * const seq = (dds_sequence_t *) addr; - seq->_length = 0; - return skip_sequence_insns (insn, ops); + return initialize_and_skip_sequence (seq, insn, ops, sample_state); } case DDS_OP_VAL_ARR: { return skip_array_default (insn, addr, allocator, ops, sample_state); From 085bd8753df15fc57e0240926d0023b083b5df63 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 28 Mar 2024 15:01:41 +0100 Subject: [PATCH 052/207] Test initializing defaulted external sequence This test relies on the combination of the address sanitizer and the undefined behaviour sanitizer: the former for initializing freshly allocated memory, the latter for faulting on trying to load `bool` from memory with a value other than 0 or 1. Signed-off-by: Erik Boasson --- src/core/ddsc/tests/cdrstream.c | 54 +++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/core/ddsc/tests/cdrstream.c b/src/core/ddsc/tests/cdrstream.c index 4a12c80c85..d34f403064 100644 --- a/src/core/ddsc/tests/cdrstream.c +++ b/src/core/ddsc/tests/cdrstream.c @@ -2194,3 +2194,57 @@ CU_Test(ddsc_cdrstream, key_flags_ext) } } #undef D + +typedef struct MutStructSeq +{ + dds_sequence_long b; + uint8_t c; +} MutStructSeq; + +typedef struct ExternMutStructSeq +{ + struct MutStructSeq * x; +} ExternMutStructSeq; + +static const uint32_t ExternMutStructSeq_ops [] = +{ + /* ExternMutStructSeq */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_OPT | DDS_OP_FLAG_EXT | DDS_OP_TYPE_EXT, offsetof (ExternMutStructSeq, x), (4u << 16u) + 5u /* MutStructSeq */, sizeof (MutStructSeq), + DDS_OP_RTS, + + /* MutStructSeq */ + DDS_OP_PLC, + DDS_OP_PLM | 5, 1u, + DDS_OP_PLM | 6, 2u, + DDS_OP_RTS, + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_4BY | DDS_OP_FLAG_SGN, offsetof (MutStructSeq, b), + DDS_OP_RTS, + DDS_OP_ADR | DDS_OP_TYPE_1BY, offsetof (MutStructSeq, c), + DDS_OP_RTS +}; + +CU_Test(ddsc_cdrstream, init_sequence_in_external_struct) +{ + static uint8_t cdr[] = { + 0x0d, 0x00, 0x00, 0x00, // 13 bytes follow for ExternMutStructSeq + 0x01, 0x00, 0x00, 0x00, // optional member present + 3x pad + 0x05, 0x00, 0x00, 0x00, // 5 bytes follow for MutStructSeq + 0x02, 0x00, 0x00, 0x00, // EM: id=2, length code 0 = 1B + 0x7b // 123: magic value for "c" + }; + struct dds_cdrstream_desc descr; + memset (&descr, 0, sizeof (descr)); + dds_cdrstream_desc_init (&descr, &dds_cdrstream_default_allocator, sizeof (ExternMutStructSeq), dds_alignof (ExternMutStructSeq), 0, ExternMutStructSeq_ops, NULL, 0); + uint32_t actual_size; + const bool byteswap = (DDSRT_ENDIAN != DDSRT_LITTLE_ENDIAN); + const bool norm_ok = dds_stream_normalize (cdr, sizeof (cdr), byteswap, DDSI_RTPS_CDR_ENC_VERSION_2, &descr, false, &actual_size); + CU_ASSERT_FATAL (norm_ok && actual_size == sizeof (cdr)); + dds_istream_t is; + dds_istream_init (&is, sizeof (cdr), cdr, DDSI_RTPS_CDR_ENC_VERSION_2); + ExternMutStructSeq * sample = ddsrt_calloc (1, sizeof (*sample)); + dds_stream_read_sample (&is, sample, &dds_cdrstream_default_allocator, &descr); + dds_stream_free_sample (sample, &dds_cdrstream_default_allocator, descr.ops.ops); + ddsrt_free (sample); + dds_cdrstream_desc_fini (&descr, &dds_cdrstream_default_allocator); +} From 0bf9627036a93de0bf74afb5d082da44ac07d3e8 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 28 Mar 2024 13:03:46 +0100 Subject: [PATCH 053/207] Always make idlc_generate available in install With cross-builds, and now therefore also static builds, one does need IDLC. Installing Generate.cmake unconditionally means one can always write idlc_generate(TARGET konijn FILES wortel.idl) and one only has to make sure that CMake can find "idlc" and the backend library. Adding the host build to the CMAKE_PREFIX_PATH as in: cmake -DCMAKE_PREFIX_PATH=.../target-install\;.../host-install results in CMake finding the CycloneDDS package for the target in the target-install directory while also looking (and finding) idlc and the backend somewhere in the host-install directory. Signed-off-by: Erik Boasson --- CMakeLists.txt | 4 ++++ PackageConfig.cmake.in | 4 +--- src/tools/idlc/CMakeLists.txt | 5 ----- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fa04d62b6d..eb7e2e0d6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -343,6 +343,10 @@ install( DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" COMPONENT dev ) +install( + FILES "${CycloneDDS_SOURCE_DIR}/cmake/Modules/Generate.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/idlc" + COMPONENT dev) # Generated file paths # although the following files are generated, they are checked into source diff --git a/PackageConfig.cmake.in b/PackageConfig.cmake.in index 8c8fbb7e5a..25aaaf265d 100644 --- a/PackageConfig.cmake.in +++ b/PackageConfig.cmake.in @@ -12,6 +12,4 @@ @PACKAGE_INIT@ include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") -if(TARGET CycloneDDS::idlc) - include("${CMAKE_CURRENT_LIST_DIR}/idlc/Generate.cmake") -endif() +include("${CMAKE_CURRENT_LIST_DIR}/idlc/Generate.cmake") diff --git a/src/tools/idlc/CMakeLists.txt b/src/tools/idlc/CMakeLists.txt index 7134fa1d20..576dd014e7 100644 --- a/src/tools/idlc/CMakeLists.txt +++ b/src/tools/idlc/CMakeLists.txt @@ -114,11 +114,6 @@ if (INSTALL_PDB) ) endif() -install( - FILES "${CycloneDDS_SOURCE_DIR}/cmake/Modules/Generate.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/idlc" - COMPONENT dev) - include("${CycloneDDS_SOURCE_DIR}/cmake/Modules/Generate.cmake") if(BUILD_TESTING) From 89590744e319d15c54d92c1e5dcdf9223704bb54 Mon Sep 17 00:00:00 2001 From: Robert Femmer Date: Fri, 29 Mar 2024 02:59:18 +0000 Subject: [PATCH 054/207] basic harness working --- fuzz/fuzz_handshake/CMakeLists.txt | 54 ++++++ fuzz/fuzz_handshake/fuzz_handshake.cc | 29 ++- fuzz/fuzz_handshake/fuzz_handshake.proto | 21 ++- fuzz/fuzz_handshake/fuzz_handshake_harness.c | 182 +++++++++++++++++++ fuzz/fuzz_handshake/fuzz_handshake_harness.h | 8 + fuzz/fuzz_handshake/prepare.sh | 18 ++ 6 files changed, 309 insertions(+), 3 deletions(-) create mode 100644 fuzz/fuzz_handshake/CMakeLists.txt create mode 100644 fuzz/fuzz_handshake/fuzz_handshake_harness.c create mode 100644 fuzz/fuzz_handshake/fuzz_handshake_harness.h create mode 100644 fuzz/fuzz_handshake/prepare.sh diff --git a/fuzz/fuzz_handshake/CMakeLists.txt b/fuzz/fuzz_handshake/CMakeLists.txt new file mode 100644 index 0000000000..a8fb041e29 --- /dev/null +++ b/fuzz/fuzz_handshake/CMakeLists.txt @@ -0,0 +1,54 @@ +project(fuzz_handshake LANGUAGES CXX) +cmake_minimum_required(VERSION 3.9) + +if(NOT TARGET CycloneDDS::ddsc) + # Find the CycloneDDS package. + find_package(CycloneDDS REQUIRED) +endif() + +# Protobuf in newer versions depend on absl (and utf8_range). These +# dependencies are not yet tracked by every cmake distribution. This makes it +# necessary to source the cmake configuration files from the build directories +# of protobuf (using the CONFIG argument to find_package)... +set(PROTOBUF_ROOT "${CMAKE_BINARY_DIR}/../LPM/external.protobuf") + +set(absl_DIR "${PROTOBUF_ROOT}/lib/cmake/absl") +find_package(absl REQUIRED CONFIG) + +set(utf8_range_DIR "${PROTOBUF_ROOT}/lib/cmake/utf8_range") +find_package(utf8_range REQUIRED CONFIG) + +set(protobuf_DIR "${PROTOBUF_ROOT}/lib/cmake/protobuf") +# ...sometime in the future these two statements should suffice: +set(Protobuf_USE_STATIC_LIBS ON) +find_package(protobuf REQUIRED CONFIG) + +add_library(fuzz_handshake_harness fuzz_handshake_harness.c) +target_include_directories( + fuzz_handshake_harness PRIVATE + "$" + "$" + "$" + "$" + "$" + "$" + "$" + "$" + "$") + +add_executable(fuzz_handshake fuzz_handshake.cc) +protobuf_generate(TARGET fuzz_handshake LANGUAGE cpp PROTOS "${CMAKE_CURRENT_SOURCE_DIR}/fuzz_handshake.proto") +target_include_directories( + fuzz_handshake PRIVATE + "$" + "$" + "$") + +target_link_libraries(fuzz_handshake + fuzz_handshake_harness + ${CMAKE_BINARY_DIR}/../LPM/src/libfuzzer/libprotobuf-mutator-libfuzzer.a + ${CMAKE_BINARY_DIR}/../LPM/src/libprotobuf-mutator.a + protobuf::libprotobuf + CycloneDDS::ddsc + $ENV{LIB_FUZZING_ENGINE} + stdc++) diff --git a/fuzz/fuzz_handshake/fuzz_handshake.cc b/fuzz/fuzz_handshake/fuzz_handshake.cc index 08b40a9200..b38ecc5ace 100644 --- a/fuzz/fuzz_handshake/fuzz_handshake.cc +++ b/fuzz/fuzz_handshake/fuzz_handshake.cc @@ -1,6 +1,33 @@ #include "fuzz_handshake.pb.h" - #include +extern "C" { +#include "fuzz_handshake_harness.h" +} +using fuzz_handshake::Event; +static bool g_init = false; DEFINE_PROTO_FUZZER(const fuzz_handshake::FuzzMsg& message) { + if (!g_init) g_init = fuzz_handshake_init(); + fuzz_handshake_reset(); + for (auto &event : message.events()) { + switch (event.event_case()) { + case Event::EventCase::kTimeout: + fuzz_handshake_handle_timeout(); + break; + case Event::EventCase::kRequest: + fuzz_handshake_handle_request(); + break; + case Event::EventCase::kReply: + fuzz_handshake_handle_reply(); + break; + case Event::EventCase::kFinal: + fuzz_handshake_handle_final(); + break; + case Event::EventCase::kCryptoTokens: + fuzz_handshake_handle_crypto_tokens(); + break; + default: + break; + } + } } diff --git a/fuzz/fuzz_handshake/fuzz_handshake.proto b/fuzz/fuzz_handshake/fuzz_handshake.proto index 657bbf3613..0340de9099 100644 --- a/fuzz/fuzz_handshake/fuzz_handshake.proto +++ b/fuzz/fuzz_handshake/fuzz_handshake.proto @@ -1,5 +1,22 @@ -syntax = "proto2"; +syntax = "proto3"; package fuzz_handshake; + +message TimeoutEvent {} +message ReceivedMessageRequest {} +message ReceivedMessageReply {} +message ReceivedMessageFinal {} +message ReceivedCryptoTokens {} + +message Event { + oneof event { + TimeoutEvent timeout = 1; + ReceivedMessageRequest request = 2; + ReceivedMessageReply reply = 3; + ReceivedMessageFinal final = 4; + ReceivedCryptoTokens crypto_tokens = 5; + } +} + message FuzzMsg { - required string msg = 1; + repeated Event events = 1; } diff --git a/fuzz/fuzz_handshake/fuzz_handshake_harness.c b/fuzz/fuzz_handshake/fuzz_handshake_harness.c new file mode 100644 index 0000000000..665b97630d --- /dev/null +++ b/fuzz/fuzz_handshake/fuzz_handshake_harness.c @@ -0,0 +1,182 @@ +#include "fuzz_handshake_harness.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include + +const char *sec_config = + "" + " " + " ${CYCLONEDDS_PID}" + " " + " finest" + " " + " " + " " + " "TEST_IDENTITY_CERTIFICATE_DUMMY"" + " "TEST_IDENTITY_CA_CERTIFICATE_DUMMY"" + " "TEST_IDENTITY_PRIVATE_KEY_DUMMY"" + " testtext_Password_testtext" + " testtext_Dir_testtext" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; +struct ddsi_cfgst *g_cfgst; +struct ddsi_guid g_ppguid; +struct ddsi_guid g_proxy_ppguid; +static struct ddsi_thread_state *thrst; + +static struct ddsi_domaingv gv; + +struct { + struct ddsi_participant *pp; + struct ddsi_proxy_participant *proxy_pp; + struct ddsi_handshake *hs; +} harness; + +bool fuzz_handshake_init() { + ddsi_iid_init(); + ddsi_thread_states_init(); + // register the main thread, then claim it as spawned by Cyclone because the + // internal processing has various asserts that it isn't an application thread + // doing the dirty work + thrst = ddsi_lookup_thread_state (); + assert (thrst->state == DDSI_THREAD_STATE_LAZILY_CREATED); + thrst->state = DDSI_THREAD_STATE_ALIVE; + thrst->vtime.v = DDSI_VTIME_NEST_MASK; + ddsrt_atomic_stvoidp (&thrst->gv, &gv); + memset(&gv, 0, sizeof(gv)); + ddsi_config_init_default(&gv.config); + gv.config.transport_selector = DDSI_TRANS_NONE; + ddsi_config_prep(&gv, NULL); + ddsi_init(&gv, NULL); + g_cfgst = ddsi_config_init(sec_config, &gv.config, 1); + + printf("Security: %p\n", gv.security_context); + + // Create participant + { + ddsi_plist_t pplist; + ddsi_plist_init_empty(&pplist); + dds_qos_t *new_qos = dds_create_qos(); + ddsi_xqos_mergein_missing (new_qos, &gv.default_local_xqos_pp, ~(uint64_t)0); + dds_apply_entity_naming(new_qos, NULL, &gv); + ddsi_xqos_mergein_missing (&pplist.qos, new_qos, ~(uint64_t)0); + dds_delete_qos(new_qos); + + dds_return_t ret = ddsi_new_participant(&g_ppguid, &gv, 0, &pplist); + if(ret != DDS_RETCODE_OK) abort(); + harness.pp = ddsi_entidx_lookup_participant_guid(gv.entity_index, &g_ppguid); + ddsi_plist_fini(&pplist); + } + + // Create proxy participant + { + ddsi_plist_t pplist; + ddsi_plist_init_empty(&pplist); + pplist.present |= PP_IDENTITY_TOKEN; + ddsi_token_t identity_token = { + .class_id = NULL, + .properties = { + .n = 0, + .props = NULL + }, + .binary_properties = { + .n = 0, + .props = NULL + } + }; + pplist.identity_token = identity_token; + union { uint64_t u64; uint32_t u32[2]; } u; + u.u32[0] = gv.ppguid_base.prefix.u[1]; + u.u32[1] = gv.ppguid_base.prefix.u[2]; + u.u64 += ddsi_iid_gen (); + g_proxy_ppguid.prefix.u[0] = gv.ppguid_base.prefix.u[0]; + g_proxy_ppguid.prefix.u[1] = u.u32[0]; + g_proxy_ppguid.prefix.u[2] = u.u32[1]; + g_proxy_ppguid.entityid.u = DDSI_ENTITYID_PARTICIPANT; + ddsrt_wctime_t timestamp = { .v = dds_time() }; + if (!ddsi_new_proxy_participant(&gv, + &g_proxy_ppguid, + DDSI_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_ANNOUNCER, + NULL, + ddsi_new_addrset(), + ddsi_new_addrset(), + &pplist, + DDS_INFINITY, + DDSI_VENDORID_ECLIPSE, + DDSI_CF_PROXYPP_NO_SPDP, + timestamp, + 0)) { + abort(); + } + + harness.proxy_pp = ddsi_entidx_lookup_proxy_participant_guid(gv.entity_index, &g_proxy_ppguid); + ddsi_plist_fini(&pplist); + } + printf("domaingv %p\n", &gv); + printf("Participant %p\n", harness.pp); + printf("Participant domaingv %p\n", harness.pp->e.gv); + printf("Participant hsadmin %p\n", harness.pp->e.gv->hsadmin); + printf("Participant sec_attr %p\n", harness.pp->sec_attr); + printf("Proxy Participant %p\n", harness.proxy_pp); + printf("Proxy Participant domaingv %p\n", harness.proxy_pp->e.gv); + printf("Proxy Participant hsadmin %p\n", harness.proxy_pp->e.gv->hsadmin); + harness.hs = ddsi_handshake_find(harness.pp, harness.proxy_pp); + printf("Handshake %p\n", harness.hs); + return true; +} + +void hs_end_cb(struct ddsi_handshake *handshake, struct ddsi_participant *pp, struct ddsi_proxy_participant *proxy_pp, enum ddsi_handshake_state state) +{ + ddsi_handshake_release(handshake); +} + +void fuzz_handshake_reset(void) { + // Remove proxy participant, if created + // Release our handshake + ddsi_handshake_remove(harness.pp, harness.proxy_pp); + ddsi_handshake_register(harness.pp, harness.proxy_pp, hs_end_cb); + //harness.hs = ddsi_handshake_find(harness.pp, harness.proxy_pp); + if (harness.hs == NULL) abort(); + //// Make a new proxy participant + // Get the proxy participant + //harness.proxy_pp = ... + // Get the handshake +} + + +void fuzz_handshake_handle_timeout(void) { + //dds_security_fsm_dispatch(harness.hs->fsm, DDS_SECURITY_FSM_EVENT_TIMEOUT, false); +} +void fuzz_handshake_handle_request(void) {} +void fuzz_handshake_handle_reply(void) {} +void fuzz_handshake_handle_final(void) {} +void fuzz_handshake_handle_crypto_tokens(void) {} diff --git a/fuzz/fuzz_handshake/fuzz_handshake_harness.h b/fuzz/fuzz_handshake/fuzz_handshake_harness.h new file mode 100644 index 0000000000..373621af4c --- /dev/null +++ b/fuzz/fuzz_handshake/fuzz_handshake_harness.h @@ -0,0 +1,8 @@ +#include +bool fuzz_handshake_init(void); +void fuzz_handshake_reset(void); +void fuzz_handshake_handle_timeout(void); +void fuzz_handshake_handle_request(void); +void fuzz_handshake_handle_reply(void); +void fuzz_handshake_handle_final(void); +void fuzz_handshake_handle_crypto_tokens(void); diff --git a/fuzz/fuzz_handshake/prepare.sh b/fuzz/fuzz_handshake/prepare.sh new file mode 100644 index 0000000000..5b463f41d9 --- /dev/null +++ b/fuzz/fuzz_handshake/prepare.sh @@ -0,0 +1,18 @@ +#!/bin/bash -eu + + +prepare_fuzz_handshake() { + apt-get -y install ninja-build liblzma-dev libz-dev libtool + rm -rf libprotobuf-mutator LPM + git clone --depth 1 https://github.com/google/libprotobuf-mutator.git + mkdir LPM && cd LPM + cmake ../libprotobuf-mutator -GNinja \ + -DCMAKE_BUILD_TYPE=Release \ + -DLIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=ON \ + -DLIB_PROTO_MUTATOR_TESTING=OFF \ + -DLIB_PROTO_MUTATOR_FUZZER_LIBRARIES=FuzzingEngine + ninja +} +export -f prepare_fuzz_handshake + +env -u CFLAGS -u LIB_FUZZING_ENGINE CXXFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -stdlib=libc++" bash -euc prepare_fuzz_handshake From d45d6ebf129579bbe22e77f4e02163051ba046e5 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 29 Mar 2024 14:56:32 +0100 Subject: [PATCH 055/207] Don't set a quorum on writers created by a DS Signed-off-by: TheFixer --- src/durability/src/dds_durability.c | 136 +++++++++++++++++++--------- 1 file changed, 93 insertions(+), 43 deletions(-) diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 696c1c4392..1f7b95faaa 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -2243,65 +2243,115 @@ dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rh return rc; } +/* Returns TRUE if the entity is an application entity, false otherwise */ +static bool is_application_entity (struct dc_t *dc, dds_entity_t entity) +{ + dds_qos_t *pqos; + dds_entity_t participant; + dds_return_t rc; + char *ident = dc->cfg.ident; + void *userdata; + size_t size = 0; + bool result = true; + + /* by convention, if there is no ident every entity is considered a local entity */ + if (ident == NULL) { + return true; + } + pqos = dds_create_qos(); + /* get the entity's participant, and determine if ident is present in the userdata */ + if ((participant = dds_get_participant(entity)) < 0) { + DDS_ERROR("dds_get_participant failed [%s]\n", dds_strretcode(participant)); + goto err_get_participant; + } + if ((rc = dds_get_qos(participant, pqos)) < 0) { + DDS_ERROR("Failed to get participant qos [%s]\n", dds_strretcode(rc)); + goto err_get_participant_qos; + } + if (!dds_qget_userdata(pqos, &userdata, &size)) { + DDS_ERROR("Unable to retrieve the participant's user data"); + goto err_qget_userdata; + } + if ((size != strlen(ident)) || (userdata == NULL) || (strcmp(userdata, ident) != 0)) { + /* the user data of the participant of the entity does not contain the ident, + * so the entity is an application entity */ + result = true; + } else { + /* the entity resides on a DS */ + result = false; + } + dds_free(userdata); + dds_delete_qos(pqos); + return result; + +err_qget_userdata: +err_get_participant_qos: +err_get_participant: + dds_delete_qos(pqos); + return true; +} + +/* check if the writer is a durable application writer, and if so, we need to keep track of the quorum */ dds_return_t dds_durability_new_local_writer (dds_entity_t writer) { dds_durability_kind_t dkind; - dds_qos_t *qos; - dds_return_t rc = DDS_RETCODE_ERROR; + dds_qos_t *wqos; + dds_return_t rc ; dds_guid_t wguid; char id_str[37]; - /* check if the writer is a durable writer, and if so, we need to keep track of the quorum */ - assert(writer); - qos = dds_create_qos(); - if ((rc = dds_get_qos(writer, qos)) < 0) { - DDS_ERROR("failed to get qos from writer [%s]\n", dds_strretcode(rc)); + /* We only need to apply quorum checking for durable application writers. + * Writers created by a DS (if any) do not have to be subjected to + * quorum checking */ + if ((rc = dds_get_guid(writer, &wguid)) != DDS_RETCODE_OK) { + DDS_ERROR("failed to retrieve writer guid\n"); + goto err_get_guid; + } + wqos = dds_create_qos(); + if ((rc = dds_get_qos(writer, wqos)) < 0) { + DDS_ERROR("failed to get qos from writer \"%s\" [%s]\n", dc_stringify_id(wguid.v, id_str), dds_strretcode(rc)); goto err_get_qos; } - if (!dds_qget_durability(qos, &dkind)) { - DDS_ERROR("failed to retrieve durability qos"); + if (!dds_qget_durability(wqos, &dkind)) { + DDS_ERROR("failed to retrieve durability qos for writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); goto err_qget_durability; } - if ((dkind == DDS_DURABILITY_TRANSIENT) || (dkind == DDS_DURABILITY_PERSISTENT)) { - assert(dc.quorum_listener); - /* The writer is durable, so subjected to reaching a quorum before - * it can start publishing. We set a publication_matched listener on - * the writer. Each time a matching durable data container is discovered - * the listener will be triggered, causing relevant quora to be updated - * accordingly. - * - * Note that setting a publication_matched listener implies that we do NOT - * allow that user application can set a listener on durable writers. - * This is currently a limitation. */ - if ((rc = dds_get_guid(writer, &wguid)) != DDS_RETCODE_OK) { - DDS_ERROR("failed to retrieve writer guid"); - goto err_get_guid; - } - /* We now set a quorum listener on the durable writer. - * Each time a matching reader will appear, wewill get notified. - * Existing readers may already have matched before the listener takes effect, - * so these publication_match events may be missed. Luckily, we can request - * all matching readers using dds_get_matched_subscriptions(). - * - * Note: be aware that the same readers can be present in the list provided - * by dds_get_matched_subscriptions(), and can also be triggered by the listener. - * Avoid counting these readers twice! - */ - DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "durable writer \"%s\" subject to quorum checking\n", dc_stringify_id(wguid.v, id_str)); - if ((rc = dds_set_listener(writer, dc.quorum_listener)) < 0) { - DDS_ERROR("Unable to set the quorum listener on writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); - goto err_set_listener; - } - dc_check_quorum_reached(&dc, writer, true); + /* not a durable writer, no quorum checking required */ + if ((dkind != DDS_DURABILITY_TRANSIENT) && (dkind != DDS_DURABILITY_PERSISTENT)) { + goto skip; + } + /* not an application writer, no quorum checking required */ + if (!is_application_entity(&dc, writer)) { + goto skip; + } + assert(dc.quorum_listener); + /* The writer is a durable application writer, so subjected to reaching + * a quorum before it can start publishing. We set a publication_matched + * listener on the writer. Each time a matching durable data container is + * discovered the listener will be triggered, causing relevant quora to + * be updated accordingly. + * + * Note: + * - setting a publication_matched listener implies that we do NOT + * allow that user applications can set a listener on durable writers. + * This is currently a limitation. + * - be aware that the same readers can be present in the list provided + * by dds_get_matched_subscriptions(), and can also be triggered by the listener. + * Avoid counting these readers twice! */ + if ((rc = dds_set_listener(writer, dc.quorum_listener)) < 0) { + DDS_ERROR("Unable to set the quorum listener on writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); + goto err_set_listener; } - dds_delete_qos(qos); + dc_check_quorum_reached(&dc, writer, true); +skip: + dds_delete_qos(wqos); return DDS_RETCODE_OK; err_set_listener: -err_get_guid: err_qget_durability: err_get_qos: - dds_delete_qos(qos); + dds_delete_qos(wqos); +err_get_guid: return rc; } From 6541a508f798585e0d4263f08927edf71361a9bc Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 29 Mar 2024 15:00:28 +0100 Subject: [PATCH 056/207] Don't run security tests when durability is enabled (they don't go well together) Signed-off-by: TheFixer --- src/security/core/CMakeLists.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/security/core/CMakeLists.txt b/src/security/core/CMakeLists.txt index 418fb3eb45..81bb2f5eb8 100644 --- a/src/security/core/CMakeLists.txt +++ b/src/security/core/CMakeLists.txt @@ -45,8 +45,16 @@ target_include_directories(security_core "$>" ) -if(BUILD_TESTING) - add_subdirectory(tests) +# Security and durable support are a problematic combination. +# Currently, the topics required for durable support are not +# part of the security configuration in the tests. This causes +# security test cases to fail when durable support is enabled. +# Until this is solved we only run security tests when +# durable support is NOT enabed. +if(NOT ENABLE_DURABILITY) + if(BUILD_TESTING) + add_subdirectory(tests) + endif() endif() install( From 3937eba04751807e39cd6c3a6b3dccf72641a071 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 2 Apr 2024 15:50:28 +0200 Subject: [PATCH 057/207] Add reader guid to dc_request Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 1 + src/durability/src/dds_durability.c | 16 +-- src/durability/src/durablesupport.c | 114 ++++++++++-------- 3 files changed, 72 insertions(+), 59 deletions(-) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index 2f8adc59b7..0e5aaf84da 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -275,6 +275,7 @@ typedef uint64_t DurableSupport_delivery_id_t; typedef struct DurableSupport_request { DurableSupport_id_t client; + DurableSupport_id_t rguid; char * partition; char * tpname; char * type_id; diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 1f7b95faaa..869d4f29e0 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -146,6 +146,7 @@ static int dc_stringify_request (char *buf, size_t n, const DurableSupport_reque size_t i = 0; int l; char id_str[37]; + char rguid_str[37]; int64_t sec; uint32_t msec; @@ -159,7 +160,7 @@ static int dc_stringify_request (char *buf, size_t n, const DurableSupport_reque if (valid_data) { /* also print non-key fields */ if (request->timeout == DDS_INFINITY) { - if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"timeout\":\"never\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, request->type_id)) < 0) { + if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"rguid\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"timeout\":\"never\"}", dc_stringify_id(request->client, id_str), dc_stringify_id(request->rguid, rguid_str), request->partition, request->tpname, request->type_id)) < 0) { goto err; } } else { @@ -1200,7 +1201,7 @@ static void dc_com_free (struct com_t *com) #define MAX_TOPIC_NAME_SIZE 255 -static dds_return_t dc_com_request_write (struct com_t *com, const char *partition, const char *tpname, const char *type_id) +static dds_return_t dc_com_request_write (struct com_t *com, const dds_guid_t rguid, const char *partition, const char *tpname, const char *type_id) { /* note: we allow doing a request for volatile readers */ DurableSupport_request *request; @@ -1211,6 +1212,7 @@ static dds_return_t dc_com_request_write (struct com_t *com, const char *partiti request = DurableSupport_request__alloc(); memcpy(request->client, dc.cfg.id, 16); + memcpy(request->rguid, rguid.v, 16); request->partition = ddsrt_strdup(partition); request->tpname = ddsrt_strdup(tpname); request->type_id = ddsrt_strdup(type_id); @@ -1706,7 +1708,7 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade uint32_t plen, i; char **partitions; struct proxy_set_t *proxy_set = NULL; - dds_guid_t guid; + dds_guid_t rguid; char id_str[37]; dds_typeinfo_t *typeinfo; ddsi_typeid_t *tid = NULL; @@ -1722,11 +1724,11 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade } (void)ddsi_make_typeid_str(&tidstr, tid); /* get reader guid */ - if ((rc = dds_get_guid(reader, &guid)) < DDS_RETCODE_OK) { + if ((rc = dds_get_guid(reader, &rguid)) < DDS_RETCODE_OK) { DDS_ERROR("Unable to retrieve the guid of the reader [%s]\n", dds_strretcode(-rc)); goto err_get_guid; } - (void)dc_stringify_id(guid.v, id_str); + (void)dc_stringify_id(rguid.v, id_str); /* get topic name */ if ((topic = dds_get_topic(reader)) < 0) { DDS_ERROR("Unable to get topic from reader [%s]\n", dds_strretcode(-topic)); @@ -1761,9 +1763,9 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade * We do this BEFORE we send the request, so that we are sure * that when we receive the response (possibly immediately after * sending the request) the reader and rhc are present */ - dc_register_reader_to_proxy_set(dc, proxy_set, guid, reader, rhc); + dc_register_reader_to_proxy_set(dc, proxy_set, rguid, reader, rhc); /* send a request for this proxy set */ - if ((rc = dc_com_request_write(dc->com, proxy_set->key.partition, proxy_set->key.tpname, proxy_set->key.type_id)) != DDS_RETCODE_OK) { + if ((rc = dc_com_request_write(dc->com, rguid, proxy_set->key.partition, proxy_set->key.tpname, proxy_set->key.type_id)) != DDS_RETCODE_OK) { DDS_ERROR("Failed to publish dc_request for proxy set %s.%s\n", proxy_set->key.partition, proxy_set->key.tpname); /* We failed to request data for this proxy set. * We could do several things now, e.g., 1) try again until we succeed, diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index 2395d59455..44413aaa4f 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -627,6 +627,7 @@ static const uint32_t DurableSupport_request_ops [] = /* request */ DDS_OP_DLC, DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, client), 16u, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, rguid), 16u, DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, partition), DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, type_id), @@ -636,42 +637,46 @@ static const uint32_t DurableSupport_request_ops [] = /* key: client */ DDS_OP_KOF | 1, 1u /* order: 0 */, - /* key: partition */ + /* key: rguid */ DDS_OP_KOF | 1, 4u /* order: 1 */, + + /* key: partition */ + DDS_OP_KOF | 1, 7u /* order: 2 */, /* key: tpname */ - DDS_OP_KOF | 1, 6u /* order: 2 */, + DDS_OP_KOF | 1, 9u /* order: 3 */, /* key: type_id */ - DDS_OP_KOF | 1, 8u /* order: 3 */ + DDS_OP_KOF | 1, 11u /* order: 4 */ }; -static const dds_key_descriptor_t DurableSupport_request_keys[4] = +static const dds_key_descriptor_t DurableSupport_request_keys[5] = { - { "client", 13, 0 }, - { "partition", 15, 1 }, - { "tpname", 17, 2 }, - { "type_id", 19, 3 } + { "client", 16, 0 }, + { "rguid", 18, 1 }, + { "partition", 20, 2 }, + { "tpname", 22, 3 }, + { "type_id", 24, 4 } }; /* Type Information: - [MINIMAL dd0d9462a253e8cce609462197f1] (#deps: 2) + [MINIMAL ab970ab07c061f95f865be523bb0] (#deps: 2) - [MINIMAL 43f53a2be35b432cc735e9431a89] - [MINIMAL 84ce9c3d894c1483f859c00d5927] - [COMPLETE 798973adc9bb497149ff155ebd9a] (#deps: 2) + [COMPLETE ca811b13ce9943d64d1fa75ace5f] (#deps: 2) - [COMPLETE aca4d5a256d39713924333e85c6d] - [COMPLETE 023df3bd21223779cd1936cef928] */ #define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ 0xc0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0xdd, 0x0d, 0x94, 0x62, 0xa2, 0x53, 0xe8, 0xcc, 0xe6, 0x09, 0x46, \ - 0x21, 0x97, 0xf1, 0x00, 0x85, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0xab, 0x97, 0x0a, 0xb0, 0x7c, 0x06, 0x1f, 0x95, 0xf8, 0x65, 0xbe, \ + 0x52, 0x3b, 0xb0, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, \ 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x79, 0x89, 0x73, 0xad, 0xc9, 0xbb, 0x49, 0x71, 0x49, 0xff, 0x15, \ - 0x5e, 0xbd, 0x9a, 0x00, 0xde, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0xca, 0x81, 0x1b, 0x13, 0xce, 0x99, 0x43, 0xd6, 0x4d, 0x1f, 0xa7, \ + 0x5a, 0xce, 0x5f, 0x00, 0x06, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ @@ -679,64 +684,68 @@ static const dds_key_descriptor_t DurableSupport_request_keys[4] = } #define TYPE_INFO_CDR_SZ_DurableSupport_request 196u #define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ - 0xeb, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0xdd, 0x0d, 0x94, 0x62, 0xa2, 0x53, 0xe8, \ - 0xcc, 0xe6, 0x09, 0x46, 0x21, 0x97, 0xf1, 0x00, 0x81, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x0b, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0xab, 0x97, 0x0a, 0xb0, 0x7c, 0x06, 0x1f, \ + 0x95, 0xf8, 0x65, 0xbe, 0x52, 0x3b, 0xb0, 0x00, 0xa1, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ - 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ - 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, \ - 0x19, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xaf, 0xc4, 0x1d, 0xc3, 0x00, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ + 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ + 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, \ + 0x19, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ - 0x8d, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0x79, 0x89, 0x73, 0xad, 0xc9, 0xbb, 0x49, \ - 0x71, 0x49, 0xff, 0x15, 0x5e, 0xbd, 0x9a, 0x00, 0xda, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0xb5, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0xca, 0x81, 0x1b, 0x13, 0xce, 0x99, 0x43, \ + 0xd6, 0x4d, 0x1f, 0xa7, 0x5a, 0xce, 0x5f, 0x00, 0x02, 0x01, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x00, 0xae, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ + 0x65, 0x73, 0x74, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, \ - 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, \ - 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, \ - 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x16, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, \ - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, \ - 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, \ - 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, \ - 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x75, 0x72, 0x61, \ - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0x79, 0x89, 0x73, \ - 0xad, 0xc9, 0xbb, 0x49, 0x71, 0x49, 0xff, 0x15, 0x5e, 0xbd, 0x9a, 0xf1, 0xdd, 0x0d, 0x94, 0x62, \ - 0xa2, 0x53, 0xe8, 0xcc, 0xe6, 0x09, 0x46, 0x21, 0x97, 0xf1, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, \ - 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, \ - 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, \ - 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ + 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x72, 0x67, 0x75, 0x69, 0x64, 0x00, 0x00, 0x00, \ + 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, \ + 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, \ + 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, \ + 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, \ + 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ + 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ + 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ + 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0xf2, 0xca, 0x81, 0x1b, 0x13, 0xce, 0x99, 0x43, 0xd6, 0x4d, 0x1f, 0xa7, \ + 0x5a, 0xce, 0x5f, 0xf1, 0xab, 0x97, 0x0a, 0xb0, 0x7c, 0x06, 0x1f, 0x95, 0xf8, 0x65, 0xbe, 0x52, \ + 0x3b, 0xb0, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ + 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, \ + 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_request 742u +#define TYPE_MAP_CDR_SZ_DurableSupport_request 814u const dds_topic_descriptor_t DurableSupport_request_desc = { .m_size = sizeof (DurableSupport_request), .m_align = dds_alignof (DurableSupport_request), .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 4u, + .m_nkeys = 5u, .m_typename = "DurableSupport::request", .m_keys = DurableSupport_request_keys, - .m_nops = 7, + .m_nops = 8, .m_ops = DurableSupport_request_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request }, @@ -949,3 +958,4 @@ const dds_topic_descriptor_t DurableSupport_response_desc = .type_information = { .data = TYPE_INFO_CDR_DurableSupport_response, .sz = TYPE_INFO_CDR_SZ_DurableSupport_response }, .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_response, .sz = TYPE_MAP_CDR_SZ_DurableSupport_response } }; + From 8c8727ee6405ee485a125cbb259622beb65a40d2 Mon Sep 17 00:00:00 2001 From: Robert Femmer Date: Wed, 3 Apr 2024 08:21:36 +0000 Subject: [PATCH 058/207] fuzz_handshake: handshake both ways working --- fuzz/fuzz_handshake/CMakeLists.txt | 2 + fuzz/fuzz_handshake/fuzz_handshake.cc | 74 ++- fuzz/fuzz_handshake/fuzz_handshake.proto | 32 +- fuzz/fuzz_handshake/fuzz_handshake_expose.h | 35 ++ fuzz/fuzz_handshake/fuzz_handshake_harness.c | 479 +++++++++++++++--- fuzz/fuzz_handshake/fuzz_handshake_harness.h | 21 +- .../handshake_reply | 60 +++ .../handshake_request_final | 67 +++ fuzz/oss-fuzz-build.sh | 2 +- 9 files changed, 672 insertions(+), 100 deletions(-) create mode 100644 fuzz/fuzz_handshake/fuzz_handshake_expose.h create mode 100644 fuzz/fuzz_handshake/fuzz_handshake_seed_corpus/handshake_reply create mode 100644 fuzz/fuzz_handshake/fuzz_handshake_seed_corpus/handshake_request_final diff --git a/fuzz/fuzz_handshake/CMakeLists.txt b/fuzz/fuzz_handshake/CMakeLists.txt index a8fb041e29..bd2d293ed4 100644 --- a/fuzz/fuzz_handshake/CMakeLists.txt +++ b/fuzz/fuzz_handshake/CMakeLists.txt @@ -40,8 +40,10 @@ add_executable(fuzz_handshake fuzz_handshake.cc) protobuf_generate(TARGET fuzz_handshake LANGUAGE cpp PROTOS "${CMAKE_CURRENT_SOURCE_DIR}/fuzz_handshake.proto") target_include_directories( fuzz_handshake PRIVATE + "$" "$" "$" + "$" "$") target_link_libraries(fuzz_handshake diff --git a/fuzz/fuzz_handshake/fuzz_handshake.cc b/fuzz/fuzz_handshake/fuzz_handshake.cc index b38ecc5ace..96356179cf 100644 --- a/fuzz/fuzz_handshake/fuzz_handshake.cc +++ b/fuzz/fuzz_handshake/fuzz_handshake.cc @@ -1,33 +1,87 @@ #include "fuzz_handshake.pb.h" #include -extern "C" { #include "fuzz_handshake_harness.h" -} + using fuzz_handshake::Event; +void to_property(const fuzz_handshake::Property &in, dds_property_t &out) { + out.propagate = in.propagate(); + out.name = strdup(in.name().c_str()); + out.value = strdup(in.value().c_str()); +} + +void to_binaryproperty(const fuzz_handshake::BinaryProperty &in, dds_binaryproperty_t &out) { + out.propagate = in.propagate(); + out.name = strdup(in.name().c_str()); + out.value.length = (uint32_t) in.value().size(); + out.value.value = (unsigned char *) malloc(out.value.length); + memcpy(out.value.value, in.value().data(), out.value.length); +} + +void to_dataholder(const fuzz_handshake::DataHolder &in, ddsi_dataholder_t &out) { + out.properties.n = (uint32_t) in.properties().size(); + out.properties.props = (dds_property_t *) calloc(out.properties.n, sizeof(dds_property_t)); + for (int i = 0; i < in.properties().size(); i++) { + to_property(in.properties().Get(i), out.properties.props[i]); + } + out.binary_properties.n = (uint32_t) in.binary_properties().size(); + out.binary_properties.props = (dds_binaryproperty_t *) calloc(out.binary_properties.n, sizeof(dds_binaryproperty_t)); + for (int i = 0; i < in.binary_properties().size(); i++) { + to_binaryproperty(in.binary_properties().Get(i), out.binary_properties.props[i]); + } +} + +void free_properties(ddsi_dataholder_t &dh) { + for (uint32_t i = 0; i < dh.properties.n; i++) { + free(dh.properties.props[i].name); + free(dh.properties.props[i].value); + } + free(dh.properties.props); + for (uint32_t i = 0; i < dh.binary_properties.n; i++) { + free(dh.binary_properties.props[i].name); + free(dh.binary_properties.props[i].value.value); + } + free(dh.binary_properties.props); +} + static bool g_init = false; DEFINE_PROTO_FUZZER(const fuzz_handshake::FuzzMsg& message) { if (!g_init) g_init = fuzz_handshake_init(); - fuzz_handshake_reset(); + fuzz_handshake_reset(message.initiate_remote()); + uint32_t n_event = 1; for (auto &event : message.events()) { switch (event.event_case()) { case Event::EventCase::kTimeout: fuzz_handshake_handle_timeout(); break; case Event::EventCase::kRequest: - fuzz_handshake_handle_request(); - break; + { + ddsi_dataholder_t token; + to_dataholder(event.request().token(), token); + fuzz_handshake_handle_request(&token); + free_properties(token); + } break; case Event::EventCase::kReply: - fuzz_handshake_handle_reply(); - break; + { + ddsi_dataholder_t token; + to_dataholder(event.reply().token(), token); + fuzz_handshake_handle_reply(&token); + free_properties(token); + } break; case Event::EventCase::kFinal: - fuzz_handshake_handle_final(); - break; + { + ddsi_dataholder_t token; + to_dataholder(event.final().token(), token); + fuzz_handshake_handle_final(&token); + free_properties(token); + } break; case Event::EventCase::kCryptoTokens: fuzz_handshake_handle_crypto_tokens(); break; default: - break; + continue; } + fuzz_handshake_wait_for_event(n_event++); } + fuzz_handshake_wait_for_completion(); } diff --git a/fuzz/fuzz_handshake/fuzz_handshake.proto b/fuzz/fuzz_handshake/fuzz_handshake.proto index 0340de9099..2aa867418b 100644 --- a/fuzz/fuzz_handshake/fuzz_handshake.proto +++ b/fuzz/fuzz_handshake/fuzz_handshake.proto @@ -1,10 +1,33 @@ syntax = "proto3"; package fuzz_handshake; +message Property { + bytes name = 1; + bytes value = 2; + bool propagate = 3; +} + +message BinaryProperty { + bytes name = 1; + bytes value = 2; + bool propagate = 3; +} + +message DataHolder { + repeated Property properties = 1; + repeated BinaryProperty binary_properties = 2; +} + message TimeoutEvent {} -message ReceivedMessageRequest {} -message ReceivedMessageReply {} -message ReceivedMessageFinal {} +message ReceivedMessageRequest { + DataHolder token = 1; +} +message ReceivedMessageReply { + DataHolder token = 1; +} +message ReceivedMessageFinal { + DataHolder token = 1; +} message ReceivedCryptoTokens {} message Event { @@ -18,5 +41,6 @@ message Event { } message FuzzMsg { - repeated Event events = 1; + bool initiate_remote = 1; + repeated Event events = 2; } diff --git a/fuzz/fuzz_handshake/fuzz_handshake_expose.h b/fuzz/fuzz_handshake/fuzz_handshake_expose.h new file mode 100644 index 0000000000..c3c4d32dd4 --- /dev/null +++ b/fuzz/fuzz_handshake/fuzz_handshake_expose.h @@ -0,0 +1,35 @@ +/* The following struct definitions are opaque in ddsi, however the fuzzer needs + * access to some of the fields and hence they are reproduced here in order to + * expose them. This is not ideal, because any changes in those structs would + * need to be reflected here. + */ +#include +#include + +struct handshake_entities { + ddsi_guid_t lguid; + ddsi_guid_t rguid; +}; + +struct ddsi_handshake +{ + ddsrt_avl_node_t avlnode; + enum ddsi_handshake_state state; + struct handshake_entities participants; + DDS_Security_HandshakeHandle handshake_handle; + ddsrt_atomic_uint32_t refc; + ddsrt_atomic_uint32_t deleting; + ddsi_handshake_end_cb_t end_cb; + ddsrt_mutex_t lock; + struct dds_security_fsm *fsm; + const struct ddsi_domaingv *gv; + dds_security_authentication *auth; + + DDS_Security_HandshakeMessageToken handshake_message_in_token; + ddsi_message_identity_t handshake_message_in_id; + DDS_Security_HandshakeMessageToken *handshake_message_out; + DDS_Security_AuthRequestMessageToken local_auth_request_token; + DDS_Security_AuthRequestMessageToken *remote_auth_request_token; + DDS_Security_OctetSeq pdata; + int64_t shared_secret; +}; diff --git a/fuzz/fuzz_handshake/fuzz_handshake_harness.c b/fuzz/fuzz_handshake/fuzz_handshake_harness.c index 665b97630d..1cdf1a659c 100644 --- a/fuzz/fuzz_handshake/fuzz_handshake_harness.c +++ b/fuzz/fuzz_handshake/fuzz_handshake_harness.c @@ -1,5 +1,8 @@ #include "fuzz_handshake_harness.h" +#include "fuzz_handshake_expose.h" + #include +#include #include #include @@ -12,16 +15,22 @@ #include #include #include +#include #include #include #include #include #include +#include #include -//#include +#include +#include +#include #include #include +#include + const char *sec_config = "" " " @@ -30,18 +39,16 @@ const char *sec_config = " finest" " " " " - " " - " "TEST_IDENTITY_CERTIFICATE_DUMMY"" - " "TEST_IDENTITY_CA_CERTIFICATE_DUMMY"" - " "TEST_IDENTITY_PRIVATE_KEY_DUMMY"" - " testtext_Password_testtext" - " testtext_Dir_testtext" + " " + " data:," TEST_IDENTITY1_CERTIFICATE "" + " data:," TEST_IDENTITY1_PRIVATE_KEY "" + " data:," TEST_IDENTITY_CA1_CERTIFICATE "" " " " " " " " " " " - " " + " " " " " " " " @@ -52,8 +59,12 @@ struct ddsi_cfgst *g_cfgst; struct ddsi_guid g_ppguid; struct ddsi_guid g_proxy_ppguid; static struct ddsi_thread_state *thrst; - static struct ddsi_domaingv gv; +EVP_PKEY *g_private_key; + +#define FUZZ_HANDSHAKE_EVENT_HANDLED (-4) +ddsrt_atomic_uint32_t g_fsm_done; +ddsrt_atomic_uint32_t g_fuzz_events; struct { struct ddsi_participant *pp; @@ -61,8 +72,17 @@ struct { struct ddsi_handshake *hs; } harness; -bool fuzz_handshake_init() { - ddsi_iid_init(); +bool fuzz_handshake_init() +{ + // Load private key for remote identity + BIO *bio; + bio = BIO_new_mem_buf(TEST_IDENTITY3_PRIVATE_KEY, -1); + if (!bio) abort(); + g_private_key = PEM_read_bio_PrivateKey(bio, NULL, NULL, ""); + if (!g_private_key) abort(); + BIO_free(bio); + + //ddsi_iid_init(); ddsi_thread_states_init(); // register the main thread, then claim it as spawned by Cyclone because the // internal processing has various asserts that it isn't an application thread @@ -77,9 +97,14 @@ bool fuzz_handshake_init() { gv.config.transport_selector = DDSI_TRANS_NONE; ddsi_config_prep(&gv, NULL); ddsi_init(&gv, NULL); + gv.handshake_include_optional = true; g_cfgst = ddsi_config_init(sec_config, &gv.config, 1); - printf("Security: %p\n", gv.security_context); + //FILE *fp = fopen("/dev/stdout", "w"); + //dds_log_cfg_init(&gv.logconfig, 1, DDS_LC_TRACE | DDS_LC_ERROR | DDS_LC_WARNING, NULL, fp); + + // Disable logging + dds_log_cfg_init(&gv.logconfig, 1, 0, NULL, NULL); // Create participant { @@ -97,86 +122,378 @@ bool fuzz_handshake_init() { ddsi_plist_fini(&pplist); } + return true; +} + +static void hs_end_cb(UNUSED_ARG(struct ddsi_handshake *handshake), + UNUSED_ARG(struct ddsi_participant *pp), + UNUSED_ARG(struct ddsi_proxy_participant *proxy_pp), + UNUSED_ARG(enum ddsi_handshake_state state)) +{ + //printf("HANDSHAKE END: %d\n", state); fflush(stdout); +} + +static void fsm_debug_func(UNUSED_ARG(struct dds_security_fsm *fsm), DDS_SECURITY_FSM_DEBUG_ACT act, UNUSED_ARG(const dds_security_fsm_state *current), int event_id, UNUSED_ARG(void *arg)) +{ + // This event is never generated by the state machine. + // The fuzzer throws it in at the end of its events to signal that it's done + // and the handshake can be abandoned. + if (act == DDS_SECURITY_FSM_DEBUG_ACT_HANDLING && event_id == DDS_SECURITY_FSM_EVENT_DELETE) { + ddsrt_atomic_st32(&g_fsm_done, 1); + } + + // This event is used to serialize the fuzzer, as the state machine is driven by a + // separate thread. The fuzzer generates events and waits for the state machine to + // finish the resulting transition. This prevents triggering any race conditions which + // may result from a bug in the fuzzing harness. Further, the handshake data structures + // containing the messages from a remote participant are being reused, so overwriting them + // before the state machine handled a message will lead nowhere. Lastly, the harness does + // not need to concern itself with locking. + if (act == DDS_SECURITY_FSM_DEBUG_ACT_HANDLING && event_id == FUZZ_HANDSHAKE_EVENT_HANDLED) { + ddsrt_atomic_inc32(&g_fuzz_events); + } +} + +void fuzz_handshake_reset(bool initiate_remote) { + ddsrt_atomic_st32(&g_fsm_done, 0); + ddsrt_atomic_st32(&g_fuzz_events, 0); + // Create proxy participant - { - ddsi_plist_t pplist; - ddsi_plist_init_empty(&pplist); - pplist.present |= PP_IDENTITY_TOKEN; - ddsi_token_t identity_token = { - .class_id = NULL, - .properties = { - .n = 0, - .props = NULL - }, - .binary_properties = { - .n = 0, - .props = NULL - } - }; - pplist.identity_token = identity_token; - union { uint64_t u64; uint32_t u32[2]; } u; - u.u32[0] = gv.ppguid_base.prefix.u[1]; - u.u32[1] = gv.ppguid_base.prefix.u[2]; - u.u64 += ddsi_iid_gen (); - g_proxy_ppguid.prefix.u[0] = gv.ppguid_base.prefix.u[0]; - g_proxy_ppguid.prefix.u[1] = u.u32[0]; - g_proxy_ppguid.prefix.u[2] = u.u32[1]; - g_proxy_ppguid.entityid.u = DDSI_ENTITYID_PARTICIPANT; - ddsrt_wctime_t timestamp = { .v = dds_time() }; - if (!ddsi_new_proxy_participant(&gv, - &g_proxy_ppguid, - DDSI_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_ANNOUNCER, - NULL, - ddsi_new_addrset(), - ddsi_new_addrset(), - &pplist, - DDS_INFINITY, - DDSI_VENDORID_ECLIPSE, - DDSI_CF_PROXYPP_NO_SPDP, - timestamp, - 0)) { - abort(); + ddsi_plist_t pplist; + ddsi_plist_init_empty(&pplist); + pplist.present |= PP_IDENTITY_TOKEN; + ddsi_token_t identity_token = { + .class_id = strdup(DDS_SECURITY_AUTH_TOKEN_CLASS_ID), + .properties = { + .n = 0, + .props = NULL + }, + .binary_properties = { + .n = 0, + .props = NULL } + }; - harness.proxy_pp = ddsi_entidx_lookup_proxy_participant_guid(gv.entity_index, &g_proxy_ppguid); - ddsi_plist_fini(&pplist); + pplist.identity_token = identity_token; + union { uint64_t u64; uint32_t u32[2]; } u; + u.u32[0] = gv.ppguid_base.prefix.u[1]; + u.u32[1] = gv.ppguid_base.prefix.u[2]; + u.u64 += ddsi_iid_gen (); + g_proxy_ppguid.prefix.u[0] = gv.ppguid_base.prefix.u[0]; + g_proxy_ppguid.prefix.u[1] = u.u32[0]; + g_proxy_ppguid.prefix.u[2] = u.u32[1]; + g_proxy_ppguid.entityid.u = DDSI_ENTITYID_PARTICIPANT; + if (!initiate_remote) { + g_proxy_ppguid.prefix.s[0] = 0xff; + g_proxy_ppguid.prefix.s[1] = 0xff; + g_proxy_ppguid.prefix.s[2] = 0xff; + g_proxy_ppguid.prefix.s[3] = 0xff; + } else { + g_proxy_ppguid.prefix.s[0] = 0x00; + g_proxy_ppguid.prefix.s[1] = 0x00; + g_proxy_ppguid.prefix.s[2] = 0x00; + g_proxy_ppguid.prefix.s[3] = 0x00; + } + + ddsrt_wctime_t timestamp = { .v = dds_time() }; + + // We avoid generating network traffic by using DDSI_TRANS_NONE + // This is the only valid locator for that "network". + const ddsi_locator_t loc = { + .kind = 2147483647, .address = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, .port = 0 + }; + struct ddsi_addrset *as = ddsi_new_addrset(); + ddsi_add_locator_to_addrset(&gv,as, &loc); + assert(!ddsi_addrset_empty_uc(as)); + + if (!ddsi_new_proxy_participant(&gv, + &g_proxy_ppguid, + DDSI_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_ANNOUNCER| + DDSI_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_ANNOUNCER|DDSI_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_DETECTOR, + NULL, + as, + ddsi_ref_addrset(as), + &pplist, + DDS_INFINITY, + DDSI_VENDORID_ECLIPSE, + DDSI_CF_PROXYPP_NO_SPDP, + timestamp, + 0)) { + abort(); } - printf("domaingv %p\n", &gv); - printf("Participant %p\n", harness.pp); - printf("Participant domaingv %p\n", harness.pp->e.gv); - printf("Participant hsadmin %p\n", harness.pp->e.gv->hsadmin); - printf("Participant sec_attr %p\n", harness.pp->sec_attr); - printf("Proxy Participant %p\n", harness.proxy_pp); - printf("Proxy Participant domaingv %p\n", harness.proxy_pp->e.gv); - printf("Proxy Participant hsadmin %p\n", harness.proxy_pp->e.gv->hsadmin); + + harness.proxy_pp = ddsi_entidx_lookup_proxy_participant_guid(gv.entity_index, &g_proxy_ppguid); + ddsi_plist_fini(&pplist); + harness.hs = ddsi_handshake_find(harness.pp, harness.proxy_pp); - printf("Handshake %p\n", harness.hs); - return true; + if (harness.hs == NULL) abort(); + + // We abuse the debug function for the serialization of the fuzzer thread + // and the handshake fsm thread. + dds_security_fsm_set_debug(harness.hs->fsm, fsm_debug_func); + harness.hs->end_cb = hs_end_cb; } -void hs_end_cb(struct ddsi_handshake *handshake, struct ddsi_participant *pp, struct ddsi_proxy_participant *proxy_pp, enum ddsi_handshake_state state) +void fuzz_handshake_handle_timeout(void) { + dds_security_fsm_dispatch(harness.hs->fsm, DDS_SECURITY_FSM_EVENT_TIMEOUT, false); +} + +typedef DDS_Security_ValidationResult_t (*dhpkey2oct_t)(EVP_PKEY *, int, unsigned char **, uint32_t *, DDS_Security_SecurityException *); +dhpkey2oct_t dh_public_key_to_oct = NULL; + +typedef DDS_Security_ValidationResult_t (*gendhkeys_t)(EVP_PKEY **, int, DDS_Security_SecurityException *); +gendhkeys_t generate_dh_keys = NULL; + +static DDS_Security_ValidationResult_t create_dh_key(int algo, unsigned char **data, uint32_t *len) { + EVP_PKEY *key; + DDS_Security_SecurityException ex = {0}; + + if (generate_dh_keys == NULL) + generate_dh_keys = dlsym(NULL, "generate_dh_keys"); + + DDS_Security_ValidationResult_t result = generate_dh_keys(&key, algo, &ex); + if (result != DDS_SECURITY_VALIDATION_OK) goto out; + + if (dh_public_key_to_oct == NULL) + dh_public_key_to_oct = dlsym(NULL, "dh_public_key_to_oct"); + result = dh_public_key_to_oct(key, algo, data, len, &ex); +out: + EVP_PKEY_free(key); + DDS_Security_Exception_reset(&ex); + return result; +} + +void fuzz_handshake_handle_request(ddsi_dataholder_t *token) { + struct ddsi_participant_generic_message msg; + msg.message_class_id = DDS_SECURITY_AUTH_HANDSHAKE; + msg.message_data.n = 1; + msg.message_data.tags = token; + token->class_id = DDS_SECURITY_AUTH_HANDSHAKE_REQUEST_TOKEN_ID; + + for (uint32_t i = 0; i < token->binary_properties.n; i++) { + dds_binaryproperty_t *binprop = &token->binary_properties.props[i]; + // To avoid fuzzing openssl, always use a valid certificate + if (strcmp(binprop->name, "c.id") == 0) { + free(binprop->value.value); + binprop->value.length = strlen(TEST_IDENTITY3_CERTIFICATE); + binprop->value.value = (unsigned char *) strdup(TEST_IDENTITY3_CERTIFICATE); + } + // Provide a valid dh public key + if (strcmp(binprop->name, "dh1") == 0) { + if (dh_public_key_to_oct == NULL) + dh_public_key_to_oct = dlsym(NULL, "dh_public_key_to_oct"); + unsigned char *data; + uint32_t len; + if (create_dh_key(1, &data, &len) == DDS_SECURITY_VALIDATION_OK) { + free(binprop->value.value); + binprop->value.length = len; + binprop->value.value = data; + } + } + } + ddsi_handshake_handle_message(harness.hs, harness.pp, harness.proxy_pp, &msg); +} + +typedef DDS_Security_ValidationResult_t (*cvas_t)(bool, EVP_PKEY *, const unsigned char *, const size_t, unsigned char **, size_t *, DDS_Security_SecurityException *); +cvas_t create_validate_asymmetrical_signature = NULL; + +static void create_signature(const DDS_Security_BinaryProperty_t **bprops, uint32_t n_bprops, unsigned char **signature, size_t *signatureLen) { - ddsi_handshake_release(handshake); + unsigned char *buffer; + size_t size; + DDS_Security_Serializer serializer = DDS_Security_Serializer_new(4096, 4096); + DDS_Security_Serialize_BinaryPropertyArray(serializer, bprops, n_bprops); + DDS_Security_Serializer_buffer(serializer, &buffer, &size); + DDS_Security_SecurityException ex; + if (create_validate_asymmetrical_signature == NULL) + create_validate_asymmetrical_signature = dlsym(NULL, "create_validate_asymmetrical_signature"); + (void) create_validate_asymmetrical_signature(true, g_private_key, buffer, size, signature, signatureLen, &ex); + free(buffer); + DDS_Security_Serializer_free(serializer); } -void fuzz_handshake_reset(void) { - // Remove proxy participant, if created - // Release our handshake - ddsi_handshake_remove(harness.pp, harness.proxy_pp); - ddsi_handshake_register(harness.pp, harness.proxy_pp, hs_end_cb); - //harness.hs = ddsi_handshake_find(harness.pp, harness.proxy_pp); - if (harness.hs == NULL) abort(); - //// Make a new proxy participant - // Get the proxy participant - //harness.proxy_pp = ... - // Get the handshake +static void create_hash(const DDS_Security_DataHolder *dh, DDS_Security_BinaryProperty_t *bprop, const char *name) +{ + unsigned char *buffer; + size_t size; + + DDS_Security_BinaryProperty_t *tokens = DDS_Security_BinaryPropertySeq_allocbuf(5); + const DDS_Security_BinaryProperty_t *c_id = DDS_Security_DataHolder_find_binary_property(dh, "c.id"); + uint32_t tokidx = 0; + if (c_id) DDS_Security_BinaryProperty_copy(&tokens[tokidx++], c_id); + const DDS_Security_BinaryProperty_t *c_perm = DDS_Security_DataHolder_find_binary_property(dh, "c.perm"); + if (c_perm) DDS_Security_BinaryProperty_copy(&tokens[tokidx++], c_perm); + const DDS_Security_BinaryProperty_t *c_pdata = DDS_Security_DataHolder_find_binary_property(dh, "c.pdata"); + if (c_pdata) DDS_Security_BinaryProperty_copy(&tokens[tokidx++], c_pdata); + const DDS_Security_BinaryProperty_t *c_dsign_algo = DDS_Security_DataHolder_find_binary_property(dh, "c.dsign_algo"); + if (c_dsign_algo) DDS_Security_BinaryProperty_copy(&tokens[tokidx++], c_dsign_algo); + const DDS_Security_BinaryProperty_t *c_kagree_algo = DDS_Security_DataHolder_find_binary_property(dh, "c.kagree_algo"); + if (c_kagree_algo) DDS_Security_BinaryProperty_copy(&tokens[tokidx++], c_kagree_algo); + DDS_Security_BinaryPropertySeq seq = { ._length = tokidx, ._buffer = tokens }; + DDS_Security_Serializer serializer = DDS_Security_Serializer_new(4096, 4096); + DDS_Security_Serialize_BinaryPropertySeq(serializer, &seq); + DDS_Security_Serializer_buffer(serializer, &buffer, &size); + + unsigned char *hash = malloc(SHA256_DIGEST_LENGTH); + SHA256(buffer, size, hash); + free(buffer); + DDS_Security_Serializer_free(serializer); + + bprop->name = strdup(name); + bprop->value._length = SHA256_DIGEST_LENGTH; + bprop->value._maximum = SHA256_DIGEST_LENGTH; + bprop->value._buffer = hash; + DDS_Security_BinaryPropertySeq_deinit(&seq); + free(tokens); } +void fuzz_handshake_handle_reply(ddsi_dataholder_t *token) { + struct ddsi_participant_generic_message msg; + msg.message_class_id = DDS_SECURITY_AUTH_HANDSHAKE; + msg.message_data.n = 1; + msg.message_data.tags = token; + token->class_id = DDS_SECURITY_AUTH_HANDSHAKE_REPLY_TOKEN_ID; + const DDS_Security_BinaryProperty_t *c1 = NULL; + const DDS_Security_BinaryProperty_t *c2 = NULL; + const DDS_Security_BinaryProperty_t *dh1 = NULL; + const DDS_Security_BinaryProperty_t *dh2 = NULL; + const DDS_Security_BinaryProperty_t *hash_c1 = NULL; + const DDS_Security_BinaryProperty_t *kagree_algo = NULL; -void fuzz_handshake_handle_timeout(void) { - //dds_security_fsm_dispatch(harness.hs->fsm, DDS_SECURITY_FSM_EVENT_TIMEOUT, false); + if (harness.hs->handshake_message_out != NULL) { + // Using gv.handshake_include_optional = true; + c1 = DDS_Security_DataHolder_find_binary_property(harness.hs->handshake_message_out, "challenge1"); + dh1 = DDS_Security_DataHolder_find_binary_property(harness.hs->handshake_message_out, "dh1"); + hash_c1 = DDS_Security_DataHolder_find_binary_property(harness.hs->handshake_message_out, "hash_c1"); + kagree_algo = DDS_Security_DataHolder_find_binary_property(harness.hs->handshake_message_out, "c.kagree_algo"); + } + + // First fix up the values necessary for the hash + for (uint32_t i = 0; i < token->binary_properties.n; i++) { + dds_binaryproperty_t *binprop = &token->binary_properties.props[i]; + // To avoid fuzzing openssl, always use a valid certificate + if (strcmp(binprop->name, "c.id") == 0) { + free(binprop->value.value); + binprop->value.length = strlen(TEST_IDENTITY3_CERTIFICATE); + binprop->value.value = (unsigned char *) strdup(TEST_IDENTITY3_CERTIFICATE); + } + if ((strcmp(binprop->name, "challenge1") == 0) && c1) { + free(binprop->value.value); + binprop->value.length = DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE; + binprop->value.value = malloc(DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE); + memcpy(binprop->value.value, c1->value._buffer, DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE); + } + // Provide a valid dh public key + if ((strcmp(binprop->name, "dh2") == 0) && kagree_algo) { + if (dh_public_key_to_oct == NULL) + dh_public_key_to_oct = dlsym(NULL, "dh_public_key_to_oct"); + + int algo = 1; + if (strncmp((const char *)kagree_algo->value._buffer, "ECDH+prime256v1-CEUM", kagree_algo->value._length) == 0) algo = 2; + unsigned char *data; + uint32_t len; + if (create_dh_key(algo, &data, &len) == DDS_SECURITY_VALIDATION_OK) { + free(binprop->value.value); + binprop->value.length = len; + binprop->value.value = data; + } + } + } + + // Generate the hash to be signed + DDS_Security_DataHolder token_holder; + ddsi_omg_shallow_copyin_DataHolder(&token_holder, token); + c2 = DDS_Security_DataHolder_find_binary_property(&token_holder, "challenge2"); + dh2 = DDS_Security_DataHolder_find_binary_property(&token_holder, "dh2"); + DDS_Security_BinaryProperty_t hash_c2 = {0}; + create_hash(&token_holder, &hash_c2, "hash_c2"); + + for (uint32_t i = 0; i < token->binary_properties.n; i++) { + dds_binaryproperty_t *binprop = &token->binary_properties.props[i]; + // Need to provide a valid signature for the handshake to succeed + if (strcmp(binprop->name, "signature") == 0 && hash_c1 && c1 && c2 && dh1 && c2 && dh2 && hash_c2.value._buffer) { + unsigned char *signature; + size_t signatureLen; + const DDS_Security_BinaryProperty_t *bprops[] = { &hash_c2, c2, dh2, c1, dh1, hash_c1}; + create_signature(bprops, 6, &signature, &signatureLen); + free(binprop->value.value); + binprop->value.length = (uint32_t) signatureLen; + binprop->value.value = signature; + } + } + DDS_Security_BinaryProperty_deinit(&hash_c2); + ddsi_handshake_handle_message(harness.hs, harness.pp, harness.proxy_pp, &msg); + ddsi_omg_shallow_free_DataHolder(&token_holder); +} + +void fuzz_handshake_handle_final(ddsi_dataholder_t *token) { + struct ddsi_participant_generic_message msg; + msg.message_class_id = DDS_SECURITY_AUTH_HANDSHAKE; + msg.message_data.n = 1; + msg.message_data.tags = token; + token->class_id = DDS_SECURITY_AUTH_HANDSHAKE_FINAL_TOKEN_ID; + + const DDS_Security_BinaryProperty_t *c1 = NULL; + const DDS_Security_BinaryProperty_t *c2 = NULL; + const DDS_Security_BinaryProperty_t *dh1 = NULL; + const DDS_Security_BinaryProperty_t *dh2 = NULL; + const DDS_Security_BinaryProperty_t *hash_c1 = NULL; + const DDS_Security_BinaryProperty_t *hash_c2 = NULL; + + if (harness.hs->handshake_message_out != NULL) { + // Using gv.handshake_include_optional = true; + c1 = DDS_Security_DataHolder_find_binary_property(harness.hs->handshake_message_out, "challenge1"); + c2 = DDS_Security_DataHolder_find_binary_property(harness.hs->handshake_message_out, "challenge2"); + dh1 = DDS_Security_DataHolder_find_binary_property(harness.hs->handshake_message_out, "dh1"); + dh2 = DDS_Security_DataHolder_find_binary_property(harness.hs->handshake_message_out, "dh2"); + hash_c1 = DDS_Security_DataHolder_find_binary_property(harness.hs->handshake_message_out, "hash_c1"); + hash_c2 = DDS_Security_DataHolder_find_binary_property(harness.hs->handshake_message_out, "hash_c2"); + } + + for (uint32_t i = 0; i < token->binary_properties.n; i++) { + dds_binaryproperty_t *binprop = &token->binary_properties.props[i]; + // Need to copy the correct values for challenge2 from the relation for the handshake to succeed + if ((strcmp(binprop->name, "challenge1") == 0) && c1) { + free(binprop->value.value); + binprop->value.length = DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE; + binprop->value.value = malloc(DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE); + memcpy(binprop->value.value, c1->value._buffer, DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE); + } + if ((strcmp(binprop->name, "challenge2") == 0) && c2) { + free(binprop->value.value); + binprop->value.length = DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE; + binprop->value.value = malloc(DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE); + memcpy(binprop->value.value, c2->value._buffer, DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE); + } + // Need to provide a valid signature for the handshake to succeed + if (strcmp(binprop->name, "signature") == 0 && hash_c1 && c1 && c2 && dh1 && c2 && dh2 && hash_c2) { + unsigned char *signature; + size_t signatureLen; + const DDS_Security_BinaryProperty_t *bprops[] = { hash_c1, c1, dh1, c2, dh2, hash_c2 }; + create_signature(bprops, 6, &signature, &signatureLen); + free(binprop->value.value); + binprop->value.length = (uint32_t) signatureLen; + binprop->value.value = signature; + } + } + + ddsi_handshake_handle_message(harness.hs, harness.pp, harness.proxy_pp, &msg); +} + +void fuzz_handshake_handle_crypto_tokens(void) { + ddsi_handshake_crypto_tokens_received(harness.hs); +} + +void fuzz_handshake_wait_for_event(uint32_t event) { + dds_security_fsm_dispatch(harness.hs->fsm, FUZZ_HANDSHAKE_EVENT_HANDLED, false); + while(ddsrt_atomic_ld32(&g_fuzz_events) != event) {} +} + +void fuzz_handshake_wait_for_completion(void) { + dds_security_fsm_dispatch(harness.hs->fsm, DDS_SECURITY_FSM_EVENT_DELETE, false); + while(ddsrt_atomic_ld32(&g_fsm_done) == 0) {} + ddsrt_wctime_t timestamp = { .v = dds_time() }; + ddsi_delete_proxy_participant_by_guid(&gv, &g_proxy_ppguid, timestamp, 1); + harness.proxy_pp = NULL; + harness.hs = NULL; } -void fuzz_handshake_handle_request(void) {} -void fuzz_handshake_handle_reply(void) {} -void fuzz_handshake_handle_final(void) {} -void fuzz_handshake_handle_crypto_tokens(void) {} diff --git a/fuzz/fuzz_handshake/fuzz_handshake_harness.h b/fuzz/fuzz_handshake/fuzz_handshake_harness.h index 373621af4c..de3dcd4a3f 100644 --- a/fuzz/fuzz_handshake/fuzz_handshake_harness.h +++ b/fuzz/fuzz_handshake/fuzz_handshake_harness.h @@ -1,8 +1,21 @@ +#include +#include + #include + +#if defined(__cplusplus) +extern "C" { +#endif bool fuzz_handshake_init(void); -void fuzz_handshake_reset(void); +void fuzz_handshake_reset(bool initiate_remote); void fuzz_handshake_handle_timeout(void); -void fuzz_handshake_handle_request(void); -void fuzz_handshake_handle_reply(void); -void fuzz_handshake_handle_final(void); +void fuzz_handshake_handle_force_handshake_request(void); +void fuzz_handshake_handle_request(ddsi_dataholder_t *token); +void fuzz_handshake_handle_reply(ddsi_dataholder_t *token); +void fuzz_handshake_handle_final(ddsi_dataholder_t *token); void fuzz_handshake_handle_crypto_tokens(void); +void fuzz_handshake_wait_for_event(uint32_t event); +void fuzz_handshake_wait_for_completion(void); +#if defined(__cplusplus) +} +#endif diff --git a/fuzz/fuzz_handshake/fuzz_handshake_seed_corpus/handshake_reply b/fuzz/fuzz_handshake/fuzz_handshake_seed_corpus/handshake_reply new file mode 100644 index 0000000000..73aa55597a --- /dev/null +++ b/fuzz/fuzz_handshake/fuzz_handshake_seed_corpus/handshake_reply @@ -0,0 +1,60 @@ +initiate_remote: false +events { + timeout { + } +} +events { + reply { + token { + binary_properties { + name: "c.id", + value: "", + propagate: false + } + binary_properties { + name: "c.perm", + value: "", + propagate: false + } + binary_properties { + name: "c.pdata", + value: "\0\120\0\20\266\202\310\131\55\340\25\354\173\360\265\7\0\0\0\0\0\1\0\0", + propagate: false + } + binary_properties { + name: "c.dsign_algo", + value: "ECDSA-SHA256", + propagate: false + } + binary_properties { + name: "c.kagree_algo", + value: "ECDH+prime256v1-CEUM", + propagate: false + } + binary_properties { + name: "challenge1", + value: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", + propagate: false + } + binary_properties { + name: "challenge2", + value: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", + propagate: false + } + binary_properties { + name: "signature", + value: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", + propagate: false + } + binary_properties { + name: "dh2", + value: "\002\001\001", + propagate: false + } + } + } +} +events { + crypto_tokens { + } +} diff --git a/fuzz/fuzz_handshake/fuzz_handshake_seed_corpus/handshake_request_final b/fuzz/fuzz_handshake/fuzz_handshake_seed_corpus/handshake_request_final new file mode 100644 index 0000000000..d43c5d654f --- /dev/null +++ b/fuzz/fuzz_handshake/fuzz_handshake_seed_corpus/handshake_request_final @@ -0,0 +1,67 @@ +initiate_remote: true +events { + request { + token { + binary_properties { + name: "c.id", + value: "", + propagate: false + }, + binary_properties { + name: "c.perm", + value: "", + propagate: false + } + binary_properties { + name: "c.pdata", + value: "\0\120\0\20\266\202\310\131\55\340\25\354\173\360\265\7\0\0\0\0\0\1\0\0", + propagate: false + } + binary_properties { + name: "c.dsign_algo", + value: "RSASSA-PSS-SHA256", + propagate: false + } + binary_properties { + name: "c.kagree_algo", + value: "DH+MODP-2048-256", + propagate: false + } + binary_properties { + name: "dh1", + value: "\002\001\001", + propagate: false + } + binary_properties { + name: "challenge1", + value: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", + propagate: false + } + } + } +} +events { + final { + token { + binary_properties { + name: "challenge1", + value: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", + propagate: false + } + binary_properties { + name: "challenge2", + value: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", + propagate: false + } + binary_properties { + name: "signature", + value: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", + propagate: false + } + } + } +} +events { + crypto_tokens { + } +} diff --git a/fuzz/oss-fuzz-build.sh b/fuzz/oss-fuzz-build.sh index fabb697556..c86abc1284 100644 --- a/fuzz/oss-fuzz-build.sh +++ b/fuzz/oss-fuzz-build.sh @@ -22,7 +22,7 @@ cmake \ -DBUILD_TESTING=ON \ -DBUILD_SHARED_LIBS=OFF \ -DBUILD_EXAMPLES=NO \ - -DENABLE_SECURITY=NO \ + -DENABLE_SECURITY=ON \ -DENABLE_SSL=NO \ -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ -DCMAKE_INSTALL_PREFIX=/usr/local .. From 4765392c690a3a5248e261b56a3a1fe33db1f3fe Mon Sep 17 00:00:00 2001 From: Andrianov Roman Date: Wed, 3 Apr 2024 14:57:33 +0200 Subject: [PATCH 059/207] qos_provider support (#1955) * qos_provider support added * qos_provider tests * qos_provider documentation * qos_provider build flag * system definition parsing support Signed-off-by: Splinter1984 * fix #1955 remarks * CI analyzer comliant fixes Signed-off-by: Splinter1984 --------- Signed-off-by: Splinter1984 --- README.md | 1 + docs/manual/about_dds/eclipse_cyclone_dds.rst | 65 +- docs/manual/about_dds/qos_provider.rst | 402 +++ docs/manual/api/qosprovider.rst | 6 + docs/manual/ddsc.rst | 1 + docs/manual/external-links.part.rst | 64 +- src/CMakeLists.txt | 1 + src/core/CMakeLists.txt | 13 + src/core/ddsc/CMakeLists.txt | 13 + src/core/ddsc/include/dds/dds.h | 1 + .../dds/ddsc/dds_public_qos_provider.h | 121 + src/core/ddsc/src/dds__qos_provider.h | 47 + src/core/ddsc/src/dds__sysdef_model.h | 706 ++++ src/core/ddsc/src/dds__sysdef_parser.h | 145 + src/core/ddsc/src/dds__sysdef_validation.h | 26 + src/core/ddsc/src/dds_qos_provider.c | 292 ++ src/core/ddsc/src/dds_sysdef_parser.c | 3065 +++++++++++++++++ src/core/ddsc/src/dds_sysdef_validation.c | 141 + src/core/ddsc/tests/CMakeLists.txt | 5 + src/core/ddsc/tests/qos_provider.c | 1205 +++++++ src/core/xtests/symbol_export/symbol_export.c | 11 + src/ddsrt/CMakeLists.txt | 2 +- src/ddsrt/include/dds/ddsrt/log.h | 4 + src/ddsrt/include/dds/features.h.in | 4 + 24 files changed, 6278 insertions(+), 63 deletions(-) create mode 100644 docs/manual/about_dds/qos_provider.rst create mode 100644 docs/manual/api/qosprovider.rst create mode 100644 src/core/ddsc/include/dds/ddsc/dds_public_qos_provider.h create mode 100644 src/core/ddsc/src/dds__qos_provider.h create mode 100644 src/core/ddsc/src/dds__sysdef_model.h create mode 100644 src/core/ddsc/src/dds__sysdef_parser.h create mode 100644 src/core/ddsc/src/dds__sysdef_validation.h create mode 100644 src/core/ddsc/src/dds_qos_provider.c create mode 100644 src/core/ddsc/src/dds_sysdef_parser.c create mode 100644 src/core/ddsc/src/dds_sysdef_validation.c create mode 100644 src/core/ddsc/tests/qos_provider.c diff --git a/README.md b/README.md index 808566ded4..2345238261 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ There are some configuration options specified using CMake defines in addition t * `-DENABLE_SOURCE_SPECIFIC_MULTICAST=NO`: to disable support for source-specific multicast (disabling this and `-DENABLE_IPV6=NO` may be needed for QNX builds) * `-DENABLE_IPV6=NO`: to disable ipv6 support (disabling this and `-DENABLE_SOURCE_SPECIFIC_MULTICAST=NO` may be needed for QNX builds) * `-DBUILD_IDLC_XTESTS=NO`: Include a set of tests for the IDL compiler that use the C back-end to compile an idl file at (test) runtime, and use the C compiler to build a test application for the generated types, that is executed to do the actual testing (not supported on Windows) +* `-DENABLE_QOS_PROVIDER=NO`: to disable support for qos provider ### For application developers diff --git a/docs/manual/about_dds/eclipse_cyclone_dds.rst b/docs/manual/about_dds/eclipse_cyclone_dds.rst index 280ecdb46f..66448cc1e7 100644 --- a/docs/manual/about_dds/eclipse_cyclone_dds.rst +++ b/docs/manual/about_dds/eclipse_cyclone_dds.rst @@ -22,6 +22,7 @@ datareaders datawriters qos + qos_provider listener waitset status @@ -30,13 +31,13 @@ ddsi_concepts contributing -|var-project| is a performant and robust OMG-compliant **Data Distribution Service** -(DDS) implementation (see |url::dds_spec|). |var-project-short| is developed -completely in the open as an Eclipse IoT project (see |url::cyclone_dds-link|) with a -growing list of |url::cyclone_adopters|. It is a tier-1 middleware for the Robot +|var-project| is a performant and robust OMG-compliant **Data Distribution Service** +(DDS) implementation (see |url::dds_spec|). |var-project-short| is developed +completely in the open as an Eclipse IoT project (see |url::cyclone_dds-link|) with a +growing list of |url::cyclone_adopters|. It is a tier-1 middleware for the Robot Operating System |url::ros2|. -The core of |var-project-short| is implemented in C and provides C-APIs to applications. +The core of |var-project-short| is implemented in C and provides C-APIs to applications. Through its C++ package, the |url::omg.org| 2003 language binding is also supported. .. index:: About DDS @@ -44,14 +45,14 @@ Through its C++ package, the |url::omg.org| 2003 language binding is also suppor About DDS ========= -DDS is the best-kept secret in distributed systems, one that has been around for much +DDS is the best-kept secret in distributed systems, one that has been around for much longer than most publish-subscribe messaging systems and still outclasses so many of them. -DDS is used in a wide variety of systems, including air-traffic control, jet engine -testing, railway control, medical systems, naval command-and-control, smart greenhouses -and much more. In short, it is well-established in aerospace and defense but no longer +DDS is used in a wide variety of systems, including air-traffic control, jet engine +testing, railway control, medical systems, naval command-and-control, smart greenhouses +and much more. In short, it is well-established in aerospace and defense but no longer limited to that. And yet it is easy to use! -Types are usually defined in IDL and preprocessed with the IDL compiler included in Cyclone, +Types are usually defined in IDL and preprocessed with the IDL compiler included in Cyclone, but our |url::python-link2| allows you to define data types on the fly: .. code-block:: python @@ -96,30 +97,30 @@ but our |url::python-link2| allows you to define data types on the fly: print("Read ", sample) sleep(rng.exponential()) -Today DDS is also popular in robotics and autonomous vehicles because those really -depend on high-throughput, low-latency control systems without introducing a single -point of failure by having a message broker in the middle. Indeed, it is by far the -most used and the default middleware choice in ROS 2. It is used to transfer commands, +Today DDS is also popular in robotics and autonomous vehicles because those really +depend on high-throughput, low-latency control systems without introducing a single +point of failure by having a message broker in the middle. Indeed, it is by far the +most used and the default middleware choice in ROS 2. It is used to transfer commands, sensor data and even video and point clouds between components. -The OMG DDS specifications cover everything one needs to build systems using -publish-subscribe messaging. They define a structural type system that allows -automatic endianness conversion and type checking between readers and writers. This -type system also supports type evolution. The interoperable networking protocol and -standard C++ API make it easy to build systems that integrate multiple DDS -implementations. Zero-configuration discovery is also included in the standard and +The OMG DDS specifications cover everything one needs to build systems using +publish-subscribe messaging. They define a structural type system that allows +automatic endianness conversion and type checking between readers and writers. This +type system also supports type evolution. The interoperable networking protocol and +standard C++ API make it easy to build systems that integrate multiple DDS +implementations. Zero-configuration discovery is also included in the standard and supported by all implementations. -DDS actually brings more: publish-subscribe messaging is a nice abstraction over -"ordinary" networking, but plain publish-subscribe doesn't affect how one *thinks* -about systems. A very powerful architecture that truly changes the perspective on -distributed systems is that of the "shared data space", in itself an old idea, and -really just a distributed database. Most shared data space designs have failed -miserably in real-time control systems because they provided strong consistency -guarantees and sacrificed too much performance and flexibility. The *eventually -consistent* shared data space of DDS has been very successful in helping with building -systems that need to satisfy many "ilities": dependability, maintainability, -extensibility, upgradeability, ... Truth be told, that's why it was invented, and +DDS actually brings more: publish-subscribe messaging is a nice abstraction over +"ordinary" networking, but plain publish-subscribe doesn't affect how one *thinks* +about systems. A very powerful architecture that truly changes the perspective on +distributed systems is that of the "shared data space", in itself an old idea, and +really just a distributed database. Most shared data space designs have failed +miserably in real-time control systems because they provided strong consistency +guarantees and sacrificed too much performance and flexibility. The *eventually +consistent* shared data space of DDS has been very successful in helping with building +systems that need to satisfy many "ilities": dependability, maintainability, +extensibility, upgradeability, ... Truth be told, that's why it was invented, and publish-subscribe messaging was simply an implementation technique. |var-project| aims at full coverage of the specs and today already covers most of this. @@ -136,8 +137,8 @@ With references to the individual OMG specifications, the following is available - |url::dds_xtypes| - the structural type system (some [caveats](docs/dev/xtypes_relnotes.md) here) - |url::dds2.5| - the interoperable network protocol -The network stack in |var-project| has been around for over a decade in one form or -another and has proven itself in many systems, including large, high-availability +The network stack in |var-project| has been around for over a decade in one form or +another and has proven itself in many systems, including large, high-availability ones and systems where inter-operation with other implementations was needed. .. include:: disclaimer.part.rst \ No newline at end of file diff --git a/docs/manual/about_dds/qos_provider.rst b/docs/manual/about_dds/qos_provider.rst new file mode 100644 index 0000000000..4de6874a00 --- /dev/null +++ b/docs/manual/about_dds/qos_provider.rst @@ -0,0 +1,402 @@ +.. + Copyright(c) 2024 ZettaScale Technology and others + + This program and the accompanying materials are made available under the + terms of the Eclipse Public License v. 2.0 which is available at + http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + v. 1.0 which is available at + http://www.eclipse.org/org/documents/edl-v10.php. + + SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +.. include:: ../external-links.part.rst +.. index:: ! QoS Provider + +.. _qos_provider: + +QoS Provider +############ + +This page provides information on using the QoS provider API of |var-project|. The QoS provider API allows users to specify the QoS settings of their DDS entities outside of application code in XML. This can be seen as a useful feature where code recompilation is restricted during the later stages of application development / during application support. The following sections explain the API and explain how to build QoS Profiles in XML. + +XML file syntax +=============== + +The syntax for the XML configuration file is defined in |url::omg_xml_1.0|. + +Entity QoS +---------- + +To configure the QoS for a DDS Entity using XML, the following tags have to be used: + +- `` +- `` +- `` +- `` +- `` +- `` + +Each XML tag with or without an associated name can be uniquely identified by its fully qualified name in C++ style. +In case of unnamed XML tag, only one tag of this kind is allowed in scope of parent ``. + +QoS Policies +------------ + +The fields in a Qos policy are described in XML using a 1-to-1 mapping with the equivalent IDL representation in the DDS specification. For example, the Reliability Qos policy is represented with the following structures: + +.. code-block:: C + + struct Duration_t { + long sec; + unsigned long nanosec; + }; + struct ReliabilityQosPolicy { + ReliabilityQosPolicyKind kind; + Duration_t max_blocking_time; + }; + +The equivalent representation in XML is as follows: + +.. code-block:: xml + + + + + + + + + +Sequences +--------- + +In general, the sequences contained in the QoS policies are described with the following XML format: + +.. code-block:: xml + + + ... + ... + ... + + +Each element of the sequence is enclosed in an tag, as shown in the following example: + +.. code-block:: xml + + + + + my name + my value + + + my name2 + my value2 + + + + + +Enumerations +------------ + +Enumeration values are represented using their IDL string representation. For example: + +.. code-block:: xml + + + KEEP_ALL_HISTORY_QOS + + + +Time values (Durations) +----------------------- + +Following values can be used for fields that require seconds or nanoseconds: + +- DURATION_INFINITE_SEC +- DURATION_INFINITE_NSEC + +The following example shows the use of time values: + +.. code-block:: xml + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + +QoS Profiles +------------ + +A QoS profile groups a set of related QoS, usually one per entity. For example: + +.. code-block:: xml + + + + + KEEP_LAST_HISTORY_QOS + 5 + + + + + KEEP_LAST_HISTORY_QOS + 1 + + + + +XML Example +----------- + +Consider the following XML file that describes two QoS profiles: + +- FooQosProfile + - DataReaderQos - KEEP_LAST (5) + - DataWriterQos - KEEP_LAST (1) + - TopicQos - KEEP_ALL +- BarQosProfile + - DataWriterQos - KEEP_ALL + - TopicQos - KEEP_LAST (5) + + +.. code-block:: xml + + + + + + + KEEP_LAST_HISTORY_QOS + 5 + + + + + KEEP_LAST_HISTORY_QOS + 1 + + + + + KEEP_ALL_HISTORY_QOS + + + + + + + KEEP_ALL_HISTORY_QOS + + + + + KEEP_LAST_HISTORY_QOS + 10 + + + + + + + +Code Example +============ + +The following C application is an example to illustrate how the QoS settings from the above XML could be accessed. + +.. tabs:: + + .. group-tab:: C + + .. code-block:: C + + #include "dds/dds.h" + #include "dds/ddsc/dds_qos_provider.h" + #include "datatypes.h" + + int main (int argc, char **argv) + { + (void) argc; + (void) argv; + + // provider will contains: + // myqoslib::foo_profile READER (KEEP_LAST 5) + // myqoslib::foo_profile WRITER (KEEP_LAST 1) + // myqoslib::foo_profile::my_topic TOPIC (KEEP_ALL) + // myqoslib::bar_profile WRITER (KEEP_ALL) + // myqoslib::bar_profile::my_topic TOPIC (KEEP_LAST 10) + dds_qos_provider_t *provider; + dds_return_t ret = dds_create_qos_provider ("/path/to/qos_definitions.xml", &provider); + assert (ret == DDS_RETCODE_OK); + + const dds_qos_t *tp_qos, *wr_qos; + // qos can be accessed by ::::[entity_name] if exist. + ret = dds_qos_provider_get_qos (provider, DDS_TOPIC_QOS, "myqoslib::bar_profile::my_topic", &tp_qos); + assert (ret == DDS_RETCODE_OK); + // or if entity_qos is unnamed only by ::. + ret = dds_qos_provider_get_qos (provider, DDS_WRITER_QOS, "myqoslib::bar_profile", &wr_qos); + assert (ret == DDS_RETCODE_OK); + + dds_entity_t pp = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL); + dds_entity_t tp = dds_create_topic (pp, &mydatatype_desc, "topic_A", tp_qos, NULL); + dds_entity_t wr = dds_create_writer (pp, tp, wr_qos, NULL); + dds_delete (pp); + dds_delete_qos_provider (provider); + + return 0; + } + + .. group-tab:: C++ + + .. code-block:: C++ + + #include "dds/dds.hpp" + #include "DataType.hpp" + + using namespace org::eclipse::cyclonedds; + + int main() + { + // provider will contains: + // myqoslib::foo_profile READER (KEEP_LAST 5) + // myqoslib::foo_profile WRITER (KEEP_LAST 1) + // myqoslib::foo_profile::my_topic TOPIC (KEEP_ALL) + // myqoslib::bar_profile WRITER (KEEP_ALL) + // myqoslib::bar_profile::my_topic TOPIC (KEEP_LAST 10) + dds::core::QosProvider provider("/path/to/qos_definitions.xml"); + auto topic_qos = provider.topic_qos("myqoslib::bar_profile::my_topic"); + auto writer_qos = provider.datawriter_qos("myqoslib::bar_profile"); + + dds::domain::DomainParticipant participant(domain::default_id()); + dds::topic::Topic topic(participant, "topic_A", topic_qos); + dds::pub::Publisher publisher(participant); + dds::pub::DataWriter writer(publisher, topic, writer_qos); + (void)writer; + return 0; + } + +Also C API allows you to specify which library, profile QoS Provider should contains. +Let's extend XML file example above, and omit QoS settings details for simplicity. + +.. code-block:: xml + + + + + + + + + + + + + + + + + + + + + + + + + + +Let's create QoS Provider that contains versions of both profiles from different libraries. + +.. tabs:: + + .. group-tab:: C + + .. code-block:: C + + #include "dds/dds.h" + #include "dds/ddsc/dds_qos_provider.h" + #include "datatypes.h" + + int main (int argc, char **argv) + { + (void) argc; + (void) argv; + + // foo_provider will contains: + // qos1_lib::foo_profile READER + // qos1_lib::foo_profile WRITER + // qos1_lib::foo_profile TOPIC + // qos2_lib::foo_profile READER + // qos2_lib::foo_profile WRITER + // qos2_lib::foo_profile TOPIC + dds_qos_provider_t *foo_provider; + char *foo_scope = "*::foo_profile"; + dds_return_t ret = dds_create_qos_provider_scope ("/path/to/qos_definitions.xml", &foo_provider, foo_scope); + assert (ret == DDS_RETCODE_OK); + + // bar_provider will contains: + // qos1_lib::bar_profile WRITER + // qos1_lib::bar_profile TOPIC + // qos2_lib::bar_profile WRITER + // qos2_lib::bar_profile TOPIC + dds_qos_provider_t *bar_provider; + char *bar_scope = "*::bar_profile"; + dds_return_t ret = dds_create_qos_provider_scope ("/path/to/qos_definitions.xml", &bar_provider, bar_scope); + assert (ret == DDS_RETCODE_OK); + ... + dds_delete_qos_provider (foo_provider); + dds_delete_qos_provider (bar_provider); + + return 0; + } + + .. group-tab:: C++ + + .. code-block:: C++ + + #include "dds/dds.hpp" + #include "DataType.hpp" + + using namespace org::eclipse::cyclonedds; + + int main() + { + // foo_provider will contains: + // qos1_lib::foo_profile READER + // qos1_lib::foo_profile WRITER + // qos1_lib::foo_profile TOPIC + // qos2_lib::foo_profile READER + // qos2_lib::foo_profile WRITER + // qos2_lib::foo_profile TOPIC + std::string foo_scope = "*::foo_profile"; + dds::core::QosProvider foo_provider("/path/to/qos_definitions.xml", foo_scope); + + // bar_provider will contains: + // qos1_lib::bar_profile WRITER + // qos1_lib::bar_profile TOPIC + // qos2_lib::bar_profile WRITER + // qos2_lib::bar_profile TOPIC + std::string bar_scope = "*::bar_profile"; + dds::core::QosProvider bar_provider("/path/to/qos_definitions.xml", bar_scope); + ... + return 0; + } + +Known limitations +================= + +- Inheritance of QoS policies and QoS profiles in XML using the "base_name" attribute is not supported +- The "topic_filter" attribute for writer, reader and topic QoSes to associate a set of topics to a specific QoS when that QoS is part of a DDS profile, is not supported yet. +- The "entity_factory" attribute for participant, writer and reader QoSes, is not supported yet. +- The <(user|topic|group)_data> base64 syntax is not supported yet. +- The C++ API QosProvider may throw an UnsupportedError when trying to access a policy that is not supported yet. diff --git a/docs/manual/api/qosprovider.rst b/docs/manual/api/qosprovider.rst new file mode 100644 index 0000000000..e8475f2554 --- /dev/null +++ b/docs/manual/api/qosprovider.rst @@ -0,0 +1,6 @@ +QosProvider +=========== + +.. doxygengroup:: qos_provider + :project: ddsc_api_docs + :members: diff --git a/docs/manual/ddsc.rst b/docs/manual/ddsc.rst index d0b2e0d31a..30ca91b846 100644 --- a/docs/manual/ddsc.rst +++ b/docs/manual/ddsc.rst @@ -22,6 +22,7 @@ C API reference api/basics api/entity api/qos + api/qosprovider api/domain api/topic api/data diff --git a/docs/manual/external-links.part.rst b/docs/manual/external-links.part.rst index ec60eb7bab..c52e892a9d 100644 --- a/docs/manual/external-links.part.rst +++ b/docs/manual/external-links.part.rst @@ -29,47 +29,47 @@ DDSI-RTPS 2.5 .. |url::omg.org| raw:: html - + DDS ISO/IEC C++ PSM API .. |url::dds_xtypes| raw:: html - + DDS XTypes .. |url::ros2| raw:: html - + ROS 2 .. |url::omg.security| raw:: html - + DDS security .. |url::logoimage| raw:: html - + .. |url::python-link| raw:: html - + Eclipse Cyclone DDS: Python API documentation .. |url::python-link2| raw:: html - + Python binding .. |url::cyclone_dds-link| raw:: html - + Eclipse Cyclone DDS .. |url::cyclone_adopters| raw:: html - + adopters .. |url::cyclone_git_logo| raw:: html - + logo .. |url::cpp-link| raw:: html - + Eclipse Cyclone DDS: C++ API documentation .. |url::git_link| raw:: html @@ -105,80 +105,80 @@ Scoop .. |url::c-api-liveliness| raw:: html - + dds_liveliness_kind .. |url::rfc5751_link| raw:: html - + IETF RFC 5751 .. |url::rfc5751_2-4-2_link| raw:: html - + IETF RFC 5751 section 2.4.2 .. |url::rfc5751_3-4-3_link| raw:: html - + IETF RFC 5751 section 3.4.3 .. |url::DDS_plugins| raw:: html - + DDS Plugins .. |url::DDS_plugins_access-control| raw:: html - + access control plugin .. |url::DDS_plugins_authentication| raw:: html - + authentication plugin .. |url::DDS_plugins_cryptographic| raw:: html - + cryptographic plugin .. |url::iceoryx_issues| raw:: html - + iceoryx issues .. |url::adlink-ROS| raw:: html - + ADLINK Advanced Robotics Platform Group .. |url::Apex.AI| raw:: html - + Apex.AI .. |url::iceoryx_introspection| raw:: html - + iceoryx introspection .. |url::scripts| raw:: html - + Scripts .. |url::environment_details| raw:: html - + Environment details .. |url::throughput| raw:: html - + Throughput .. |url::latency| raw:: html - + Latency .. |url::helloworld_cpp_github| raw:: html - + GitHub cyclonedds-cxx/examples/helloworld/ .. |url::helloworld_c_github| raw:: html - + GitHub cyclonedds/examples/helloworld/ .. |url::ddsperf_github| raw:: html - + GitHub ddsperf .. |url::cpp_api_link| raw:: html @@ -196,3 +196,7 @@ .. |url::runtype_link| raw:: html runtype + +.. |url::omg_xml_1.0| raw:: html + + DDS Consolidated XML Syntax diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index da328a2ea2..9240255504 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,6 +32,7 @@ option(ENABLE_IPV6 "Enable ipv6 support" ON) option(ENABLE_TYPELIB "Enable Type Library support" ON) option(ENABLE_TYPE_DISCOVERY "Enable Type Discovery support" ON) option(ENABLE_TOPIC_DISCOVERY "Enable Topic Discovery support" ON) +option(ENABLE_QOS_PROVIDER "Enable Qos Provider support" ON) if(ENABLE_TYPE_DISCOVERY) if(NOT ENABLE_TYPELIB) message(FATAL_ERROR "ENABLE_TYPE_DISCOVERY requires ENABLE_TYPELIB to be enabled") diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 2c5761e36b..a37f837212 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -133,6 +133,19 @@ set_property( TARGET ddsc APPEND PROPERTY EXPORT_PROPERTIES "TOPIC_DISCOVERY_IS_AVAILABLE") +# define target property to indicate if Cyclone DDS is compiled with qos provider +define_property(TARGET + PROPERTY QOS_PROVIDER_IS_AVAILABLE + BRIEF_DOCS "Indicator whether qos provider is available with current Cyclone DDS build configuration." + FULL_DOCS "Indicator whether qos provider is available with current Cyclone DDS build configuration." + ) +set_property( + TARGET ddsc + APPEND PROPERTY QOS_PROVIDER_IS_AVAILABLE "${ENABLE_QOS_PROVIDER}") +set_property( + TARGET ddsc + APPEND PROPERTY EXPORT_PROPERTIES "QOS_PROVIDER_IS_AVAILABLE") + # Create a pseudo-target that other targets (i.e. examples, tests) can depend # on and can also be provided as import-target by a package-file when building # those targets outside the regular Cyclone build-tree (i.e. the installed tree) diff --git a/src/core/ddsc/CMakeLists.txt b/src/core/ddsc/CMakeLists.txt index dd21a6772d..9ac86c23e3 100644 --- a/src/core/ddsc/CMakeLists.txt +++ b/src/core/ddsc/CMakeLists.txt @@ -51,6 +51,12 @@ prepend(srcs_ddsc "${CMAKE_CURRENT_LIST_DIR}/src/" if(ENABLE_TYPELIB) list(APPEND srcs_ddsc "${CMAKE_CURRENT_LIST_DIR}/src/dds_dynamic_type.c") endif() +if(ENABLE_QOS_PROVIDER) + list(APPEND srcs_ddsc + "${CMAKE_CURRENT_LIST_DIR}/src/dds_sysdef_parser.c" + "${CMAKE_CURRENT_LIST_DIR}/src/dds_sysdef_validation.c" + "${CMAKE_CURRENT_LIST_DIR}/src/dds_qos_provider.c") +endif() prepend(hdrs_private_ddsc "${CMAKE_CURRENT_LIST_DIR}/src/" dds__builtin.h @@ -81,6 +87,10 @@ prepend(hdrs_private_ddsc "${CMAKE_CURRENT_LIST_DIR}/src/" dds__loaned_sample.h dds__heap_loan.h dds__psmx.h + dds__sysdef_model.h + dds__sysdef_parser.h + dds__sysdef_validation.h + dds__qos_provider.h ) prepend(hdrs_public_ddsc "$$/dds/" @@ -104,6 +114,9 @@ prepend(hdrs_public_ddsc "$$< if(ENABLE_TYPELIB) list(APPEND hdrs_public_ddsc "$$/dds/ddsc/dds_public_dynamic_type.h") endif() +if(ENABLE_QOS_PROVIDER) + list(APPEND hdrs_public_ddsc "$$/dds/ddsc/dds_public_qos_provider.h") +endif() generate_export_header( ddsc BASE_NAME DDS EXPORT_FILE_NAME include/dds/export.h) diff --git a/src/core/ddsc/include/dds/dds.h b/src/core/ddsc/include/dds/dds.h index 60b73aa017..b196553aae 100644 --- a/src/core/ddsc/include/dds/dds.h +++ b/src/core/ddsc/include/dds/dds.h @@ -47,6 +47,7 @@ #include "dds/ddsc/dds_public_listener.h" #include "dds/ddsc/dds_public_dynamic_type.h" #include "dds/ddsc/dds_public_loan_api.h" +#include "dds/ddsc/dds_public_qos_provider.h" #if defined (__cplusplus) extern "C" { diff --git a/src/core/ddsc/include/dds/ddsc/dds_public_qos_provider.h b/src/core/ddsc/include/dds/ddsc/dds_public_qos_provider.h new file mode 100644 index 0000000000..6e84126b51 --- /dev/null +++ b/src/core/ddsc/include/dds/ddsc/dds_public_qos_provider.h @@ -0,0 +1,121 @@ +// Copyright(c) 2024 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause +#ifndef DDS_QOS_PROVIDER_H +#define DDS_QOS_PROVIDER_H + +#include "dds/export.h" +#include "dds/ddsrt/retcode.h" +#include "dds/ddsc/dds_public_qosdefs.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#ifdef DDS_HAS_QOS_PROVIDER + +/** + * @defgroup qos_provider (QosProvider) + * @ingroup dds + * The Qos Provider API. + */ + +/** + * @brief All kind of entities for which qos can be stored in Profile. + * @ingroup qos_provider + * @component qos_provider_api + */ +enum dds_qos_kind +{ + DDS_PARTICIPANT_QOS, + DDS_PUBLISHER_QOS, + DDS_SUBSCRIBER_QOS, + DDS_TOPIC_QOS, + DDS_READER_QOS, + DDS_WRITER_QOS +}; +typedef enum dds_qos_kind dds_qos_kind_t; + +/** + * @brief Sample structure of the Qos Provider. + * @ingroup qos_provider + * @component qos_provider_api + */ +struct dds_qos_provider; +typedef struct dds_qos_provider dds_qos_provider_t; + +/** + * @brief Initialize Qos Provider. + * @ingroup qos_provider + * @component qos_provider_api + * + * Create dds_qos_provider with provided system definition file path. + * + * @param[in] path - String that contains system definition inself or path to system defenition file. + * @param[in,out] provider - Pointer to the Qos Provider structure. + * + * @return a DDS return code + */ +DDS_EXPORT dds_return_t +dds_create_qos_provider (const char *path, dds_qos_provider_t **provider); + +/** + * @brief Initialize Qos Provider with certain scope. + * @ingroup qos_provider + * @component qos_provider_api + * + * Create dds_qos_provider with provided system definition file path and scope. + * + * @param[in] path - String that contains system definition inself or path to system defenition file. + * @param[in,out] provider - Pointer to the Qos Provider structure. + * @param[in] key - String that contains pattern of interested qos from `path` in format '::::'. + * + * @return a DDS return code + */ +DDS_EXPORT dds_return_t +dds_create_qos_provider_scope (const char *path, dds_qos_provider_t **provider, + const char *key); + +/** + * @brief Get Qos from Qos Provider. + * @ingroup qos_provider + * @component qos_provider_api + * + * Provide access to dds_qos_t from dds_qos_provider by full key and type of qos entity. + * + * @param[in] provider - Pointer to the Qos Provider structure. + * @param[in] type - Type of entity which Qos to get. + * @param[in] key - Full qualify name of Qos to get in format '::::'. + * @param[in,out] qos - Pointer to the Qos structure. + * + * @return a DDS return code + */ +DDS_EXPORT dds_return_t +dds_qos_provider_get_qos (const dds_qos_provider_t *provider, dds_qos_kind_t type, + const char *key, const dds_qos_t **qos); + +/** + * @brief Finalize Qos Provider. + * @ingroup qos_provider + * @component qos_provider_api + * + * Release resources allocated by dds_qos_provider. + * + * @param[in] provider - Pointer to the Qos Provider structure. + */ +DDS_EXPORT void +dds_delete_qos_provider (dds_qos_provider_t *provider); + +#endif /* DDS_HAS_QOS_PROVIDER */ + +#if defined (__cplusplus) +} +#endif + +#endif // DDS_QOS_PROVIDER_H diff --git a/src/core/ddsc/src/dds__qos_provider.h b/src/core/ddsc/src/dds__qos_provider.h new file mode 100644 index 0000000000..ce60e4cef2 --- /dev/null +++ b/src/core/ddsc/src/dds__qos_provider.h @@ -0,0 +1,47 @@ +// Copyright(c) 2024 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause +#ifndef DDS__QOS_PROVIDER_H +#define DDS__QOS_PROVIDER_H + +#include "dds/dds.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define PROVIDER_ITEM_SEP "::" +#define PROVIDER_ITEM_SCOPE_NONE "*" +#define QOSPROV_ERROR(...) DDS_LOG(DDS_LC_QOSPROV | DDS_LC_ERROR, __VA_ARGS__) +#define QOSPROV_WARN(...) DDS_LOG(DDS_LC_QOSPROV | DDS_LC_WARNING, __VA_ARGS__) +#define QOSPROV_TRACE(...) DDS_LOG(DDS_LC_QOSPROV | DDS_LC_TRACE, __VA_ARGS__) + +/** + * @brief Sample structure of the Qos stored in Provider. + * @ingroup qos_provider + * @component qos_provider_api + */ +typedef struct dds_qos_item +{ + char *full_name; + dds_qos_t *qos; + enum dds_qos_kind kind; +} dds_qos_item_t; + +struct dds_qos_provider +{ + char* file_path; + struct ddsrt_hh *keyed_qos; +}; + +#if defined (__cplusplus) +} +#endif + +#endif // DDS__QOS_PROVIDER_H diff --git a/src/core/ddsc/src/dds__sysdef_model.h b/src/core/ddsc/src/dds__sysdef_model.h new file mode 100644 index 0000000000..8c673dfb0e --- /dev/null +++ b/src/core/ddsc/src/dds__sysdef_model.h @@ -0,0 +1,706 @@ +// Copyright(c) 2024 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause +#ifndef DDS__SYSDEF_MODEL_H +#define DDS__SYSDEF_MODEL_H + +#include "dds/dds.h" +#include "dds/ddsi/ddsi_xqos.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define TYPE_HASH_LENGTH 14 + +struct dds_sysdef_type_metadata { + unsigned char *type_hash; + size_t type_info_cdr_sz; + unsigned char *type_info_cdr; + size_t type_map_cdr_sz; + unsigned char *type_map_cdr; +}; + +struct dds_sysdef_type_metadata_admin { + struct ddsrt_hh *m; +}; + +struct xml_element; +struct dds_sysdef_type; +struct dds_sysdef_type_lib; +struct dds_sysdef_qos; +struct dds_sysdef_qos_profile; +struct dds_sysdef_qos_lib; +struct dds_sysdef_domain; +struct dds_sysdef_domain_lib; +struct dds_sysdef_participant; +struct dds_sysdef_participant_lib; +struct dds_sysdef_publisher; +struct dds_sysdef_subscriber; +struct dds_sysdef_application; +struct dds_sysdef_application_lib; +struct dds_sysdef_node_lib; +struct parse_sysdef_state; + +enum element_kind +{ + ELEMENT_KIND_UNDEFINED, + ELEMENT_KIND_DDS, + + ELEMENT_KIND_TYPE_LIB, + ELEMENT_KIND_TYPE, + + ELEMENT_KIND_QOS_LIB, + ELEMENT_KIND_QOS_PROFILE, + ELEMENT_KIND_QOS_PARTICIPANT, + ELEMENT_KIND_QOS_PUBLISHER, + ELEMENT_KIND_QOS_SUBSCRIBER, + ELEMENT_KIND_QOS_TOPIC, + ELEMENT_KIND_QOS_WRITER, + ELEMENT_KIND_QOS_READER, + + ELEMENT_KIND_QOS_DURATION_SEC, + ELEMENT_KIND_QOS_DURATION_NSEC, + + ELEMENT_KIND_QOS_POLICY_DEADLINE, + ELEMENT_KIND_QOS_POLICY_DEADLINE_PERIOD, + ELEMENT_KIND_QOS_POLICY_DESTINATIONORDER, + ELEMENT_KIND_QOS_POLICY_DESTINATIONORDER_KIND, + ELEMENT_KIND_QOS_POLICY_DURABILITY, + ELEMENT_KIND_QOS_POLICY_DURABILITY_KIND, + ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE, + ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_SERVICE_CLEANUP_DELAY, + ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_HISTORY_KIND, + ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_HISTORY_DEPTH, + ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_RESOURCE_LIMIT_MAX_SAMPLES, + ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_RESOURCE_LIMIT_MAX_INSTANCES, + ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_RESOURCE_LIMIT_MAX_SAMPLES_PER_INSTANCE, + ELEMENT_KIND_QOS_POLICY_ENTITYFACTORY, + ELEMENT_KIND_QOS_POLICY_ENTITYFACTORY_AUTOENABLE_CREATED_ENTITIES, + ELEMENT_KIND_QOS_POLICY_GROUPDATA, + ELEMENT_KIND_QOS_POLICY_GROUPDATA_VALUE, + ELEMENT_KIND_QOS_POLICY_HISTORY, + ELEMENT_KIND_QOS_POLICY_HISTORY_KIND, + ELEMENT_KIND_QOS_POLICY_HISTORY_DEPTH, + ELEMENT_KIND_QOS_POLICY_LATENCYBUDGET, + ELEMENT_KIND_QOS_POLICY_LATENCYBUDGET_DURATION, + ELEMENT_KIND_QOS_POLICY_LIFESPAN, + ELEMENT_KIND_QOS_POLICY_LIFESPAN_DURATION, + ELEMENT_KIND_QOS_POLICY_LIVELINESS, + ELEMENT_KIND_QOS_POLICY_LIVELINESS_KIND, + ELEMENT_KIND_QOS_POLICY_LIVELINESS_LEASE_DURATION, + ELEMENT_KIND_QOS_POLICY_OWNERSHIP, + ELEMENT_KIND_QOS_POLICY_OWNERSHIP_KIND, + ELEMENT_KIND_QOS_POLICY_OWNERSHIPSTRENGTH, + ELEMENT_KIND_QOS_POLICY_OWNERSHIPSTRENGTH_VALUE, + ELEMENT_KIND_QOS_POLICY_PARTITION, + ELEMENT_KIND_QOS_POLICY_PARTITION_NAME, + ELEMENT_KIND_QOS_POLICY_PARTITION_NAME_ELEMENT, + ELEMENT_KIND_QOS_POLICY_PRESENTATION, + ELEMENT_KIND_QOS_POLICY_PRESENTATION_ACCESS_SCOPE, + ELEMENT_KIND_QOS_POLICY_PRESENTATION_COHERENT_ACCESS, + ELEMENT_KIND_QOS_POLICY_PRESENTATION_ORDERED_ACCESS, + ELEMENT_KIND_QOS_POLICY_READERDATALIFECYCLE, + ELEMENT_KIND_QOS_POLICY_READERDATALIFECYCLE_AUTOPURGE_NOWRITER_SAMPLES_DELAY, + ELEMENT_KIND_QOS_POLICY_READERDATALIFECYCLE_AUTOPURGE_DISPOSED_SAMPLES_DELAY, + ELEMENT_KIND_QOS_POLICY_RELIABILITY, + ELEMENT_KIND_QOS_POLICY_RELIABILITY_KIND, + ELEMENT_KIND_QOS_POLICY_RELIABILITY_MAX_BLOCKING_DELAY, + ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS, + ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_INITIAL_INSTANCES, + ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_INITIAL_SAMPLES, + ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_MAX_SAMPLES, + ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_MAX_INSTANCES, + ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_MAX_SAMPLES_PER_INSTANCE, + ELEMENT_KIND_QOS_POLICY_TIMEBASEDFILTER, + ELEMENT_KIND_QOS_POLICY_TIMEBASEDFILTER_MINIMUM_SEPARATION, + ELEMENT_KIND_QOS_POLICY_TOPICDATA, + ELEMENT_KIND_QOS_POLICY_TOPICDATA_VALUE, + ELEMENT_KIND_QOS_POLICY_TRANSPORTPRIORITY, + ELEMENT_KIND_QOS_POLICY_TRANSPORTPRIORITY_VALUE, + ELEMENT_KIND_QOS_POLICY_USERDATA, + ELEMENT_KIND_QOS_POLICY_USERDATA_VALUE, + ELEMENT_KIND_QOS_POLICY_WRITERDATALIFECYCLE, + ELEMENT_KIND_QOS_POLICY_WRITERDATALIFECYCLE_AUTODISPOSE_UNREGISTERED_INSTANCES, + + ELEMENT_KIND_DOMAIN_LIB, + ELEMENT_KIND_DOMAIN, + ELEMENT_KIND_REGISTER_TYPE, + ELEMENT_KIND_TOPIC, + + ELEMENT_KIND_PARTICIPANT_LIB, + ELEMENT_KIND_PARTICIPANT, + ELEMENT_KIND_PUBLISHER, + ELEMENT_KIND_SUBSCRIBER, + ELEMENT_KIND_WRITER, + ELEMENT_KIND_READER, + + ELEMENT_KIND_APPLICATION_LIB, + ELEMENT_KIND_APPLICATION, + + ELEMENT_KIND_NODE_LIB, + ELEMENT_KIND_NODE, + ELEMENT_KIND_NODE_HOSTNAME, + ELEMENT_KIND_NODE_IPV4_ADDRESS, + ELEMENT_KIND_NODE_IPV6_ADDRESS, + ELEMENT_KIND_NODE_MAC_ADDRESS, + + ELEMENT_KIND_DEPLOYMENT_LIB, + ELEMENT_KIND_DEPLOYMENT, + ELEMENT_KIND_DEPLOYMENT_NODE_REF, + ELEMENT_KIND_DEPLOYMENT_APPLICATION_LIST, + ELEMENT_KIND_DEPLOYMENT_APPLICATION_REF, + ELEMENT_KIND_DEPLOYMENT_CONF, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_SOURCE_IP_ADDRESS, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_DESTINATION_IP_ADDRESS, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_DSCP, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_PROTOCOL, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_SOURCE_PORT, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_DESTINATION_PORT, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_SOURCE_IP_ADDRESS, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_DESTINATION_IP_ADDRESS, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_DSCP, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_PROTOCOL, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_SOURCE_PORT, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_DESTINATION_PORT, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_PERIODICITY, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_SAMPLES_PER_PERIOD, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_MAX_BYTES_PER_SAMPLE, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TRANSMISSION_SELECTION, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE_EARLIEST_TRANSMIT_OFFSET, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE_LATEST_TRANSMIT_OFFSET, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE_JITTER, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_NETWORK_REQUIREMENTS, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_NETWORK_REQUIREMENTS_NUM_SEAMLESS_TREES, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_NETWORK_REQUIREMENTS_MAX_LATENCY, + + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER_NETWORK_REQUIREMENTS, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER_NETWORK_REQUIREMENTS_NUM_SEAMLESS_TREES, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER_NETWORK_REQUIREMENTS_MAX_LATENCY +}; + +enum element_data_type { + ELEMENT_DATA_TYPE_GENERIC, + ELEMENT_DATA_TYPE_DURATION +}; + +typedef int (* init_fn) (struct parse_sysdef_state * const pstate, struct xml_element *element); +typedef void (* fini_fn) (struct xml_element *element); + +struct xml_element +{ + struct xml_element *parent; + enum element_kind kind; + enum element_data_type data_type; + bool retain; + bool handle_close; + struct xml_element *next; + fini_fn fini; +}; + +/* Type library */ +struct dds_sysdef_type { + struct xml_element xmlnode; + char *name; + unsigned char *identifier; + struct dds_sysdef_type_lib *parent; +}; + +struct dds_sysdef_type_lib { + struct xml_element xmlnode; + struct dds_sysdef_type *types; +}; + +/* QoS library */ +enum dds_sysdef_qos_kind { + DDS_SYSDEF_TOPIC_QOS, + DDS_SYSDEF_READER_QOS, + DDS_SYSDEF_WRITER_QOS, + DDS_SYSDEF_SUBSCRIBER_QOS, + DDS_SYSDEF_PUBLISHER_QOS, + DDS_SYSDEF_PARTICIPANT_QOS +}; + +#define QOS_POLICY_SYSDEF_STRUCT(p,t) \ + struct dds_sysdef_ ## p { \ + struct xml_element xmlnode; \ + t values; \ + uint32_t populated; \ + }; + +#define QOS_POLICY_DEADLINE_PARAM_PERIOD (1 << 0u) +#define QOS_POLICY_DEADLINE_PARAMS (QOS_POLICY_DEADLINE_PARAM_PERIOD) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_DEADLINE, dds_deadline_qospolicy_t) + +#define QOS_POLICY_DESTINATIONORDER_PARAM_KIND (1 << 0u) +#define QOS_POLICY_DESTINATIONORDER_PARAMS (QOS_POLICY_DESTINATIONORDER_PARAM_KIND) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_DESTINATIONORDER, dds_destination_order_qospolicy_t) + +#define QOS_POLICY_DURABILITY_PARAM_KIND (1 << 0u) +#define QOS_POLICY_DURABILITY_PARAMS (QOS_POLICY_DURABILITY_PARAM_KIND) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_DURABILITY, dds_durability_qospolicy_t) + +#define QOS_POLICY_DURABILITYSERVICE_PARAM_SERVICE_CLEANUP_DELAY (1 << 0u) +#define QOS_POLICY_DURABILITYSERVICE_PARAM_HISTORY_KIND (1 << 1u) +#define QOS_POLICY_DURABILITYSERVICE_PARAM_HISTORY_DEPTH (1 << 2u) +#define QOS_POLICY_DURABILITYSERVICE_PARAM_RESOURCE_LIMIT_MAX_SAMPLES (1 << 3u) +#define QOS_POLICY_DURABILITYSERVICE_PARAM_RESOURCE_LIMIT_MAX_INSTANCES (1 << 4u) +#define QOS_POLICY_DURABILITYSERVICE_PARAM_RESOURCE_LIMIT_MAX_SAMPLES_PER_INSTANCE (1 << 5u) +#define QOS_POLICY_DURABILITYSERVICE_PARAMS (\ + QOS_POLICY_DURABILITYSERVICE_PARAM_SERVICE_CLEANUP_DELAY \ + | QOS_POLICY_DURABILITYSERVICE_PARAM_HISTORY_KIND \ + | QOS_POLICY_DURABILITYSERVICE_PARAM_HISTORY_DEPTH \ + | QOS_POLICY_DURABILITYSERVICE_PARAM_RESOURCE_LIMIT_MAX_SAMPLES \ + | QOS_POLICY_DURABILITYSERVICE_PARAM_RESOURCE_LIMIT_MAX_INSTANCES \ + | QOS_POLICY_DURABILITYSERVICE_PARAM_RESOURCE_LIMIT_MAX_SAMPLES_PER_INSTANCE) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_DURABILITYSERVICE, dds_durability_service_qospolicy_t) + +#define QOS_POLICY_ENTITYFACTORY_PARAM_AUTOENABLE_CREATED_ENTITIES (1 << 0u) +#define QOS_POLICY_ENTITYFACTORY_PARAMS (QOS_POLICY_ENTITYFACTORY_PARAM_AUTOENABLE_CREATED_ENTITIES) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_ENTITYFACTORY, dds_entity_factory_qospolicy_t) + +#define QOS_POLICY_HISTORY_PARAM_KIND (1 << 0u) +#define QOS_POLICY_HISTORY_PARAM_DEPTH (1 << 1u) +#define QOS_POLICY_HISTORY_PARAMS (QOS_POLICY_HISTORY_PARAM_KIND | QOS_POLICY_HISTORY_PARAM_DEPTH) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_HISTORY, dds_history_qospolicy_t) + +#define QOS_POLICY_LATENCYBUDGET_PARAM_DURATION (1 << 0u) +#define QOS_POLICY_LATENCYBUDGET_PARAMS (QOS_POLICY_LATENCYBUDGET_PARAM_DURATION) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_LATENCYBUDGET, dds_latency_budget_qospolicy_t) + +#define QOS_POLICY_LIFESPAN_PARAM_DURATION (1 << 0u) +#define QOS_POLICY_LIFESPAN_PARAMS (QOS_POLICY_LIFESPAN_PARAM_DURATION) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_LIFESPAN, dds_lifespan_qospolicy_t) + +#define QOS_POLICY_LIVELINESS_PARAM_KIND (1 << 0u) +#define QOS_POLICY_LIVELINESS_PARAM_LEASE_DURATION (1 << 1u) +#define QOS_POLICY_LIVELINESS_PARAMS (QOS_POLICY_LIVELINESS_PARAM_KIND | QOS_POLICY_LIVELINESS_PARAM_LEASE_DURATION) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_LIVELINESS, dds_liveliness_qospolicy_t) + +#define QOS_POLICY_OWNERSHIP_PARAM_KIND (1 << 0u) +#define QOS_POLICY_OWNERSHIP_PARAMS (QOS_POLICY_OWNERSHIP_PARAM_KIND) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_OWNERSHIP, dds_ownership_qospolicy_t) + +#define QOS_POLICY_OWNERSHIPSTRENGTH_PARAM_VALUE (1 << 0u) +#define QOS_POLICY_OWNERSHIPSTRENGTH_PARAMS (QOS_POLICY_OWNERSHIPSTRENGTH_PARAM_VALUE) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_OWNERSHIPSTRENGTH, dds_ownership_strength_qospolicy_t) + +#define QOS_POLICY_PARTITION_PARAM_NAME (1 << 0u) +#define QOS_POLICY_PARTITION_PARAMS (QOS_POLICY_PARTITION_PARAM_NAME) +struct dds_sysdef_QOS_POLICY_PARTITION_NAME_ELEMENT { + struct xml_element xmlnode; + char *element; +}; + +struct dds_sysdef_QOS_POLICY_PARTITION_NAME { + struct xml_element xmlnode; + struct dds_sysdef_QOS_POLICY_PARTITION_NAME_ELEMENT *elements; +}; + +struct dds_sysdef_QOS_POLICY_PARTITION { + struct xml_element xmlnode; + struct dds_sysdef_QOS_POLICY_PARTITION_NAME *name; + uint32_t populated; +}; + +#define QOS_POLICY_PRESENTATION_PARAM_ACCESS_SCOPE (1 << 0u) +#define QOS_POLICY_PRESENTATION_PARAM_COHERENT_ACCESS (1 << 1u) +#define QOS_POLICY_PRESENTATION_PARAM_ORDERED_ACCESS (1 << 2u) +#define QOS_POLICY_PRESENTATION_PARAMS (QOS_POLICY_PRESENTATION_PARAM_ACCESS_SCOPE | QOS_POLICY_PRESENTATION_PARAM_COHERENT_ACCESS | QOS_POLICY_PRESENTATION_PARAM_ORDERED_ACCESS) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_PRESENTATION, dds_presentation_qospolicy_t) + +#define QOS_POLICY_READERDATALIFECYCLE_PARAM_AUTOPURGE_NOWRITER_SAMPLES_DELAY (1 << 0u) +#define QOS_POLICY_READERDATALIFECYCLE_PARAM_AUTOPURGE_DISPOSED_SAMPLES_DELAY (1 << 1u) +#define QOS_POLICY_READERDATALIFECYCLE_PARAMS (QOS_POLICY_READERDATALIFECYCLE_PARAM_AUTOPURGE_NOWRITER_SAMPLES_DELAY | QOS_POLICY_READERDATALIFECYCLE_PARAM_AUTOPURGE_DISPOSED_SAMPLES_DELAY) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_READERDATALIFECYCLE, dds_reader_data_lifecycle_qospolicy_t) + +#define QOS_POLICY_RELIABILITY_PARAM_KIND (1 << 0u) +#define QOS_POLICY_RELIABILITY_PARAM_MAX_BLOCKING_DELAY (1 << 1u) +#define QOS_POLICY_RELIABILITY_PARAMS (QOS_POLICY_RELIABILITY_PARAM_KIND | QOS_POLICY_RELIABILITY_PARAM_MAX_BLOCKING_DELAY) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_RELIABILITY, dds_reliability_qospolicy_t) + +#define QOS_POLICY_RESOURCELIMITS_PARAM_MAX_SAMPLES (1 << 0u) +#define QOS_POLICY_RESOURCELIMITS_PARAM_MAX_INSTANCES (1 << 1u) +#define QOS_POLICY_RESOURCELIMITS_PARAM_MAX_SAMPLES_PER_INSTANCE (1 << 2u) +#define QOS_POLICY_RESOURCELIMITS_PARAMS (QOS_POLICY_RESOURCELIMITS_PARAM_MAX_SAMPLES | QOS_POLICY_RESOURCELIMITS_PARAM_MAX_INSTANCES | QOS_POLICY_RESOURCELIMITS_PARAM_MAX_SAMPLES_PER_INSTANCE) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_RESOURCELIMITS, dds_resource_limits_qospolicy_t) + +#define QOS_POLICY_TIMEBASEDFILTER_PARAM_MINIMUM_SEPARATION (1 << 0u) +#define QOS_POLICY_TIMEBASEDFILTER_PARAMS (QOS_POLICY_TIMEBASEDFILTER_PARAM_MINIMUM_SEPARATION) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_TIMEBASEDFILTER, dds_time_based_filter_qospolicy_t) + +#define QOS_POLICY_TRANSPORTPRIORITY_PARAM_VALUE (1 << 0u) +#define QOS_POLICY_TRANSPORTPRIORITY_PARAMS (QOS_POLICY_TRANSPORTPRIORITY_PARAM_VALUE) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_TRANSPORTPRIORITY, dds_transport_priority_qospolicy_t) + +#define QOS_POLICY_WRITERDATALIFECYCLE_PARAM_AUTODISPOSE_UNREGISTERED_INSTANCES (1 << 0u) +#define QOS_POLICY_WRITERDATALIFECYCLE_PARAMS (QOS_POLICY_WRITERDATALIFECYCLE_PARAM_AUTODISPOSE_UNREGISTERED_INSTANCES) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_WRITERDATALIFECYCLE, dds_writer_data_lifecycle_qospolicy_t) + +#define QOS_POLICY_GROUPDATA_PARAM_VALUE (1 << 0u) +#define QOS_POLICY_GROUPDATA_PARAMS (QOS_POLICY_GROUPDATA_PARAM_VALUE) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_GROUPDATA, dds_groupdata_qospolicy_t) + +#define QOS_POLICY_TOPICDATA_PARAM_VALUE (1 << 0u) +#define QOS_POLICY_TOPICDATA_PARAMS (QOS_POLICY_TOPICDATA_PARAM_VALUE) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_TOPICDATA, dds_topicdata_qospolicy_t) + +#define QOS_POLICY_USERDATA_PARAM_VALUE (1 << 0u) +#define QOS_POLICY_USERDATA_PARAMS (QOS_POLICY_USERDATA_PARAM_VALUE) +QOS_POLICY_SYSDEF_STRUCT (QOS_POLICY_USERDATA, dds_userdata_qospolicy_t) + +struct dds_sysdef_qos_generic_property { + struct xml_element xmlnode; +}; + +#define QOS_LENGTH_UNLIMITED "LENGTH_UNLIMITED" +#define QOS_DURATION_INFINITY "DURATION_INFINITY" +#define QOS_DURATION_INFINITY_SEC "DURATION_INFINITE_SEC" +#define QOS_DURATION_INFINITY_NSEC "DURATION_INFINITE_NSEC" + +#define QOS_DURATION_PARAM_SEC (1 << 0u) +#define QOS_DURATION_PARAM_NSEC (1 << 1u) +struct dds_sysdef_qos_duration_property { + struct xml_element xmlnode; + dds_duration_t sec; + dds_duration_t nsec; + uint32_t populated; +}; + +struct dds_sysdef_qos { + struct xml_element xmlnode; + enum dds_sysdef_qos_kind kind; + dds_qos_t *qos; + char *name; + struct dds_sysdef_qos_profile *base_profile; +}; + +struct dds_sysdef_qos_profile { + struct xml_element xmlnode; + char *name; + struct dds_sysdef_qos *qos; + struct dds_sysdef_qos_profile *base_profile; +}; + +struct dds_sysdef_qos_lib { + struct xml_element xmlnode; + char *name; + struct dds_sysdef_qos_profile *qos_profiles; +}; + +/* Domain library */ +struct dds_sysdef_topic { + struct xml_element xmlnode; + char *name; + // TODO: registered_name? + struct dds_sysdef_qos *qos; + struct dds_sysdef_register_type *register_type_ref; +}; + +enum dds_sysdef_register_type_parent_kind { + DDS_SYSDEF_TYPEREG_PARENT_KIND_DOMAIN, + DDS_SYSDEF_TYPEREG_PARENT_KIND_PARTICIPANT +}; + +struct dds_sysdef_register_type { + struct xml_element xmlnode; + char *name; + struct dds_sysdef_type *type_ref; + enum dds_sysdef_register_type_parent_kind parent_kind; +}; + +#define SYSDEF_DOMAIN_DOMAIN_ID_PARAM_VALUE (1 << 0u) +#define SYSDEF_DOMAIN_PARTICIPANT_INDEX_PARAM_VALUE (1 << 1u) +#define SYSDEF_DOMAIN_PARAMS (SYSDEF_DOMAIN_DOMAIN_ID_PARAM_VALUE) +struct dds_sysdef_domain { + struct xml_element xmlnode; + uint32_t domain_id; + char *name; + int32_t participant_index; + struct dds_sysdef_register_type *register_types; + struct dds_sysdef_topic *topics; + uint32_t populated; +}; + +struct dds_sysdef_domain_lib { + struct xml_element xmlnode; + char *name; + struct dds_sysdef_domain *domains; +}; + +/* Participant library */ +struct dds_sysdef_endpoint { + struct xml_element xmlnode; + char *name; + uint32_t entity_key; +}; + +#define SYSDEF_WRITER_ENTITY_KEY_PARAM_VALUE (1 << 0u) +#define SYSDEF_WRITER_PARAMS (SYSDEF_WRITER_ENTITY_KEY_PARAM_VALUE) +struct dds_sysdef_writer { + struct xml_element xmlnode; + char *name; + uint32_t entity_key; + struct dds_sysdef_topic *topic; + struct dds_sysdef_qos *qos; + uint32_t populated; +}; +DDSRT_STATIC_ASSERT (offsetof (struct dds_sysdef_writer, xmlnode) == offsetof (struct dds_sysdef_endpoint, xmlnode)); +DDSRT_STATIC_ASSERT (offsetof (struct dds_sysdef_writer, name) == offsetof (struct dds_sysdef_endpoint, name)); +DDSRT_STATIC_ASSERT (offsetof (struct dds_sysdef_writer, entity_key) == offsetof (struct dds_sysdef_endpoint, entity_key)); + +#define SYSDEF_READER_ENTITY_KEY_PARAM_VALUE (1 << 0u) +#define SYSDEF_READER_PARAMS (SYSDEF_READER_ENTITY_KEY_PARAM_VALUE) +struct dds_sysdef_reader { + struct xml_element xmlnode; + char *name; + uint32_t entity_key; + struct dds_sysdef_topic *topic; + struct dds_sysdef_qos *qos; + uint32_t populated; +}; +DDSRT_STATIC_ASSERT (offsetof (struct dds_sysdef_reader, xmlnode) == offsetof (struct dds_sysdef_endpoint, xmlnode)); +DDSRT_STATIC_ASSERT (offsetof (struct dds_sysdef_reader, name) == offsetof (struct dds_sysdef_endpoint, name)); +DDSRT_STATIC_ASSERT (offsetof (struct dds_sysdef_reader, entity_key) == offsetof (struct dds_sysdef_endpoint, entity_key)); + +struct dds_sysdef_publisher { + struct xml_element xmlnode; + char *name; + struct dds_sysdef_qos *qos; + struct dds_sysdef_writer *writers; +}; + +struct dds_sysdef_subscriber { + struct xml_element xmlnode; + char *name; + struct dds_sysdef_qos *qos; + struct dds_sysdef_reader *readers; +}; + +enum dds_sysdef_participant_parent_kind { + DDS_SYSDEF_PARTICIPANT_PARENT_KIND_APPLICATION, + DDS_SYSDEF_PARTICIPANT_PARENT_KIND_PARTICIPANTLIB +}; + +struct dds_sysdef_participant_guid_prefix { + uint32_t p; +}; + +struct dds_sysdef_participant { + struct xml_element xmlnode; + char *name; + struct dds_sysdef_qos *qos; + struct dds_sysdef_domain *domain_ref; + struct dds_sysdef_participant *base; + struct dds_sysdef_participant_guid_prefix *guid_prefix; + + struct dds_sysdef_register_type *register_types; + struct dds_sysdef_topic *topics; + struct dds_sysdef_publisher *publishers; + struct dds_sysdef_subscriber *subscribers; + + enum dds_sysdef_participant_parent_kind parent_kind; + uint32_t populated; +}; + +struct dds_sysdef_participant_lib { + struct xml_element xmlnode; + char *name; + struct dds_sysdef_participant *participants; +}; + +/* Application library */ +struct dds_sysdef_application { + struct xml_element xmlnode; + char *name; + struct dds_sysdef_participant *participants; +}; + +struct dds_sysdef_application_lib { + struct xml_element xmlnode; + char *name; + struct dds_sysdef_application *applications; +}; + +/* Node library */ +struct dds_sysdef_mac_addr { + uint8_t addr[6]; +}; +struct dds_sysdef_ip_addr { + struct sockaddr_storage addr; +}; +struct dds_sysdef_node { + struct xml_element xmlnode; + char *name; + char *hostname; + struct dds_sysdef_ip_addr *ipv4_addr; + struct dds_sysdef_ip_addr *ipv6_addr; + struct dds_sysdef_mac_addr *mac_addr; +}; + +struct dds_sysdef_node_lib { + struct xml_element xmlnode; + char *name; + struct dds_sysdef_node *nodes; +}; + +/* Deployment library */ +#define SYSDEF_TSN_TIME_AWARE_EARLIEST_TRANSMIT_OFFSET_PARAM_VALUE (1 << 0u) +#define SYSDEF_TSN_TIME_AWARE_LATEST_TRANSMIT_OFFSET_PARAM_VALUE (1 << 1u) +#define SYSDEF_TSN_TIME_JITTER_PARAM_VALUE (1 << 2u) +struct dds_sysdef_tsn_time_aware { + struct xml_element xmlnode; + uint32_t earliest_transmit_offset; + uint32_t latest_transmit_offset; + uint32_t jitter; + uint32_t populated; +}; + +enum dds_sysdef_tsn_traffic_transmission_selection { + DDS_SYSDEF_TSN_TRAFFIC_TRANSMISSION_STRICT_PRIORITY, + DDS_SYSDEF_TSN_TRAFFIC_TRANSMISSION_CREDIT_BASED_SHAPER, + DDS_SYSDEF_TSN_TRAFFIC_TRANSMISSION_ENHANCED_TRANSMISSION_SELECTION, + DDS_SYSDEF_TSN_TRAFFIC_TRANSMISSION_ATS_TRANSMISSION_SELECTION +}; + +#define SYSDEF_TSN_TRAFFIC_SPEC_SAMPLES_PER_PERIOD_PARAM_VALUE (1 << 0u) +#define SYSDEF_TSN_TRAFFIC_SPEC_MAX_BYTES_PER_SAMPLE_PARAM_VALUE (1 << 1u) +#define SYSDEF_TSN_TRAFFIC_SPEC_TRANSMISSION_SELECTION_PARAM_VALUE (1 << 2u) +struct dds_sysdef_tsn_traffic_specification { + struct xml_element xmlnode; + dds_duration_t periodicity; + uint16_t samples_per_period; + uint16_t max_bytes_per_sample; + enum dds_sysdef_tsn_traffic_transmission_selection transmission_selection; + struct dds_sysdef_tsn_time_aware *time_aware; + uint32_t populated; +}; + +#define SYSDEF_TSN_NETWORK_REQ_NUM_SEAMLESS_TREES_PARAM_VALUE (1 << 0u) +#define SYSDEF_TSN_NETWORK_REQ_MAX_LATENCY_PARAM_VALUE (1 << 1u) +struct dds_sysdef_tsn_network_requirements { + struct xml_element xmlnode; + uint8_t num_seamless_trees; + uint32_t max_latency; + uint32_t populated; +}; + +struct dds_sysdef_tsn_ieee802_mac_addresses { + struct xml_element xmlnode; + char *destination_mac_address; + char *source_mac_address; +}; + +struct dds_sysdef_tsn_ieee802_vlan_tag { + struct xml_element xmlnode; + uint8_t priority_code_point; + uint16_t vlan_id; + uint32_t populated; +}; + +#define SYSDEF_TSN_IP_TUPLE_DSCP_PARAM_VALUE (1 << 0u) +#define SYSDEF_TSN_IP_TUPLE_PROTOCOL_PARAM_VALUE (1 << 1u) +#define SYSDEF_TSN_IP_TUPLE_SOURCE_PORT_PARAM_VALUE (1 << 2u) +#define SYSDEF_TSN_IP_TUPLE_DESTINATION_PORT_PARAM_VALUE (1 << 3u) +struct dds_sysdef_tsn_ip_tuple { + struct xml_element xmlnode; + char *source_ip_address; + char *destination_ip_address; + uint8_t dscp; + uint16_t protocol; + uint16_t source_port; + uint16_t destination_port; + uint32_t populated; +}; + +struct dds_sysdef_tsn_data_frame_specification { + struct xml_element xmlnode; + struct dds_sysdef_tsn_ieee802_mac_addresses *mac_addresses; + struct dds_sysdef_tsn_ieee802_vlan_tag *vlan_tag; + struct dds_sysdef_tsn_ip_tuple *ipv4_tuple; + struct dds_sysdef_tsn_ip_tuple *ipv6_tuple; +}; + +struct dds_sysdef_tsn_talker_configuration { + struct xml_element xmlnode; + char *name; + char *stream_name; + struct dds_sysdef_writer *writer; + struct dds_sysdef_tsn_traffic_specification *traffic_specification; + struct dds_sysdef_tsn_network_requirements *network_requirements; + struct dds_sysdef_tsn_data_frame_specification *data_frame_specification; +}; + +struct dds_sysdef_tsn_listener_configuration { + struct xml_element xmlnode; + char *name; + char *stream_name; + struct dds_sysdef_reader *reader; + struct dds_sysdef_tsn_network_requirements *network_requirements; +}; + +struct dds_sysdef_tsn_configuration { + struct xml_element xmlnode; + struct dds_sysdef_tsn_talker_configuration *tsn_talker_configurations; + struct dds_sysdef_tsn_listener_configuration *tsn_listener_configurations; +}; + +struct dds_sysdef_configuration { + struct xml_element xmlnode; + struct dds_sysdef_tsn_configuration *tsn_configuration; +}; + +struct dds_sysdef_application_ref { + struct xml_element xmlnode; + struct dds_sysdef_application *application; +}; + +struct dds_sysdef_application_list { + struct xml_element xmlnode; + struct dds_sysdef_application_ref *application_refs; +}; + +struct dds_sysdef_deployment { + struct xml_element xmlnode; + char *name; + struct dds_sysdef_node *node; + struct dds_sysdef_application_list *application_list; + struct dds_sysdef_configuration *configuration; +}; + +struct dds_sysdef_deployment_lib { + struct xml_element xmlnode; + char *name; + struct dds_sysdef_deployment *deployments; +}; + +struct dds_sysdef_system { + struct xml_element xmlnode; + struct dds_sysdef_type_lib *type_libs; + struct dds_sysdef_qos_lib *qos_libs; + struct dds_sysdef_domain_lib *domain_libs; + struct dds_sysdef_participant_lib *participant_libs; + struct dds_sysdef_application_lib *application_libs; + struct dds_sysdef_node_lib *node_libs; + struct dds_sysdef_deployment_lib *deployment_libs; +}; + +#if defined (__cplusplus) +} +#endif + +#endif // DDS__SYSDEF_MODEL_H diff --git a/src/core/ddsc/src/dds__sysdef_parser.h b/src/core/ddsc/src/dds__sysdef_parser.h new file mode 100644 index 0000000000..f999767e85 --- /dev/null +++ b/src/core/ddsc/src/dds__sysdef_parser.h @@ -0,0 +1,145 @@ +// Copyright(c) 2024 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause +#ifndef DDS_SYSDEF_PARSER_H +#define DDS_SYSDEF_PARSER_H + +#include "dds/dds.h" +#include "dds/ddsrt/log.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define SYSDEF_SCOPE_TYPE_LIB (1u << 0u) +#define SYSDEF_SCOPE_QOS_LIB (1u << 1u) +#define SYSDEF_SCOPE_DOMAIN_LIB (1u << 2u) +#define SYSDEF_SCOPE_PARTICIPANT_LIB (1u << 3u) +#define SYSDEF_SCOPE_APPLICATION_LIB (1u << 4u) +#define SYSDEF_SCOPE_NODE_LIB (1u << 5u) +#define SYSDEF_SCOPE_DEPLOYMENT_LIB (1u << 6u) + +#define SYSDEF_SCOPE_ALL_LIB ( \ + SYSDEF_SCOPE_TYPE_LIB |\ + SYSDEF_SCOPE_QOS_LIB |\ + SYSDEF_SCOPE_DOMAIN_LIB |\ + SYSDEF_SCOPE_PARTICIPANT_LIB |\ + SYSDEF_SCOPE_APPLICATION_LIB |\ + SYSDEF_SCOPE_NODE_LIB |\ + SYSDEF_SCOPE_DEPLOYMENT_LIB \ +) + +#define SYSDEF_RET_OK 0 +#define SYSDEF_RET_FAILURE 1 + +#define SD_PARSE_RESULT_OK 0 +#define SD_PARSE_RESULT_ERR -1 +#define SD_PARSE_RESULT_SYNTAX_ERR -2 +#define SD_PARSE_RESULT_OUT_OF_RESOURCES -3 +#define SD_PARSE_RESULT_NOT_SUPPORTED -4 +#define SD_PARSE_RESULT_INVALID_REF -5 +#define SD_PARSE_RESULT_DUPLICATE -6 + +/** + * @defgroup sysdef_parser (SysdefParser) + */ + +#define SYSDEF_TRACE(...) DDS_LOG(DDS_LC_SYSDEF | DDS_LC_TRACE, __VA_ARGS__) +#define SYSDEF_ERROR(...) DDS_LOG(DDS_LC_SYSDEF | DDS_LC_ERROR, __VA_ARGS__) + +/** + * @brief Sample structure of System definition. + * @ingroup sysdef_parser + * @componen sysdef_parser_api + */ +struct dds_sysdef_system; +/** + * @brief Sample structure of System definition for data types. + * @ingroup sysdef_parser + * @componen sysdef_parser_api + */ +struct dds_sysdef_type_metadata_admin; + +/** + * @defgroup sysdef_parser (SysdefParser) + */ + +/** +* @brief Initialize System definition from file. +* @ingroup dds_sysdef +* @component dds_sysdef_api +* +* Create dds_sysdef_system with provided system definition. +* +* @param[in] fp - Pointer to system definition file. +* @param[in,out] sysdef - Pointer dds_sysdef_system structure. +* @param[in] lib_scope - Library initialization mask. +* +* @return a DDS return code +*/ +dds_return_t dds_sysdef_init_sysdef (FILE *fp, struct dds_sysdef_system **sysdef, uint32_t lib_scope); + +/** +* @brief Initialize System definition from `xml` string. +* @ingroup dds_sysdef +* @component dds_sysdef_api +* +* Create dds_sysdef_system with provided system definition. +* +* @param[in] raw - System definition string. +* @param[in,out] sysdef - Pointer dds_sysdef_system structure. +* @param[in] lib_scope - Library initialization mask. +* +* @return a DDS return code +*/ +dds_return_t dds_sysdef_init_sysdef_str (const char *raw, struct dds_sysdef_system **sysdef, uint32_t lib_scope); + +/** +* @brief Finalize System definition. +* @ingroup dds_sysdef +* @component dds_sysdef_api +* +* Release resources allocated by dds_sysdef_system. +* +* @param[in] sysdef - Pointer to dds_sysdef_system structure. +* +*/ +void dds_sysdef_fini_sysdef (struct dds_sysdef_system *sysdef); + +/** +* @brief Initialize System definition for data types. +* @ingroup dds_sysdef +* @component dds_sysdef_api +* +* Create dds_sysdef_type_metadata_admin with provided system definition. +* +* @param[in] fp - Pointer to system definition file. +* @param[in,out] type_meta_data - Pointer dds_sysdef_type_metadata_admin structure. +* +* @return a DDS return code +*/ +dds_return_t dds_sysdef_init_data_types (FILE *fp, struct dds_sysdef_type_metadata_admin **type_meta_data); + +/** +* @brief Finalize System definition for data types. +* @ingroup dds_sysdef +* @component dds_sysdef_api +* +* Release resources allocated by dds_sysdef_system. +* +* @param[in,out] type_meta_data - Pointer dds_sysdef_type_metadata_admin structure. +* +*/ +void dds_sysdef_fini_data_types (struct dds_sysdef_type_metadata_admin *type_meta_data); + +#if defined (__cplusplus) +} +#endif + +#endif // DDS_SYSDEF_PARSER_H diff --git a/src/core/ddsc/src/dds__sysdef_validation.h b/src/core/ddsc/src/dds__sysdef_validation.h new file mode 100644 index 0000000000..341b19b537 --- /dev/null +++ b/src/core/ddsc/src/dds__sysdef_validation.h @@ -0,0 +1,26 @@ +// Copyright(c) 2024 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause +#ifndef DDS__SYSDEF_VALIDATION_H +#define DDS__SYSDEF_VALIDATION_H + +#if defined (__cplusplus) +extern "C" { +#endif + +#include "dds/dds.h" +#include "dds__sysdef_model.h" + +dds_return_t dds_validate_qos_lib ( + const struct dds_sysdef_system *sysdef, uint64_t qos_mask); + +#if defined (__cplusplus) +} +#endif +#endif // DDS__SYSDEF_VALIDATION_H diff --git a/src/core/ddsc/src/dds_qos_provider.c b/src/core/ddsc/src/dds_qos_provider.c new file mode 100644 index 0000000000..6f638b4d1c --- /dev/null +++ b/src/core/ddsc/src/dds_qos_provider.c @@ -0,0 +1,292 @@ + +// Copyright(c) 2024 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause +#include "string.h" + +#include "dds/ddsrt/io.h" +#include "dds/ddsrt/string.h" +#include "dds/ddsrt/mh3.h" +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/hopscotch.h" + +#include "dds__sysdef_model.h" +#include "dds__sysdef_parser.h" +#include "dds__sysdef_validation.h" +#include "dds__qos_provider.h" +#include "dds__qos.h" + +static dds_return_t read_sysdef (const char *path, struct dds_sysdef_system **sysdef) +{ + dds_return_t ret = DDS_RETCODE_BAD_PARAMETER; + if (path == NULL) + return ret; + if (path[0] == '<') + { + ret = dds_sysdef_init_sysdef_str(path, sysdef, SYSDEF_SCOPE_QOS_LIB); + } else { + FILE *fp; + DDSRT_WARNING_MSVC_OFF(4996) + if ((fp = fopen (path, "r")) == NULL) + { + SYSDEF_ERROR ("Error reading system definition: can't read from path '%s'\n", path); + ret = DDS_RETCODE_BAD_PARAMETER; + } else { + ret = dds_sysdef_init_sysdef (fp, sysdef, SYSDEF_SCOPE_QOS_LIB); + (void)fclose(fp); + DDSRT_WARNING_MSVC_ON(4996) + } + } + + return ret; +} + +static uint32_t qos_item_hash_fn(const void *a) +{ + dds_qos_item_t *item = (dds_qos_item_t *)a; + uint32_t x = ddsrt_mh3(&item->kind, sizeof(item->kind), 0); + x = ddsrt_mh3(item->full_name, strlen(item->full_name), x); + return x; +} + +static bool qos_item_equals_fn(const void *a, const void *b) +{ + dds_qos_item_t *aa = (dds_qos_item_t *)a; + dds_qos_item_t *bb = (dds_qos_item_t *)b; + + return aa->kind == bb->kind && strcmp(aa->full_name, bb->full_name) == 0; +} + +static void cleanup_qos_items (void *vnode, void *varg) +{ + (void) varg; + dds_qos_item_t *d = (dds_qos_item_t *) vnode; + ddsrt_free (d->full_name); + dds_delete_qos(d->qos); + ddsrt_free(d); +} + +#define PROVIDER_ALLOWED_QOS_MASK \ + (DDS_TOPIC_QOS_MASK | DDS_READER_QOS_MASK | DDS_WRITER_QOS_MASK | \ + DDS_SUBSCRIBER_QOS_MASK | DDS_PUBLISHER_QOS_MASK | DDS_PARTICIPANT_QOS_MASK) ^ \ + (DDSI_QP_ENTITY_NAME | DDSI_QP_ADLINK_ENTITY_FACTORY | \ + DDSI_QP_CYCLONE_IGNORELOCAL | DDSI_QP_PSMX) +static dds_return_t read_validate_sysdef(const char *path, struct dds_sysdef_system **sysdef) +{ + dds_return_t ret = DDS_RETCODE_OK; + struct dds_sysdef_system *def; + if ((ret = read_sysdef (path, &def)) != DDS_RETCODE_OK) + { + QOSPROV_ERROR("Failed during read sysdef: %s\n", path); + goto err_read; + } + if ((ret = dds_validate_qos_lib (def, PROVIDER_ALLOWED_QOS_MASK)) != DDS_RETCODE_OK) + { + QOSPROV_ERROR("Failed during validate sysdef: %s\n", path); + goto err_validate; + } + *sysdef = def; + + return ret; +err_validate: + dds_sysdef_fini_sysdef(def); +err_read: + return ret; +} +#undef PROVIDER_ALLOWED_QOS_MASK + +static dds_return_t init_qos_provider (const struct dds_sysdef_system *sysdef, const char *path, dds_qos_provider_t **provider, char *lib_scope, char *prof_scope, char *ent_scope) +{ + dds_return_t ret = DDS_RETCODE_OK; + dds_qos_provider_t *qos_provider = (dds_qos_provider_t *)ddsrt_malloc(sizeof(*qos_provider)); + struct ddsrt_hh *keyed_qos = ddsrt_hh_new(1, qos_item_hash_fn, qos_item_equals_fn); + for (const struct dds_sysdef_qos_lib *lib = sysdef->qos_libs; lib != NULL; lib = (const struct dds_sysdef_qos_lib *)lib->xmlnode.next) + { + char *lib_name = lib->name; + if (lib_scope != NULL && strcmp(lib_scope, PROVIDER_ITEM_SCOPE_NONE) != 0 && strcmp(lib_name, lib_scope) != 0) + continue; + for (const struct dds_sysdef_qos_profile *prof = lib->qos_profiles; prof != NULL; prof = (const struct dds_sysdef_qos_profile *)prof->xmlnode.next) + { + char *prof_name = prof->name; + if (prof_scope != NULL && strcmp(prof_scope, PROVIDER_ITEM_SCOPE_NONE) != 0 && strcmp(prof_name, prof_scope) != 0) + continue; + char *prefix; + (void) ddsrt_asprintf(&prefix, "%s"PROVIDER_ITEM_SEP"%s", lib_name, prof_name); + for (const struct dds_sysdef_qos *qos = prof->qos; qos != NULL; qos = (const struct dds_sysdef_qos *)qos->xmlnode.next) + { + if (ent_scope != NULL && strcmp(ent_scope, PROVIDER_ITEM_SCOPE_NONE) != 0 && (qos->name == NULL || strcmp(qos->name, ent_scope) != 0)) + continue; + dds_qos_item_t *item = ddsrt_malloc(sizeof(*item)); + dds_qos_kind_t kind; + switch(qos->kind) + { + case DDS_SYSDEF_TOPIC_QOS: + kind = DDS_TOPIC_QOS; + break; + case DDS_SYSDEF_READER_QOS: + kind = DDS_READER_QOS; + break; + case DDS_SYSDEF_WRITER_QOS: + kind = DDS_WRITER_QOS; + break; + case DDS_SYSDEF_SUBSCRIBER_QOS: + kind = DDS_SUBSCRIBER_QOS; + break; + case DDS_SYSDEF_PUBLISHER_QOS: + kind = DDS_PUBLISHER_QOS; + break; + case DDS_SYSDEF_PARTICIPANT_QOS: + kind = DDS_PARTICIPANT_QOS; + break; + default: + ddsrt_free(prefix); + ddsrt_free(item); + goto err_prov; + } + item->kind = kind; + item->qos = dds_create_qos(); + dds_merge_qos(item->qos, qos->qos); + if (qos->name != NULL) + (void) ddsrt_asprintf(&item->full_name, "%s"PROVIDER_ITEM_SEP"%s", prefix, qos->name); + else + item->full_name = ddsrt_strdup(prefix); + if (!ddsrt_hh_add(keyed_qos, item)) + { + QOSPROV_ERROR("Qos duplicate name: %s kind: %d file: %s.\n", + item->full_name, item->kind, path); + ret = DDS_RETCODE_BAD_PARAMETER; + ddsrt_free(prefix); + cleanup_qos_items(item, NULL); + goto err_prov; + } + } + ddsrt_free(prefix); + } + } + qos_provider->file_path = ddsrt_strdup(path); + qos_provider->keyed_qos = keyed_qos; + *provider = qos_provider; + + return ret; +err_prov: + ddsrt_hh_enum(keyed_qos, cleanup_qos_items, NULL); + ddsrt_hh_free(keyed_qos); + ddsrt_free(qos_provider); + return ret; +} + +dds_return_t dds_create_qos_provider (const char *path, dds_qos_provider_t **provider) +{ + dds_return_t ret = DDS_RETCODE_OK; + if ((ret = dds_create_qos_provider_scope (path, provider, PROVIDER_ITEM_SCOPE_NONE)) != DDS_RETCODE_OK) + goto err; + +err: + return ret; +} + +dds_return_t dds_qos_provider_get_qos (const dds_qos_provider_t *provider, dds_qos_kind_t type, const char *key, const dds_qos_t **qos) +{ + dds_return_t ret = DDS_RETCODE_OK; + if (provider == NULL || provider->keyed_qos == NULL) + { + QOSPROV_WARN("Failed to access provider qos\n"); + ret = DDS_RETCODE_BAD_PARAMETER; + goto err; + } + QOSPROV_TRACE("request qos for entity type: %d, scope: %s", type, key); + dds_qos_item_t it = {.full_name = ddsrt_strdup(key), .kind = type}; + dds_qos_item_t *item; + if ((item = ddsrt_hh_lookup(provider->keyed_qos, &it)) == NULL) + { + QOSPROV_WARN("Failed to get qos with name: %s, kind: %d ref file: %s\n", + it.full_name, it.kind, provider->file_path); + ret = DDS_RETCODE_BAD_PARAMETER; + goto err2; + } + *qos = item->qos; + +err2: + ddsrt_free(it.full_name); +err: + return ret; +} + +static void fill_token(char **start, char **end, char **token) +{ + char *bg = *start; + char *ed = *end; + if ((bg != NULL) && (ed = strstr(bg, PROVIDER_ITEM_SEP)) != NULL) + *token = ((ed-bg) > 0)? ddsrt_strndup(bg, (size_t)(ed-bg)): ddsrt_strdup(PROVIDER_ITEM_SCOPE_NONE); + else + *token = (bg != NULL && *bg != '\0')? ddsrt_strdup(bg): ddsrt_strdup(PROVIDER_ITEM_SCOPE_NONE); + *start = (ed != NULL)? ed + strlen(PROVIDER_ITEM_SEP): NULL; + *end = ed; +} + +static void fill_tokens_str(const char *start, char **lib, char **pro, char **ent) +{ + char *current = ddsrt_strdup(start); + char *next = current; + char *ending = next; + fill_token(&next, &ending, lib); + fill_token(&next, &ending, pro); + fill_token(&next, &ending, ent); + ddsrt_free(current); +} + +static void empty_tokens_str(char *lib, char *pro, char *ent) +{ + ddsrt_free(lib); + ddsrt_free(pro); + ddsrt_free(ent); +} + +static dds_return_t resolve_token(const char *key, char **lib, char **prof, char **ent) +{ + dds_return_t ret = DDS_RETCODE_OK; + if (key == NULL) + { + ret = DDS_RETCODE_ERROR; + goto err; + } + fill_tokens_str(key, lib, prof, ent); +err: + return ret; +} + +dds_return_t dds_create_qos_provider_scope (const char *path, dds_qos_provider_t **provider, const char *key) +{ + dds_return_t ret = DDS_RETCODE_OK; + struct dds_sysdef_system *sysdef; + if ((ret = read_validate_sysdef(path, &sysdef)) != DDS_RETCODE_OK) + return ret; + char *lib_name = NULL, *prof_name = NULL, *ent_name = NULL; + (void)resolve_token(key, &lib_name, &prof_name, &ent_name); + if ((ret = init_qos_provider(sysdef, path, provider, lib_name, prof_name, ent_name)) != DDS_RETCODE_OK) + { + QOSPROV_ERROR("Failed to create qos provider file: %s, scope: %s", path, key); + goto err; + } +err: + empty_tokens_str(lib_name, prof_name, ent_name); + dds_sysdef_fini_sysdef(sysdef); + return ret; +} + +void dds_delete_qos_provider (dds_qos_provider_t *provider) +{ + if (provider) + { + ddsrt_hh_enum(provider->keyed_qos, cleanup_qos_items, NULL); + ddsrt_hh_free(provider->keyed_qos); + ddsrt_free(provider->file_path); + ddsrt_free(provider); + } +} diff --git a/src/core/ddsc/src/dds_sysdef_parser.c b/src/core/ddsc/src/dds_sysdef_parser.c new file mode 100644 index 0000000000..63c5150d87 --- /dev/null +++ b/src/core/ddsc/src/dds_sysdef_parser.c @@ -0,0 +1,3065 @@ +// Copyright(c) 2024 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#include +#include + +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/string.h" +#include "dds/ddsrt/strtol.h" +#include "dds/ddsrt/hopscotch.h" +#include "dds/ddsrt/xmlparser.h" +#include "dds/ddsrt/sockets.h" +#include "dds/ddsi/ddsi_unused.h" +#include "dds/ddsi/ddsi_domaingv.h" + +#include "dds__sysdef_model.h" +#include "dds__sysdef_parser.h" + +#define _STR(s) #s +#define STR(s) _STR(s) + +#define PP ELEMENT_KIND_QOS_PARTICIPANT +#define SUB ELEMENT_KIND_QOS_SUBSCRIBER +#define PUB ELEMENT_KIND_QOS_PUBLISHER +#define TP ELEMENT_KIND_QOS_TOPIC +#define WR ELEMENT_KIND_QOS_WRITER +#define RD ELEMENT_KIND_QOS_READER +#define QOS_POLICY_MAPPING(p,...) \ + static const enum element_kind qos_policy_mapping_ ## p[] = { __VA_ARGS__ }; + + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_DEADLINE, RD, WR, TP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_DESTINATIONORDER, RD, WR, TP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_DURABILITY, RD, WR, TP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE, WR, TP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_ENTITYFACTORY, SUB, PUB, PP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_GROUPDATA, SUB, PUB) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_HISTORY, RD, WR, TP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_LATENCYBUDGET, RD, WR, TP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_LIFESPAN, WR, TP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_LIVELINESS, RD, WR, TP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_OWNERSHIP, RD, WR, TP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_OWNERSHIPSTRENGTH, WR) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_PARTITION, SUB, PUB) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_PRESENTATION, SUB, PUB) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_READERDATALIFECYCLE, RD) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_RELIABILITY, RD, WR, TP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS, RD, WR, TP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_TIMEBASEDFILTER, RD) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_TOPICDATA, TP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_TRANSPORTPRIORITY, WR, TP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_USERDATA, RD, WR, PP) + QOS_POLICY_MAPPING (ELEMENT_KIND_QOS_POLICY_WRITERDATALIFECYCLE, WR) + +#undef PP +#undef SUB +#undef PUB +#undef TP +#undef WR +#undef RD + +#define MAX_ERRMSG_SZ 300 + +#define NO_INIT NULL +#define NO_FINI NULL + +#define PARSER_ERROR(pstate,line,...) \ + do { \ + (void) snprintf ((pstate)->err_msg, MAX_ERRMSG_SZ, __VA_ARGS__); \ + (pstate)->err_line = (line); \ + (pstate)->has_err = true; \ + } while (0) + +#define CHECK_PARENT_NULL(pstate, current) \ + do { if ((current) == NULL) { \ + PARSER_ERROR (pstate, line, "Current element NULL for element '%s'", name); \ + return SD_PARSE_RESULT_SYNTAX_ERR; \ + } } while (0) + +#define CHECK_PARENT_KIND(pstate, parent_kind, current) \ + do { if ((current)->kind != parent_kind) { \ + PARSER_ERROR (pstate, line, "Invalid parent kind (%d) for element '%s'", (current)->kind, name); \ + return SD_PARSE_RESULT_SYNTAX_ERR; \ + } } while (0) + +#define _CREATE_NODE(pstate, element_type, element_kind, element_data_type, parent_kind, current, element_init, element_fini) \ + { \ + CHECK_PARENT_KIND (pstate, (parent_kind), current); \ + if (((current) = new_node (pstate, element_kind, element_data_type, current, sizeof (struct element_type), element_init, element_fini)) == NULL) \ + return SD_PARSE_RESULT_ERR; \ + } + +#define CREATE_NODE_LIST(pstate, element_type, element_kind, element_init, element_fini, element_name, parent_type, parent_kind, current) \ + do { \ + struct parent_type *parent = (struct parent_type *) current; \ + _CREATE_NODE(pstate, element_type, element_kind, ELEMENT_DATA_TYPE_GENERIC, parent_kind, current, element_init, element_fini); \ + if (parent->element_name == NULL) { \ + parent->element_name = (struct element_type *) current; \ + } else { \ + struct xml_element *tail = (struct xml_element *) parent->element_name; \ + while (tail->next != NULL) { \ + tail = tail->next; \ + } \ + tail->next = current; \ + } \ + goto status_ok; \ + } while (0) + +#define CREATE_NODE_SINGLE(pstate, element_type, element_kind, element_init, element_fini, element_name, parent_type, parent_kind, current) \ + do { \ + struct parent_type *parent = (struct parent_type *) current; \ + if (parent->element_name != NULL) { \ + PARSER_ERROR (pstate, line, "Duplicate element '%s'", name); \ + return SD_PARSE_RESULT_SYNTAX_ERR; \ + } \ + _CREATE_NODE(pstate, element_type, element_kind, ELEMENT_DATA_TYPE_GENERIC, parent_kind, current, element_init, element_fini); \ + parent->element_name = (struct element_type *) current; \ + goto status_ok; \ + } while (0) + +#define CREATE_NODE_CUSTOM(pstate, element_type, element_kind, element_init, element_fini, parent_kind, current) \ + do { \ + _CREATE_NODE(pstate, element_type, element_kind, ELEMENT_DATA_TYPE_GENERIC, parent_kind, current, element_init, element_fini); \ + current->retain = false; \ + goto status_ok; \ + } while (0) + +#define CREATE_NODE_DURATION(pstate, element_type, element_kind, element_init, element_fini, parent_kind, current) \ + do { \ + _CREATE_NODE(pstate, element_type, element_kind, ELEMENT_DATA_TYPE_DURATION, parent_kind, current, element_init, element_fini); \ + current->retain = false; \ + current->handle_close = true; \ + goto status_ok; \ + } while (0) + +#define CREATE_NODE_DURATION_SEC(pstate, current) \ + do { \ + _CREATE_NODE(pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_DURATION_SEC, ELEMENT_DATA_TYPE_GENERIC, current->kind, current, NO_INIT, NO_FINI); \ + current->retain = false; \ + goto status_ok; \ + } while (0) + +#define CREATE_NODE_DURATION_NSEC(pstate, current) \ + do { \ + _CREATE_NODE(pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_DURATION_NSEC, ELEMENT_DATA_TYPE_GENERIC, current->kind, current, NO_INIT, NO_FINI); \ + current->retain = false; \ + goto status_ok; \ + } while (0) + +#define CREATE_NODE_QOS(pstate, element_type, element_kind, element_init, element_fini, current) \ + do { \ + bool allowed = false; \ + for (uint32_t n = 0; !allowed && n < sizeof (qos_policy_mapping_ ## element_kind) / sizeof (qos_policy_mapping_ ## element_kind[0]); n++) { \ + allowed = (current)->kind == qos_policy_mapping_ ## element_kind[n]; \ + } \ + if (!allowed) { \ + PARSER_ERROR (pstate, line, "Invalid parent kind (%d) for element '%s'", (current)->kind, name); \ + return SD_PARSE_RESULT_SYNTAX_ERR; \ + } \ + if (((current) = new_node (pstate, element_kind, ELEMENT_DATA_TYPE_GENERIC, current, sizeof (struct element_type), element_init, element_fini)) == NULL) \ + return SD_PARSE_RESULT_ERR;\ + current->retain = false; \ + current->handle_close = true; \ + goto status_ok; \ + } while (0) + +struct parse_sysdef_state { + struct dds_sysdef_system *sysdef; + struct xml_element *current; + uint32_t scope; + bool has_err; + int err_line; + char err_msg[MAX_ERRMSG_SZ]; +}; + +static bool str_to_int32 (const char *str, int32_t *value) +{ + char *endptr; + long long l; + if (ddsrt_strtoll (str, &endptr, 0, &l) != DDS_RETCODE_OK || l < INT32_MIN || l > INT32_MAX) { + return false; + } + *value = (int32_t) l; + return (*endptr == '\0'); +} + +static bool str_to_uint8 (const char *str, uint8_t *value) +{ + char *endptr; + long long l; + if (ddsrt_strtoll (str, &endptr, 0, &l) != DDS_RETCODE_OK || l < 0 || l > UINT8_MAX) { + return false; + } + *value = (uint8_t) l; + return (*endptr == '\0'); +} + +static bool str_to_uint16 (const char *str, uint16_t *value) +{ + char *endptr; + long long l; + if (ddsrt_strtoll (str, &endptr, 0, &l) != DDS_RETCODE_OK || l < 0 || l > UINT16_MAX) { + return false; + } + *value = (uint16_t) l; + return (*endptr == '\0'); +} + +static bool str_to_uint32 (const char *str, uint32_t *value) +{ + char *endptr; + long long l; + if (ddsrt_strtoll (str, &endptr, 0, &l) != DDS_RETCODE_OK || l < 0 || l > UINT32_MAX) { + return false; + } + *value = (uint32_t) l; + return (*endptr == '\0'); +} + +static bool str_to_int64 (const char *str, int64_t *value) +{ + char *endptr; + long long l; + if (ddsrt_strtoll (str, &endptr, 0, &l) != DDS_RETCODE_OK || l < INT64_MIN || l > INT64_MAX) { + return false; + } + *value = (int64_t) l; + return (*endptr == '\0'); +} + +static bool str_to_bool (const char *str, bool *value) +{ + if (strcmp (str, "true") == 0 || strcmp (str, "1") == 0) + *value = true; + else if (strcmp (str, "false") == 0 || strcmp (str, "0") == 0) + *value = false; + else + return false; + + return true; +} + +static struct xml_element *new_node (struct parse_sysdef_state * const pstate, enum element_kind kind, enum element_data_type data_type, struct xml_element *parent, size_t size, init_fn init, fini_fn fini) +{ + struct xml_element *e = ddsrt_malloc (size); + if (e == NULL) { + PARSER_ERROR (pstate, 0, "Out of memory"); + return NULL; + } + memset (e, 0, size); + e->parent = parent; + e->kind = kind; + e->data_type = data_type; + e->retain = true; + e->handle_close = false; + e->next = NULL; + e->fini = fini; + if (init) { + if (init (pstate, e) != 0) { + return NULL; + } + } + return e; +} + +static void free_node (void *node) +{ + struct xml_element *element = (struct xml_element *) node; + while (element != NULL) + { + struct xml_element *tmp = element; + element = tmp->next; + if (tmp->fini) + tmp->fini (tmp); + ddsrt_free (tmp); + } +} + +static void fini_type (struct xml_element *node) +{ + struct dds_sysdef_type *type = (struct dds_sysdef_type *) node; + ddsrt_free (type->name); + ddsrt_free (type->identifier); +} + +static void fini_type_lib (struct xml_element *node) +{ + struct dds_sysdef_type_lib *type_lib = (struct dds_sysdef_type_lib *) node; + free_node (type_lib->types); +} + +static void fini_qos_groupdata (struct xml_element *node) +{ + struct dds_sysdef_QOS_POLICY_GROUPDATA *qp = (struct dds_sysdef_QOS_POLICY_GROUPDATA *) node; + assert (qp != NULL); + ddsrt_free (qp->values.value); +} + +static void fini_qos_topicdata (struct xml_element *node) +{ + struct dds_sysdef_QOS_POLICY_TOPICDATA *qp = (struct dds_sysdef_QOS_POLICY_TOPICDATA *) node; + assert (qp != NULL); + ddsrt_free (qp->values.value); +} + +static void fini_qos_userdata (struct xml_element *node) +{ + struct dds_sysdef_QOS_POLICY_USERDATA *qp = (struct dds_sysdef_QOS_POLICY_USERDATA *) node; + assert (qp != NULL); + ddsrt_free (qp->values.value); +} + +static void fini_qos_partition (struct xml_element *node) +{ + struct dds_sysdef_QOS_POLICY_PARTITION *qp = (struct dds_sysdef_QOS_POLICY_PARTITION *) node; + assert (qp != NULL); + free_node (qp->name); +} + +static void fini_qos_partition_name (struct xml_element *node) +{ + struct dds_sysdef_QOS_POLICY_PARTITION_NAME *p = (struct dds_sysdef_QOS_POLICY_PARTITION_NAME *) node; + assert (p != NULL); + free_node (p->elements); +} + +static void fini_qos_partition_name_element (struct xml_element *node) +{ + struct dds_sysdef_QOS_POLICY_PARTITION_NAME_ELEMENT *p = (struct dds_sysdef_QOS_POLICY_PARTITION_NAME_ELEMENT *) node; + assert (p != NULL); + ddsrt_free (p->element); +} + +static void fini_qos (struct xml_element *node) +{ + struct dds_sysdef_qos *qos = (struct dds_sysdef_qos *) node; + assert (qos != NULL); + dds_delete_qos (qos->qos); + ddsrt_free (qos->name); +} + +static void fini_qos_profile (struct xml_element *node) +{ + struct dds_sysdef_qos_profile *qos_profile = (struct dds_sysdef_qos_profile *) node; + free_node (qos_profile->qos); + ddsrt_free (qos_profile->name); +} + +static void fini_qos_lib (struct xml_element *node) +{ + struct dds_sysdef_qos_lib *qos_lib = (struct dds_sysdef_qos_lib *) node; + free_node (qos_lib->qos_profiles); + ddsrt_free (qos_lib->name); +} + +static void fini_register_type (struct xml_element *node) +{ + struct dds_sysdef_register_type *reg_type = (struct dds_sysdef_register_type *) node; + ddsrt_free (reg_type->name); +} + +static void fini_topic (struct xml_element *node) +{ + struct dds_sysdef_topic *topic = (struct dds_sysdef_topic *) node; + free_node (topic->qos); + ddsrt_free (topic->name); +} + +static void fini_domain (struct xml_element *node) +{ + struct dds_sysdef_domain *domain = (struct dds_sysdef_domain *) node; + free_node (domain->register_types); + free_node (domain->topics); + ddsrt_free (domain->name); +} + +static void fini_domain_lib (struct xml_element *node) +{ + struct dds_sysdef_domain_lib *domain_lib = (struct dds_sysdef_domain_lib *) node; + free_node (domain_lib->domains); + ddsrt_free (domain_lib->name); +} + +static void fini_publisher (struct xml_element *node) +{ + struct dds_sysdef_publisher *publisher = (struct dds_sysdef_publisher *) node; + free_node (publisher->writers); + free_node (publisher->qos); + ddsrt_free (publisher->name); +} + +static void fini_writer (struct xml_element *node) +{ + struct dds_sysdef_writer *writer = (struct dds_sysdef_writer *) node; + free_node (writer->qos); + ddsrt_free (writer->name); +} + +static void fini_subscriber (struct xml_element *node) +{ + struct dds_sysdef_subscriber *subscriber = (struct dds_sysdef_subscriber *) node; + free_node (subscriber->readers); + free_node (subscriber->qos); + ddsrt_free (subscriber->name); +} + +static void fini_reader (struct xml_element *node) +{ + struct dds_sysdef_reader *reader = (struct dds_sysdef_reader *) node; + free_node (reader->qos); + ddsrt_free (reader->name); +} + +static void fini_participant (struct xml_element *node) +{ + struct dds_sysdef_participant *participant = (struct dds_sysdef_participant *) node; + free_node (participant->publishers); + free_node (participant->subscribers); + free_node (participant->topics); + free_node (participant->qos); + free_node (participant->register_types); + ddsrt_free (participant->name); + ddsrt_free (participant->guid_prefix); +} + +static void fini_participant_lib (struct xml_element *node) +{ + struct dds_sysdef_participant_lib *participant_lib = (struct dds_sysdef_participant_lib *) node; + free_node (participant_lib->participants); + ddsrt_free (participant_lib->name); +} + +static void fini_application (struct xml_element *node) +{ + struct dds_sysdef_application *application = (struct dds_sysdef_application *) node; + free_node (application->participants); + ddsrt_free (application->name); +} + +static void fini_application_lib (struct xml_element *node) +{ + struct dds_sysdef_application_lib *application_lib = (struct dds_sysdef_application_lib *) node; + free_node (application_lib->applications); + ddsrt_free (application_lib->name); +} + +static void fini_node (struct xml_element *node) +{ + struct dds_sysdef_node *n = (struct dds_sysdef_node *) node; + ddsrt_free (n->name); + ddsrt_free (n->hostname); + ddsrt_free (n->ipv4_addr); + ddsrt_free (n->ipv6_addr); + ddsrt_free (n->mac_addr); +} + +static void fini_node_lib (struct xml_element *node) +{ + struct dds_sysdef_node_lib *node_lib = (struct dds_sysdef_node_lib *) node; + free_node (node_lib->nodes); + ddsrt_free (node_lib->name); +} + +static void fini_conf (struct xml_element *node) +{ + struct dds_sysdef_configuration *conf = (struct dds_sysdef_configuration *) node; + free_node (conf->tsn_configuration); +} + +static void fini_conf_tsn (struct xml_element *node) +{ + struct dds_sysdef_tsn_configuration *conf = (struct dds_sysdef_tsn_configuration *) node; + free_node (conf->tsn_talker_configurations); + free_node (conf->tsn_listener_configurations); +} + +static void fini_conf_tsn_talker (struct xml_element *node) +{ + struct dds_sysdef_tsn_talker_configuration *conf = (struct dds_sysdef_tsn_talker_configuration *) node; + free_node (conf->data_frame_specification); + free_node (conf->network_requirements); + free_node (conf->traffic_specification); + ddsrt_free (conf->stream_name); + ddsrt_free (conf->name); +} + +static void fini_conf_tsn_traffic_specification (struct xml_element *node) +{ + struct dds_sysdef_tsn_traffic_specification *conf = (struct dds_sysdef_tsn_traffic_specification *) node; + free_node (conf->time_aware); +} + +static void fini_conf_tsn_ip_tuple (struct xml_element *node) +{ + struct dds_sysdef_tsn_ip_tuple *conf = (struct dds_sysdef_tsn_ip_tuple *) node; + ddsrt_free (conf->destination_ip_address); + ddsrt_free (conf->source_ip_address); +} + +static void fini_conf_tsn_data_frame_specification (struct xml_element *node) +{ + struct dds_sysdef_tsn_data_frame_specification *conf = (struct dds_sysdef_tsn_data_frame_specification *) node; + free_node (conf->ipv4_tuple); + free_node (conf->ipv6_tuple); + free_node (conf->mac_addresses); + free_node (conf->vlan_tag); +} + +static void fini_conf_tsn_listener (struct xml_element *node) +{ + struct dds_sysdef_tsn_listener_configuration *conf = (struct dds_sysdef_tsn_listener_configuration *) node; + free_node (conf->network_requirements); + ddsrt_free (conf->stream_name); + ddsrt_free (conf->name); +} + +static void fini_application_list (struct xml_element *node) +{ + struct dds_sysdef_application_list *application_list = (struct dds_sysdef_application_list *) node; + free_node (application_list->application_refs); +} + +static void fini_deployment (struct xml_element *node) +{ + struct dds_sysdef_deployment *deployment = (struct dds_sysdef_deployment *) node; + free_node (deployment->application_list); + free_node (deployment->configuration); + ddsrt_free (deployment->name); +} + +static void fini_deployment_lib (struct xml_element *node) +{ + struct dds_sysdef_deployment_lib *deployment_lib = (struct dds_sysdef_deployment_lib *) node; + free_node (deployment_lib->deployments); + ddsrt_free (deployment_lib->name); +} + +static void fini_sysdef (struct xml_element *node) +{ + struct dds_sysdef_system *sysdef = (struct dds_sysdef_system *) node; + free_node (sysdef->type_libs); + free_node (sysdef->qos_libs); + free_node (sysdef->domain_libs); + free_node (sysdef->participant_libs); + free_node (sysdef->application_libs); + free_node (sysdef->node_libs); + free_node (sysdef->deployment_libs); +} + +static int init_qos (UNUSED_ARG (struct parse_sysdef_state * const pstate), struct xml_element *node) +{ + struct dds_sysdef_qos *sdqos = (struct dds_sysdef_qos *) node; + sdqos->qos = dds_create_qos (); + enum dds_sysdef_qos_kind qos_kind; + switch (node->kind) { + case ELEMENT_KIND_QOS_PARTICIPANT: + qos_kind = DDS_SYSDEF_PARTICIPANT_QOS; + break; + case ELEMENT_KIND_QOS_TOPIC: + qos_kind = DDS_SYSDEF_TOPIC_QOS; + break; + case ELEMENT_KIND_QOS_PUBLISHER: + qos_kind = DDS_SYSDEF_PUBLISHER_QOS; + break; + case ELEMENT_KIND_QOS_SUBSCRIBER: + qos_kind = DDS_SYSDEF_SUBSCRIBER_QOS; + break; + case ELEMENT_KIND_QOS_READER: + qos_kind = DDS_SYSDEF_READER_QOS; + break; + case ELEMENT_KIND_QOS_WRITER: + qos_kind = DDS_SYSDEF_WRITER_QOS; + break; + default: + return SD_PARSE_RESULT_SYNTAX_ERR; + } + sdqos->kind = qos_kind; + return 0; +} + +#define PROC_ATTR_STRING(type,attr_name,param_field,validator_fn) \ + do { \ + if (ddsrt_strcasecmp (name, attr_name) == 0) \ + { \ + if (!validator_fn (value)) { \ + PARSER_ERROR (pstate, line, "Invalid identifier '%s'", value); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } else { \ + struct type *t = (struct type *) pstate->current; \ + if (t->param_field == NULL) { \ + assert (!attr_processed); \ + t->param_field = ddsrt_strdup (value); \ + attr_processed = true; \ + } else { \ + PARSER_ERROR (pstate, line, "Duplicate attribute '%s'", attr_name); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } \ + } \ + } \ + } while (0) + +#define PROC_ATTR_NAME(type) PROC_ATTR_STRING(type, "name", name, dds_sysdef_is_valid_identifier_syntax) + +#define _PROC_ATTR_INTEGER(type, attr_type, attr_name, param_field, param_populated_bit) \ + do { \ + if (ddsrt_strcasecmp (name, attr_name) == 0) \ + { \ + assert (!attr_processed); \ + struct type *t = (struct type *) pstate->current; \ + if (t->populated & param_populated_bit) { \ + PARSER_ERROR (pstate, line, "Duplicate attribute '%s'", STR(param_field)); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } else { \ + attr_type ## _t v; \ + if (str_to_ ## attr_type (value, &v)) { \ + t->param_field = v; \ + t->populated |= param_populated_bit; \ + attr_processed = true; \ + } else { \ + PARSER_ERROR (pstate, line, "Invalid value for attribute '%s'", attr_name); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } \ + } \ + } \ + } while (0) + +#define PROC_ATTR_UINT32(type, attr_name, param_field, param_populated_bit) \ + _PROC_ATTR_INTEGER(type,uint32,attr_name,param_field,param_populated_bit) + +#define PROC_ATTR_INT32(type, attr_name, param_field, param_populated_bit) \ + _PROC_ATTR_INTEGER(type,int32,attr_name,param_field,param_populated_bit) + +#define _PROC_ATTR_FN(type, attr_name, current, param_field, fn) \ + do { \ + if (ddsrt_strcasecmp (name, attr_name) == 0) \ + { \ + assert (!attr_processed); \ + struct type *t = (struct type *) current; \ + int fn_ret; \ + if ((fn_ret = fn (pstate, value, &t->param_field)) == SD_PARSE_RESULT_OK) { \ + attr_processed = true; \ + } else { \ + if (fn_ret == SD_PARSE_RESULT_DUPLICATE) \ + PARSER_ERROR (pstate, line, "Duplicate attribute '%s'", attr_name); \ + else \ + PARSER_ERROR (pstate, line, "Invalid value for attribute '%s'", attr_name); \ + ret = fn_ret; \ + } \ + } \ + } while (0) + +#define PROC_ATTR_FN(type, attr_name, param_field, fn) \ + _PROC_ATTR_FN(type, attr_name, pstate->current, param_field, fn) + +#define PROC_ATTR_FN_PARENT(type, attr_name, param_field, fn) \ + _PROC_ATTR_FN(type, attr_name, pstate->current->parent, param_field, fn) + +static int proc_attr_resolve_type_ref (struct parse_sysdef_state * const pstate, const char *type_ref, struct dds_sysdef_type **type) +{ + if (*type != NULL) { + return SD_PARSE_RESULT_DUPLICATE; + } + for (struct dds_sysdef_type_lib *tlib = pstate->sysdef->type_libs; *type == NULL && tlib != NULL; tlib = (struct dds_sysdef_type_lib *) tlib->xmlnode.next) + { + for (struct dds_sysdef_type *t = tlib->types; *type == NULL && t != NULL; t = (struct dds_sysdef_type *) t->xmlnode.next) + { + if (strcmp (t->name, type_ref) == 0) { + *type = t; + } + } + } + return *type != NULL ? SD_PARSE_RESULT_OK : SD_PARSE_RESULT_INVALID_REF; +} + +static struct dds_sysdef_register_type *find_reg_type_impl (const char *register_type_ref, struct dds_sysdef_register_type *register_types) +{ + struct dds_sysdef_register_type *register_type = NULL; + for (struct dds_sysdef_register_type *t = register_types; register_type == NULL && t != NULL; t = (struct dds_sysdef_register_type *) t->xmlnode.next) + { + if (strcmp (t->name, register_type_ref) == 0) + register_type = t; + } + return register_type; +} + +static int proc_attr_resolve_register_type_ref (struct parse_sysdef_state * const pstate, const char *register_type_ref, struct dds_sysdef_register_type **register_type) +{ + assert (pstate->current->parent->kind == ELEMENT_KIND_DOMAIN || pstate->current->parent->kind == ELEMENT_KIND_PARTICIPANT); + if (*register_type != NULL) { + return SD_PARSE_RESULT_DUPLICATE; + } + struct dds_sysdef_domain *domain = NULL; + if (pstate->current->parent->kind == ELEMENT_KIND_PARTICIPANT) + { + for (struct dds_sysdef_participant *participant = (struct dds_sysdef_participant *) pstate->current->parent; *register_type == NULL && participant != NULL; participant = participant->base) + { + if ((*register_type = find_reg_type_impl (register_type_ref, participant->register_types)) == NULL) + { + // Not found in this participant, get the domain to search in + if (participant->domain_ref == NULL) + ; + else if (domain == NULL) + domain = participant->domain_ref; + else + { + // Domain ref for a participant should be equal to the domain ref of its base-participants + if (domain != participant->domain_ref) + return SD_PARSE_RESULT_ERR; + } + } + } + if (domain == NULL && *register_type == NULL) + return SD_PARSE_RESULT_ERR; + } + else + { + domain = (struct dds_sysdef_domain *) pstate->current->parent; + } + + if (*register_type == NULL) + *register_type = find_reg_type_impl (register_type_ref, domain->register_types); + + return *register_type != NULL ? SD_PARSE_RESULT_OK : SD_PARSE_RESULT_INVALID_REF; +} + +static int proc_attr_resolve_topic_ref (struct parse_sysdef_state * const pstate, const char *topic_ref, struct dds_sysdef_topic **topic) +{ + if (*topic != NULL) { + return SD_PARSE_RESULT_DUPLICATE; + } + assert ((pstate->current->kind == ELEMENT_KIND_READER && pstate->current->parent->kind == ELEMENT_KIND_SUBSCRIBER) || + (pstate->current->kind == ELEMENT_KIND_WRITER && pstate->current->parent->kind == ELEMENT_KIND_PUBLISHER)); + assert (pstate->current->parent->parent->kind == ELEMENT_KIND_PARTICIPANT); + struct dds_sysdef_domain *domain = NULL; + for (struct dds_sysdef_participant *participant = (struct dds_sysdef_participant *) pstate->current->parent->parent; *topic == NULL && participant != NULL; participant = participant->base) + { + struct dds_sysdef_topic *topics[2] = { participant->topics }; + if (participant->domain_ref == NULL) + ; + else if (domain == NULL) + { + domain = participant->domain_ref; + topics[1] = domain->topics; + } + else + { + /* Domain ref for a participant should be equal to the domain ref of its base-participants, + this is checked in the validation step after parsing */ + } + for (uint32_t n = 0; n < sizeof (topics) / sizeof (topics[0]); n++) + { + for (struct dds_sysdef_topic *t = topics[n]; *topic == NULL && t != NULL; t = (struct dds_sysdef_topic *) t->xmlnode.next) + { + if (strcmp (t->name, topic_ref) == 0) { + *topic = t; + } + } + } + } + + return *topic != NULL ? SD_PARSE_RESULT_OK : SD_PARSE_RESULT_INVALID_REF; +} + + +static int split_ref (const char *ref, char **lib, char **local_name) +{ + int ret = SD_PARSE_RESULT_OK; + const char *sep = "::"; + const char *spos = strstr (ref, sep); + if (spos != NULL) + { + ptrdiff_t lib_len = spos - ref; + *lib = ddsrt_strndup (ref, (size_t) lib_len); + *local_name = ddsrt_strdup (spos + strlen (sep)); + } + else + { + ret = SD_PARSE_RESULT_INVALID_REF; + } + return ret; +} + +#define _RESOLVE_LIB(lib_type, lib_name, dst) \ + do { for (struct dds_sysdef_## lib_type ## _lib *l = pstate->sysdef->lib_type ## _libs ; dst == NULL && l != NULL; l = (struct dds_sysdef_ ## lib_type ## _lib *) l->xmlnode.next) \ + { \ + if (strcmp (l->name, lib_name) == 0) { \ + dst = l; \ + } \ + } } while (0) + +#define _RESOLVE_ENTITY(lib, entity_type, ent_var, ent_name, dst) \ + do { for (struct dds_sysdef_ ## entity_type *e = lib->ent_var; dst == NULL && e != NULL; e = (struct dds_sysdef_## entity_type *) e->xmlnode.next) \ + { \ + if (strcmp (e->name, ent_name) == 0) { \ + dst = e; \ + } \ + } } while (0) + +#define RESOLVE_REF_FNDEF(type, lib_type, type_var) \ + static int proc_attr_resolve_ ## type ## _ref (struct parse_sysdef_state * const pstate, const char *type_ref, struct dds_sysdef_ ## type **type) \ + { \ + char *lib_name, *local_name; \ + if (*type != NULL) { \ + return SD_PARSE_RESULT_DUPLICATE; \ + } \ + if (split_ref (type_ref, &lib_name, &local_name) != SD_PARSE_RESULT_OK) \ + return SD_PARSE_RESULT_ERR; \ + struct dds_sysdef_ ## lib_type ## _lib *lib = NULL; \ + _RESOLVE_LIB(lib_type, lib_name, lib); \ + if (lib != NULL) \ + _RESOLVE_ENTITY(lib, type, type_var, local_name, *type); \ + ddsrt_free (lib_name); \ + ddsrt_free (local_name); \ + return *type != NULL ? SD_PARSE_RESULT_OK : SD_PARSE_RESULT_INVALID_REF; \ + } + +RESOLVE_REF_FNDEF(qos_profile, qos, qos_profiles) +RESOLVE_REF_FNDEF(domain, domain, domains) +RESOLVE_REF_FNDEF(participant, participant, participants) +RESOLVE_REF_FNDEF(node, node, nodes) +RESOLVE_REF_FNDEF(application, application, applications) + +enum resolve_endpoint_kind { + RESOLVE_ENDPOINT_READER, + RESOLVE_ENDPOINT_WRITER +}; + +static int proc_attr_resolve_endpoint_ref (struct parse_sysdef_state * const pstate, const char *type_ref, enum resolve_endpoint_kind kind, struct xml_element **endpoint) +{ + char *appl_lib_name, *tail; + if (*endpoint != NULL) { + return SD_PARSE_RESULT_ERR; + } + if (split_ref (type_ref, &appl_lib_name, &tail) != SD_PARSE_RESULT_OK) + return SD_PARSE_RESULT_ERR; + struct dds_sysdef_application_lib *appl_lib = NULL; + _RESOLVE_LIB(application, appl_lib_name, appl_lib); + if (appl_lib != NULL) + { + char *appl_name, *tail1; + if (split_ref (tail, &appl_name, &tail1) != SD_PARSE_RESULT_OK) + return SD_PARSE_RESULT_ERR; + + struct dds_sysdef_application *appl = NULL; + _RESOLVE_ENTITY(appl_lib, application, applications, appl_name, appl); + if (appl != NULL) + { + char *pp_name, *tail2; + if (split_ref (tail1, &pp_name, &tail2) != SD_PARSE_RESULT_OK) + return SD_PARSE_RESULT_ERR; + + struct dds_sysdef_participant *pp = NULL; + _RESOLVE_ENTITY(appl, participant, participants, pp_name, pp); + if (pp != NULL) + { + char *pubsub_name, *endpoint_name; + if (split_ref (tail2, &pubsub_name, &endpoint_name) != SD_PARSE_RESULT_OK) + return SD_PARSE_RESULT_ERR; + + if (kind == RESOLVE_ENDPOINT_WRITER) + { + struct dds_sysdef_publisher *pub = NULL; + _RESOLVE_ENTITY(pp, publisher, publishers, pubsub_name, pub); + if (pub != NULL) + { + struct dds_sysdef_writer **writer = (struct dds_sysdef_writer **) endpoint; + _RESOLVE_ENTITY(pub, writer, writers, endpoint_name, *writer); + } + } + else + { + struct dds_sysdef_subscriber *sub = NULL; + _RESOLVE_ENTITY(pp, subscriber, subscribers, pubsub_name, sub); + if (sub != NULL) + { + struct dds_sysdef_reader **reader = (struct dds_sysdef_reader **) endpoint; + _RESOLVE_ENTITY(sub, reader, readers, endpoint_name, *reader); + } + } + ddsrt_free (endpoint_name); + ddsrt_free (pubsub_name); + } + ddsrt_free (pp_name); + ddsrt_free (tail2); + } + ddsrt_free (appl_name); + ddsrt_free (tail1); + } + ddsrt_free (appl_lib_name); + ddsrt_free (tail); + + return *endpoint != NULL ? SD_PARSE_RESULT_OK : SD_PARSE_RESULT_INVALID_REF; +} + +static int proc_attr_resolve_datawriter_ref (struct parse_sysdef_state * const pstate, const char *type_ref, struct dds_sysdef_writer **writer) +{ + return proc_attr_resolve_endpoint_ref (pstate, type_ref, RESOLVE_ENDPOINT_WRITER, (struct xml_element **) writer); +} + +static int proc_attr_resolve_datareader_ref (struct parse_sysdef_state * const pstate, const char *type_ref, struct dds_sysdef_reader **reader) +{ + return proc_attr_resolve_endpoint_ref (pstate, type_ref, RESOLVE_ENDPOINT_READER, (struct xml_element **) reader); +} + +static int dds_sysdef_parse_hex (const char* hex, unsigned char* bytes) +{ + size_t hex_len = strlen (hex); + if (hex_len % 2 != 0) + return SD_PARSE_RESULT_ERR; + + for (size_t i = 0; i < hex_len; i += 2) + { + int a = ddsrt_todigit (hex[i]), b = ddsrt_todigit (hex[i + 1]); + if (a == -1 || a > 15 || b == -1 || b > 15) + return SD_PARSE_RESULT_ERR; + bytes[i / 2] = (unsigned char) (((uint8_t) a << 4) + b); + } + return SD_PARSE_RESULT_OK; +} + +static int proc_attr_type_identifier (struct parse_sysdef_state * const pstate, const char *value, unsigned char **identifier) +{ + (void) pstate; + if (*identifier != NULL) + return SD_PARSE_RESULT_DUPLICATE; + if (strlen (value) != 2 * TYPE_HASH_LENGTH) + return SD_PARSE_RESULT_ERR; + *identifier = ddsrt_malloc (TYPE_HASH_LENGTH); + if (dds_sysdef_parse_hex (value, *identifier) != SD_PARSE_RESULT_OK) + return SD_PARSE_RESULT_ERR; + return SD_PARSE_RESULT_OK; +} + +static int proc_attr_guid_prefix (struct parse_sysdef_state * const pstate, const char *value, struct dds_sysdef_participant_guid_prefix **prefix) +{ + (void) pstate; + if (strlen (value) != 2 * sizeof (struct dds_sysdef_participant_guid_prefix)) + return SD_PARSE_RESULT_ERR; + + if (*prefix != NULL) + return SD_PARSE_RESULT_DUPLICATE; + + *prefix = ddsrt_malloc (sizeof (**prefix)); + union { struct dds_sysdef_participant_guid_prefix p; unsigned char d[sizeof (struct dds_sysdef_participant_guid_prefix)]; } u = {.p = {0}}; + if (dds_sysdef_parse_hex (value, u.d) != SD_PARSE_RESULT_OK) + return SD_PARSE_RESULT_ERR; + + (*prefix)->p = ddsrt_fromBE4u (u.p.p); + return SD_PARSE_RESULT_OK; +} + +static bool is_alpha (char c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +static bool is_alphanum (char c) +{ + return is_alpha (c) || (c >= '0' && c <= '9'); +} + +static bool is_valid_identifier_char (char c) +{ + return is_alphanum (c) || c == '_'; +} + +static bool dds_sysdef_is_valid_identifier_syntax (const char *name) +{ + if (strlen (name) == 0) + return false; + if (!is_alpha (name[0])) + return false; + for (size_t i = 1; i < strlen (name); i++) + { + if (!is_valid_identifier_char (name[i])) + return false; + } + return true; +} + +static int proc_attr (void *varg, UNUSED_ARG (uintptr_t eleminfo), const char *name, const char *value, int line) +{ + /* All attributes are processed immediately after opening the element */ + struct parse_sysdef_state * const pstate = varg; + bool attr_processed = false; + + if (ddsrt_strcasecmp(name, "xmlns") == 0 || ddsrt_strcasecmp(name, "xmlns:xsi") == 0 ||ddsrt_strcasecmp(name, "xsi:schemaLocation") == 0) + return 0; + + int ret = SD_PARSE_RESULT_OK; + if (pstate->current == NULL) { + PARSER_ERROR (pstate, line, "Current element NULL in proc_attr"); + ret = SD_PARSE_RESULT_ERR; + } + else + { + switch (pstate->current->kind) + { + // Type library + case ELEMENT_KIND_TYPE: + PROC_ATTR_NAME(dds_sysdef_type); + PROC_ATTR_FN(dds_sysdef_type, "identifier", identifier, proc_attr_type_identifier); + break; + + // QoS library + case ELEMENT_KIND_QOS_LIB: + PROC_ATTR_NAME(dds_sysdef_qos_lib); + break; + case ELEMENT_KIND_QOS_PROFILE: + PROC_ATTR_NAME(dds_sysdef_qos_profile); + PROC_ATTR_FN(dds_sysdef_qos_profile, "base_name", base_profile, proc_attr_resolve_qos_profile_ref); + break; + case ELEMENT_KIND_QOS_PARTICIPANT: + case ELEMENT_KIND_QOS_TOPIC: + case ELEMENT_KIND_QOS_PUBLISHER: + case ELEMENT_KIND_QOS_SUBSCRIBER: + case ELEMENT_KIND_QOS_WRITER: + case ELEMENT_KIND_QOS_READER: + PROC_ATTR_NAME(dds_sysdef_qos); + PROC_ATTR_FN(dds_sysdef_qos, "base_name", base_profile, proc_attr_resolve_qos_profile_ref); + break; + + // Domain library + case ELEMENT_KIND_DOMAIN_LIB: + PROC_ATTR_NAME(dds_sysdef_domain_lib); + break; + case ELEMENT_KIND_DOMAIN: + PROC_ATTR_NAME(dds_sysdef_domain); + PROC_ATTR_UINT32(dds_sysdef_domain, "domain_id", domain_id, SYSDEF_DOMAIN_DOMAIN_ID_PARAM_VALUE); + PROC_ATTR_INT32(dds_sysdef_domain, "participant_index", participant_index, SYSDEF_DOMAIN_PARTICIPANT_INDEX_PARAM_VALUE); + break; + case ELEMENT_KIND_PARTICIPANT: + PROC_ATTR_NAME(dds_sysdef_participant); + PROC_ATTR_FN(dds_sysdef_participant, "domain_ref", domain_ref, proc_attr_resolve_domain_ref); + PROC_ATTR_FN(dds_sysdef_participant, "base_name", base, proc_attr_resolve_participant_ref); + PROC_ATTR_FN(dds_sysdef_participant, "guid_prefix", guid_prefix, proc_attr_guid_prefix); + break; + case ELEMENT_KIND_REGISTER_TYPE: + PROC_ATTR_NAME(dds_sysdef_register_type); + PROC_ATTR_FN(dds_sysdef_register_type, "type_ref", type_ref, proc_attr_resolve_type_ref); + break; + case ELEMENT_KIND_PARTICIPANT_LIB: + PROC_ATTR_NAME(dds_sysdef_participant); + break; + case ELEMENT_KIND_TOPIC: + PROC_ATTR_NAME(dds_sysdef_topic); + PROC_ATTR_FN(dds_sysdef_topic, "register_type_ref", register_type_ref, proc_attr_resolve_register_type_ref); + break; + case ELEMENT_KIND_PUBLISHER: + PROC_ATTR_NAME(dds_sysdef_publisher); + break; + case ELEMENT_KIND_SUBSCRIBER: + PROC_ATTR_NAME(dds_sysdef_subscriber); + break; + case ELEMENT_KIND_WRITER: + PROC_ATTR_NAME(dds_sysdef_writer); + PROC_ATTR_FN(dds_sysdef_writer, "topic_ref", topic, proc_attr_resolve_topic_ref); + PROC_ATTR_UINT32(dds_sysdef_writer, "entity_key", entity_key, SYSDEF_WRITER_ENTITY_KEY_PARAM_VALUE); + break; + case ELEMENT_KIND_READER: + PROC_ATTR_NAME(dds_sysdef_reader); + PROC_ATTR_FN(dds_sysdef_reader, "topic_ref", topic, proc_attr_resolve_topic_ref); + PROC_ATTR_UINT32(dds_sysdef_reader, "entity_key", entity_key, SYSDEF_READER_ENTITY_KEY_PARAM_VALUE); + break; + + // Application library + case ELEMENT_KIND_APPLICATION_LIB: + PROC_ATTR_NAME(dds_sysdef_application_lib); + break; + case ELEMENT_KIND_APPLICATION: + PROC_ATTR_NAME(dds_sysdef_application); + break; + + // Node library + case ELEMENT_KIND_NODE_LIB: + PROC_ATTR_NAME(dds_sysdef_node_lib); + break; + case ELEMENT_KIND_NODE: + PROC_ATTR_NAME(dds_sysdef_node); + break; + + // Deployment library + case ELEMENT_KIND_DEPLOYMENT_LIB: + PROC_ATTR_NAME(dds_sysdef_deployment_lib); + break; + case ELEMENT_KIND_DEPLOYMENT: + PROC_ATTR_NAME(dds_sysdef_deployment); + break; + case ELEMENT_KIND_DEPLOYMENT_NODE_REF: + PROC_ATTR_FN_PARENT(dds_sysdef_deployment, "node_ref", node, proc_attr_resolve_node_ref); + break; + case ELEMENT_KIND_DEPLOYMENT_APPLICATION_REF: + PROC_ATTR_FN(dds_sysdef_application_ref, "application_ref", application, proc_attr_resolve_application_ref); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER: + PROC_ATTR_NAME(dds_sysdef_tsn_talker_configuration); + PROC_ATTR_STRING(dds_sysdef_tsn_talker_configuration, "stream_name", stream_name, dds_sysdef_is_valid_identifier_syntax); + PROC_ATTR_FN(dds_sysdef_tsn_talker_configuration, "datawriter_ref", writer, proc_attr_resolve_datawriter_ref); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER: + PROC_ATTR_NAME(dds_sysdef_tsn_listener_configuration); + PROC_ATTR_STRING(dds_sysdef_tsn_listener_configuration, "stream_name", stream_name, dds_sysdef_is_valid_identifier_syntax); + PROC_ATTR_FN(dds_sysdef_tsn_listener_configuration, "datareader_ref", reader, proc_attr_resolve_datareader_ref); + break; + + default: + break; + } + + if (!attr_processed && ret == SD_PARSE_RESULT_OK) + { + PARSER_ERROR (pstate, line, "Unknown attribute '%s'", name); + ret = SD_PARSE_RESULT_ERR; + } + } + return ret; +} + +#define ELEM_CLOSE_QOS_POLICY(policy, policy_desc) \ + do { \ + struct dds_sysdef_QOS_POLICY_ ## policy *qp = (struct dds_sysdef_QOS_POLICY_ ## policy *) pstate->current; \ + struct dds_sysdef_qos *sdqos = (struct dds_sysdef_qos *) pstate->current->parent; \ + if (qp->populated != QOS_POLICY_ ## policy ## _PARAMS) \ + { \ + PARSER_ERROR (pstate, line, "Not all params set for " policy_desc " QoS policy"); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } \ + else if (qget_ ## policy (sdqos->qos)) \ + { \ + PARSER_ERROR (pstate, line, policy_desc " QoS policy already set"); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } \ + else \ + { \ + qset_ ## policy (sdqos->qos, qp ); \ + } \ + } while (0) + +#define ELEM_CLOSE_QOS_DURATION_PROPERTY(policy, param, element_name) \ + do { \ + assert (pstate->current->data_type == ELEMENT_DATA_TYPE_DURATION); \ + struct dds_sysdef_qos_duration_property *d = (struct dds_sysdef_qos_duration_property *) pstate->current; \ + struct dds_sysdef_QOS_POLICY_ ## policy *qp = (struct dds_sysdef_QOS_POLICY_ ## policy *) pstate->current->parent; \ + if (d->populated == 0) \ + { \ + PARSER_ERROR (pstate, line, "Duration not set"); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } \ + else \ + { \ + qp->values.element_name = DDS_SECS(d->sec) + d->nsec; \ + qp->populated |= QOS_POLICY_ ## policy ## _PARAM_ ## param; \ + } \ + } while (0) + +static bool qget_DEADLINE (dds_qos_t *qos) +{ + return dds_qget_deadline (qos, NULL); +} + +static void qset_DEADLINE (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_DEADLINE *qp) +{ + dds_qset_deadline (qos, qp->values.deadline); +} + +static bool qget_DESTINATIONORDER (dds_qos_t *qos) +{ + return dds_qget_destination_order (qos, NULL); +} + +static void qset_DESTINATIONORDER (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_DESTINATIONORDER *qp) +{ + dds_qset_destination_order (qos, qp->values.kind); +} + +static bool qget_DURABILITY (dds_qos_t *qos) +{ + return dds_qget_durability (qos, NULL); +} + +static void qset_DURABILITY (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_DURABILITY *qp) +{ + dds_qset_durability (qos, qp->values.kind); +} + +static bool qget_DURABILITYSERVICE (dds_qos_t *qos) +{ + return dds_qget_durability_service (qos, NULL, NULL, NULL, NULL, NULL, NULL); +} + +static void qset_DURABILITYSERVICE (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_DURABILITYSERVICE *qp) +{ + dds_qset_durability_service (qos, qp->values.service_cleanup_delay, qp->values.history.kind, qp->values.history.depth, qp->values.resource_limits.max_samples, qp->values.resource_limits.max_instances, qp->values.resource_limits.max_samples_per_instance); +} + +static bool qget_GROUPDATA (dds_qos_t *qos) +{ + return dds_qget_groupdata (qos, NULL, NULL); +} + +static void qset_GROUPDATA (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_GROUPDATA *qp) +{ + dds_qset_groupdata (qos, qp->values.value, qp->values.length); +} + +static bool qget_TOPICDATA (dds_qos_t *qos) +{ + return dds_qget_topicdata (qos, NULL, NULL); +} + +static void qset_TOPICDATA (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_TOPICDATA *qp) +{ + dds_qset_topicdata (qos, qp->values.value, qp->values.length); +} + +static bool qget_USERDATA (dds_qos_t *qos) +{ + return dds_qget_userdata (qos, NULL, NULL); +} + +static void qset_USERDATA (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_USERDATA *qp) +{ + dds_qset_userdata (qos, qp->values.value, qp->values.length); +} + +static bool qget_HISTORY (dds_qos_t *qos) +{ + return dds_qget_history (qos, NULL, NULL); +} + +static void qset_HISTORY (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_HISTORY *qp) +{ + dds_qset_history (qos, qp->values.kind, qp->values.depth); +} + +static bool qget_LATENCYBUDGET (dds_qos_t *qos) +{ + return dds_qget_latency_budget (qos, NULL); +} + +static void qset_LATENCYBUDGET (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_LATENCYBUDGET *qp) +{ + dds_qset_latency_budget (qos, qp->values.duration); +} + +static bool qget_LIFESPAN (dds_qos_t *qos) +{ + return dds_qget_lifespan (qos, NULL); +} + +static void qset_LIFESPAN (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_LIFESPAN *qp) +{ + dds_qset_lifespan (qos, qp->values.duration); +} + +static bool qget_LIVELINESS (dds_qos_t *qos) +{ + return dds_qget_liveliness (qos, NULL, NULL); +} + +static void qset_LIVELINESS (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_LIVELINESS *qp) +{ + dds_qset_liveliness (qos, qp->values.kind, qp->values.lease_duration); +} + +static bool qget_OWNERSHIP (dds_qos_t *qos) +{ + return dds_qget_ownership (qos, NULL); +} + +static void qset_OWNERSHIP (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_OWNERSHIP *qp) +{ + dds_qset_ownership (qos, qp->values.kind); +} + +static bool qget_OWNERSHIPSTRENGTH (dds_qos_t *qos) +{ + return dds_qget_ownership_strength (qos, NULL); +} + +static void qset_OWNERSHIPSTRENGTH (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_OWNERSHIPSTRENGTH *qp) +{ + dds_qset_ownership_strength (qos, qp->values.value); +} + +static bool qget_PARTITION (dds_qos_t *qos) +{ + return dds_qget_partition (qos, NULL, NULL); +} + +static void qset_PARTITION (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_PARTITION *qp) +{ + uint32_t c = 0; + for (struct dds_sysdef_QOS_POLICY_PARTITION_NAME_ELEMENT *v = qp->name->elements; v != NULL; v = (struct dds_sysdef_QOS_POLICY_PARTITION_NAME_ELEMENT *) v->xmlnode.next) + c++; + + const char **partitions = ddsrt_malloc (c * sizeof (*partitions)); + uint32_t i = 0; + for (struct dds_sysdef_QOS_POLICY_PARTITION_NAME_ELEMENT *v = qp->name->elements; v != NULL; v = (struct dds_sysdef_QOS_POLICY_PARTITION_NAME_ELEMENT *) v->xmlnode.next) + partitions[i++] = v->element; + dds_qset_partition (qos, c, partitions); +#if _MSC_VER +__pragma(warning(push)) +__pragma(warning(disable: 4090)) +#endif + ddsrt_free (partitions); +#if _MSC_VER +__pragma(warning(pop)) +#endif +} + +static bool qget_PRESENTATION (dds_qos_t *qos) +{ + return dds_qget_presentation (qos, NULL, NULL, NULL); +} + +static void qset_PRESENTATION (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_PRESENTATION *qp) +{ + dds_qset_presentation (qos, qp->values.access_scope, qp->values.coherent_access, qp->values.ordered_access); +} + +static bool qget_READERDATALIFECYCLE (dds_qos_t *qos) +{ + return dds_qget_reader_data_lifecycle (qos, NULL, NULL); +} + +static void qset_READERDATALIFECYCLE (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_READERDATALIFECYCLE *qp) +{ + dds_qset_reader_data_lifecycle (qos, qp->values.autopurge_nowriter_samples_delay, qp->values.autopurge_disposed_samples_delay); +} + +static bool qget_RELIABILITY (dds_qos_t *qos) +{ + return dds_qget_reliability (qos, NULL, NULL); +} + +static void qset_RELIABILITY (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_RELIABILITY *qp) +{ + dds_qset_reliability (qos, qp->values.kind, qp->values.max_blocking_time); +} + +static bool qget_RESOURCELIMITS (dds_qos_t *qos) +{ + return dds_qget_resource_limits (qos, NULL, NULL, NULL); +} + +static void qset_RESOURCELIMITS (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_RESOURCELIMITS *qp) +{ + dds_qset_resource_limits (qos, qp->values.max_samples, qp->values.max_instances, qp->values.max_samples_per_instance); +} + +static bool qget_TIMEBASEDFILTER (dds_qos_t *qos) +{ + return dds_qget_time_based_filter (qos, NULL); +} + +static void qset_TIMEBASEDFILTER (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_TIMEBASEDFILTER *qp) +{ + dds_qset_time_based_filter (qos, qp->values.minimum_separation); +} + +static bool qget_TRANSPORTPRIORITY (dds_qos_t *qos) +{ + return dds_qget_transport_priority (qos, NULL); +} + +static void qset_TRANSPORTPRIORITY (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_TRANSPORTPRIORITY *qp) +{ + dds_qset_transport_priority (qos, qp->values.value); +} + +static bool qget_WRITERDATALIFECYCLE (dds_qos_t *qos) +{ + return dds_qget_writer_data_lifecycle (qos, NULL); +} + +static void qset_WRITERDATALIFECYCLE (dds_qos_t *qos, struct dds_sysdef_QOS_POLICY_WRITERDATALIFECYCLE *qp) +{ + dds_qset_writer_data_lifecycle (qos, qp->values.autodispose_unregistered_instances); +} + +#define _ELEM_CLOSE_REQUIRE_ATTR(type,attr_name,current,element_name) \ + do { \ + struct type *t = (struct type *) current; \ + if (t->element_name == NULL) \ + { \ + PARSER_ERROR (pstate, line, "Attribute '%s' not set", STR(attr_name)); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } \ + } while (0) + +#define ELEM_CLOSE_REQUIRE_ATTR(type,attr_name,param_field) \ + _ELEM_CLOSE_REQUIRE_ATTR(type, attr_name, pstate->current, param_field) + +#define ELEM_CLOSE_REQUIRE_ATTR_PARENT(type,attr_name,param_field) \ + _ELEM_CLOSE_REQUIRE_ATTR(type, attr_name, pstate->current->parent, param_field) + +#define ELEM_CLOSE_REQUIRE_ATTR_POPULATED(type,type_name,exp_populated) \ + do { \ + if (~(((struct type *) pstate->current)->populated) & exp_populated) \ + { \ + PARSER_ERROR (pstate, line, "Not all params set for %s", type_name); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } \ + } while (0) + + +static int proc_elem_close (void *varg, UNUSED_ARG (uintptr_t eleminfo), UNUSED_ARG (int line)) +{ + struct parse_sysdef_state * const pstate = varg; + int ret = SD_PARSE_RESULT_OK; + if (pstate->current == NULL) { + PARSER_ERROR (pstate, line, "Current element NULL in close element"); + ret = SD_PARSE_RESULT_ERR; + } + else + { + switch (pstate->current->kind) + { + case ELEMENT_KIND_QOS_POLICY_DEADLINE: + ELEM_CLOSE_QOS_POLICY(DEADLINE, "Deadline"); + break; + case ELEMENT_KIND_QOS_POLICY_DEADLINE_PERIOD: + ELEM_CLOSE_QOS_DURATION_PROPERTY(DEADLINE, PERIOD, deadline); + break; + case ELEMENT_KIND_QOS_POLICY_DESTINATIONORDER: + ELEM_CLOSE_QOS_POLICY(DESTINATIONORDER, "Destination Order"); + break; + case ELEMENT_KIND_QOS_POLICY_DURABILITY: + ELEM_CLOSE_QOS_POLICY(DURABILITY, "Durability"); + break; + case ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE: + ELEM_CLOSE_QOS_POLICY(DURABILITYSERVICE, "Durability Service"); + break; + case ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_SERVICE_CLEANUP_DELAY: + ELEM_CLOSE_QOS_DURATION_PROPERTY(DURABILITYSERVICE, SERVICE_CLEANUP_DELAY, service_cleanup_delay); + break; + case ELEMENT_KIND_QOS_POLICY_GROUPDATA: + ELEM_CLOSE_QOS_POLICY(GROUPDATA, "Group Data"); + break; + case ELEMENT_KIND_QOS_POLICY_HISTORY: + ELEM_CLOSE_QOS_POLICY(HISTORY, "History"); + break; + case ELEMENT_KIND_QOS_POLICY_LATENCYBUDGET: + ELEM_CLOSE_QOS_POLICY(LATENCYBUDGET, "Latency Budget"); + break; + case ELEMENT_KIND_QOS_POLICY_LATENCYBUDGET_DURATION: + ELEM_CLOSE_QOS_DURATION_PROPERTY(LATENCYBUDGET, DURATION, duration); + break; + case ELEMENT_KIND_QOS_POLICY_LIFESPAN: + ELEM_CLOSE_QOS_POLICY(LIFESPAN, "Lifespan"); + break; + case ELEMENT_KIND_QOS_POLICY_LIFESPAN_DURATION: + ELEM_CLOSE_QOS_DURATION_PROPERTY(LIFESPAN, DURATION, duration); + break; + case ELEMENT_KIND_QOS_POLICY_LIVELINESS: + ELEM_CLOSE_QOS_POLICY(LIVELINESS, "Liveliness"); + break; + case ELEMENT_KIND_QOS_POLICY_LIVELINESS_LEASE_DURATION: + ELEM_CLOSE_QOS_DURATION_PROPERTY(LIVELINESS, LEASE_DURATION, lease_duration); + break; + case ELEMENT_KIND_QOS_POLICY_OWNERSHIP: + ELEM_CLOSE_QOS_POLICY(OWNERSHIP, "Ownership"); + break; + case ELEMENT_KIND_QOS_POLICY_OWNERSHIPSTRENGTH: + ELEM_CLOSE_QOS_POLICY(OWNERSHIPSTRENGTH, "Ownership Strength"); + break; + case ELEMENT_KIND_QOS_POLICY_PARTITION: + ELEM_CLOSE_QOS_POLICY(PARTITION, "Partition"); + break; + case ELEMENT_KIND_QOS_POLICY_PRESENTATION: + ELEM_CLOSE_QOS_POLICY(PRESENTATION, "Presentation"); + break; + case ELEMENT_KIND_QOS_POLICY_READERDATALIFECYCLE_AUTOPURGE_NOWRITER_SAMPLES_DELAY: + ELEM_CLOSE_QOS_DURATION_PROPERTY(READERDATALIFECYCLE, AUTOPURGE_NOWRITER_SAMPLES_DELAY, autopurge_nowriter_samples_delay); + break; + case ELEMENT_KIND_QOS_POLICY_READERDATALIFECYCLE_AUTOPURGE_DISPOSED_SAMPLES_DELAY: + ELEM_CLOSE_QOS_DURATION_PROPERTY(READERDATALIFECYCLE, AUTOPURGE_DISPOSED_SAMPLES_DELAY, autopurge_disposed_samples_delay); + break; + case ELEMENT_KIND_QOS_POLICY_READERDATALIFECYCLE: + ELEM_CLOSE_QOS_POLICY(READERDATALIFECYCLE, "Reader Data Life-cycle"); + break; + case ELEMENT_KIND_QOS_POLICY_RELIABILITY: + ELEM_CLOSE_QOS_POLICY(RELIABILITY, "Reliability"); + break; + case ELEMENT_KIND_QOS_POLICY_RELIABILITY_MAX_BLOCKING_DELAY: + ELEM_CLOSE_QOS_DURATION_PROPERTY(RELIABILITY, MAX_BLOCKING_DELAY, max_blocking_time); + break; + case ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS: + ELEM_CLOSE_QOS_POLICY(RESOURCELIMITS, "Resource Limits"); + break; + case ELEMENT_KIND_QOS_POLICY_TIMEBASEDFILTER_MINIMUM_SEPARATION: + ELEM_CLOSE_QOS_DURATION_PROPERTY(TIMEBASEDFILTER, MINIMUM_SEPARATION, minimum_separation); + break; + case ELEMENT_KIND_QOS_POLICY_TIMEBASEDFILTER: + ELEM_CLOSE_QOS_POLICY(TIMEBASEDFILTER, "Time-based Filter"); + break; + case ELEMENT_KIND_QOS_POLICY_TOPICDATA: + ELEM_CLOSE_QOS_POLICY(TOPICDATA, "Topic Data"); + break; + case ELEMENT_KIND_QOS_POLICY_TRANSPORTPRIORITY: + ELEM_CLOSE_QOS_POLICY(TRANSPORTPRIORITY, "Transport Priority"); + break; + case ELEMENT_KIND_QOS_POLICY_USERDATA: + ELEM_CLOSE_QOS_POLICY(USERDATA, "User data"); + break; + case ELEMENT_KIND_QOS_POLICY_WRITERDATALIFECYCLE: + ELEM_CLOSE_QOS_POLICY(WRITERDATALIFECYCLE, "Writer Data Life-cycle"); + break; + case ELEMENT_KIND_QOS_POLICY_ENTITYFACTORY: + //ELEM_CLOSE_QOS_POLICY(ENTITYFACTORY, "Entity factory"); + PARSER_ERROR (pstate, line, "Unsupported QoS policy"); + ret = SD_PARSE_RESULT_NOT_SUPPORTED; + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_PERIODICITY: { + struct dds_sysdef_tsn_traffic_specification *t = (struct dds_sysdef_tsn_traffic_specification *) pstate->current->parent; + struct dds_sysdef_qos_duration_property *d = (struct dds_sysdef_qos_duration_property *) pstate->current; + t->periodicity = DDS_SECS (d->sec) + d->nsec; + break; + } + case ELEMENT_KIND_TYPE: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_type, "name", name); + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_type, "identifier", identifier); + break; + case ELEMENT_KIND_QOS_LIB: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_qos_lib, "name", name); + break; + case ELEMENT_KIND_QOS_PROFILE: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_qos_profile, "name", name); + break; + case ELEMENT_KIND_DOMAIN_LIB: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_domain_lib, "name", name); + break; + case ELEMENT_KIND_DOMAIN: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_domain, "name", name); + ELEM_CLOSE_REQUIRE_ATTR_POPULATED (dds_sysdef_domain, "domain", SYSDEF_DOMAIN_PARAMS); + break; + case ELEMENT_KIND_PARTICIPANT: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_participant, "name", name); + break; + case ELEMENT_KIND_REGISTER_TYPE: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_register_type, "name", name); + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_register_type, "type_ref", type_ref); + break; + case ELEMENT_KIND_PARTICIPANT_LIB: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_participant, "name", name); + break; + case ELEMENT_KIND_TOPIC: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_topic, "name", name); + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_topic, "register_type_ref", register_type_ref); + break; + case ELEMENT_KIND_PUBLISHER: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_publisher, "name", name); + break; + case ELEMENT_KIND_SUBSCRIBER: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_subscriber, "name", name); + break; + case ELEMENT_KIND_WRITER: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_writer, "name", name); + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_writer, "topic_ref", topic); + ELEM_CLOSE_REQUIRE_ATTR_POPULATED (dds_sysdef_writer, "writer", SYSDEF_WRITER_PARAMS); + break; + case ELEMENT_KIND_READER: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_reader, "name", name); + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_reader, "topic_ref", topic); + ELEM_CLOSE_REQUIRE_ATTR_POPULATED (dds_sysdef_reader, "reader", SYSDEF_READER_PARAMS); + break; + case ELEMENT_KIND_APPLICATION_LIB: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_application_lib, "name", name); + break; + case ELEMENT_KIND_APPLICATION: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_application, "name", name); + break; + case ELEMENT_KIND_DEPLOYMENT_NODE_REF: + ELEM_CLOSE_REQUIRE_ATTR_PARENT (dds_sysdef_deployment, "node_ref", node); + break; + case ELEMENT_KIND_DEPLOYMENT_APPLICATION_REF: + ELEM_CLOSE_REQUIRE_ATTR (dds_sysdef_application_ref, "application_ref", application); + break; + default: + if (pstate->current->handle_close) + { + PARSER_ERROR (pstate, line, "Close element not handled"); + ret = SD_PARSE_RESULT_ERR; + } + break; + } + } + + struct xml_element *parent = pstate->current->parent; + if (!pstate->current->retain) { + free_node (pstate->current); + } + pstate->current = parent; + return ret; +} + +#define QOS_PARAM_SET_NUMERIC_UNLIMITED(policy, param, param_field, type) \ + static int set_ ## policy ## _ ## param (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_ ## policy *qp, const char *value, int line) \ + { \ + int ret = SD_PARSE_RESULT_OK; \ + type ## _t s; \ + if (!strcmp(value, QOS_LENGTH_UNLIMITED)){ \ + qp->values.param_field = -1; \ + } else if (str_to_ ## type (value, &s)) { \ + qp->values.param_field = s; \ + } else { \ + PARSER_ERROR (pstate, line, "Invalid value '%s'", value); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } \ + return ret; \ + } + +#define QOS_PARAM_SET_NUMERIC(policy, param, param_field, type) \ + static int set_ ## policy ## _ ## param (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_ ## policy *qp, const char *value, int line) \ + { \ + int ret = SD_PARSE_RESULT_OK; \ + type ## _t s; \ + if (str_to_ ## type (value, &s)) { \ + qp->values.param_field = s; \ + } else { \ + PARSER_ERROR (pstate, line, "Invalid value '%s'", value); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } \ + return ret; \ + } + +#define QOS_PARAM_SET_BOOLEAN(policy, param, param_field) \ + static int set_ ## policy ## _ ## param (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_ ## policy *qp, const char *value, int line) \ + { \ + int ret = SD_PARSE_RESULT_OK; \ + bool s; \ + if (str_to_bool (value, &s)) { \ + qp->values.param_field = s; \ + } else { \ + PARSER_ERROR (pstate, line, "Invalid value '%s'", value); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } \ + return ret; \ + } + +#define QOS_PARAM_SET_STRING(policy, param, param_field) \ + static int set_ ## policy ## _ ## param (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_ ## policy *qp, const char *value, int line) \ + { \ + qp->values.param_field = ddsrt_strdup (value); \ + return SD_PARSE_RESULT_OK; \ + } + +#define QOS_PARAM_SET_BASE64(policy, param, param_data_field, param_length_field) \ + static int set_ ## policy ## _ ## param (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_ ## policy *qp, const char *value, int line) \ + { \ + (void) pstate; (void) line; \ + /* FIXME: base 64 decode */ \ + qp->values.param_data_field = ddsrt_memdup (value, strlen (value)); \ + qp->values.param_length_field = (uint32_t) strlen (value); \ + return SD_PARSE_RESULT_OK; \ + } + +static int set_DESTINATIONORDER_KIND (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_DESTINATIONORDER *qp, const char *value, int line) +{ + int ret = SD_PARSE_RESULT_OK; + if (strcmp (value, "BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS") == 0) { + qp->values.kind = DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP; + } else if (strcmp (value, "BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS") == 0) { + qp->values.kind = DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP; + } else { + PARSER_ERROR (pstate, line, "Invalid value '%s'", value); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + return ret; +} + +static int set_DURABILITY_KIND (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_DURABILITY *qp, const char *value, int line) +{ + int ret = SD_PARSE_RESULT_OK; + if (strcmp (value, "VOLATILE_DURABILITY_QOS") == 0) { + qp->values.kind = DDS_DURABILITY_VOLATILE; + } else if (strcmp (value, "TRANSIENT_LOCAL_DURABILITY_QOS") == 0) { + qp->values.kind = DDS_DURABILITY_TRANSIENT_LOCAL; + } else if (strcmp (value, "TRANSIENT_DURABILITY_QOS") == 0) { + qp->values.kind = DDS_DURABILITY_TRANSIENT; + } else if (strcmp (value, "PERSISTENT_DURABILITY_QOS") == 0) { + PARSER_ERROR (pstate, line, "Unsupported value '%s'", value); + ret = SD_PARSE_RESULT_NOT_SUPPORTED; + } else { + PARSER_ERROR (pstate, line, "Invalid value '%s'", value); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + return ret; +} + +static int set_DURABILITYSERVICE_HISTORY_KIND (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_DURABILITYSERVICE *qp, const char *value, int line) +{ + int ret = SD_PARSE_RESULT_OK; + if (strcmp (value, "KEEP_LAST_HISTORY_QOS") == 0) { + qp->values.history.kind = DDS_HISTORY_KEEP_LAST; + } else if (strcmp (value, "KEEP_ALL_HISTORY_QOS") == 0) { + qp->values.history.kind = DDS_HISTORY_KEEP_ALL; + } else { + PARSER_ERROR (pstate, line, "Invalid value '%s'", value); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + return ret; +} + +static int set_HISTORY_KIND (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_HISTORY *qp, const char *value, int line) +{ + int ret = SD_PARSE_RESULT_OK; + if (strcmp (value, "KEEP_LAST_HISTORY_QOS") == 0) { + qp->values.kind = DDS_HISTORY_KEEP_LAST; + } else if (strcmp (value, "KEEP_ALL_HISTORY_QOS") == 0) { + qp->values.kind = DDS_HISTORY_KEEP_ALL; + } else { + PARSER_ERROR (pstate, line, "Invalid value '%s'", value); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + return ret; +} + +static int set_LIVELINESS_KIND (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_LIVELINESS *qp, const char *value, int line) +{ + int ret = SD_PARSE_RESULT_OK; + if (strcmp (value, "AUTOMATIC_LIVELINESS_QOS") == 0) { + qp->values.kind = DDS_LIVELINESS_AUTOMATIC; + } else if (strcmp (value, "MANUAL_BY_PARTICIPANT_LIVELINESS_QOS") == 0) { + qp->values.kind = DDS_LIVELINESS_MANUAL_BY_PARTICIPANT; + } else if (strcmp (value, "MANUAL_BY_TOPIC_LIVELINESS_QOS") == 0) { + qp->values.kind = DDS_LIVELINESS_MANUAL_BY_TOPIC; + } else { + PARSER_ERROR (pstate, line, "Invalid value '%s'", value); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + return ret; +} + +static int set_OWNERSHIP_KIND (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_OWNERSHIP *qp, const char *value, int line) +{ + int ret = SD_PARSE_RESULT_OK; + if (strcmp (value, "SHARED_OWNERSHIP_QOS") == 0) { + qp->values.kind = DDS_OWNERSHIP_SHARED; + } else if (strcmp (value, "EXCLUSIVE_OWNERSHIP_QOS") == 0) { + qp->values.kind = DDS_OWNERSHIP_EXCLUSIVE; + } else { + PARSER_ERROR (pstate, line, "Invalid value '%s'", value); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + return ret; +} + +static int set_PRESENTATION_ACCESS_SCOPE (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_PRESENTATION *qp, const char *value, int line) +{ + int ret = SD_PARSE_RESULT_OK; + if (strcmp (value, "INSTANCE_PRESENTATION_QOS") == 0) { + qp->values.access_scope = DDS_PRESENTATION_INSTANCE; + } else if (strcmp (value, "TOPIC_PRESENTATION_QOS") == 0) { + qp->values.access_scope = DDS_PRESENTATION_TOPIC; + } else if (strcmp (value, "GROUP_PRESENTATION_QOS") == 0) { + qp->values.access_scope = DDS_PRESENTATION_GROUP; + } else { + PARSER_ERROR (pstate, line, "Invalid value '%s'", value); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + return ret; +} + +static int set_RELIABILITY_KIND (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_RELIABILITY *qp, const char *value, int line) +{ + int ret = SD_PARSE_RESULT_OK; + if (strcmp (value, "BEST_EFFORT_RELIABILITY_QOS") == 0) { + qp->values.kind = DDS_RELIABILITY_BEST_EFFORT; + } else if (strcmp (value, "RELIABLE_RELIABILITY_QOS") == 0) { + qp->values.kind = DDS_RELIABILITY_RELIABLE; + } else { + PARSER_ERROR (pstate, line, "Invalid value '%s'", value); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + return ret; +} + +QOS_PARAM_SET_NUMERIC(DURABILITYSERVICE, HISTORY_DEPTH, history.depth, int32) +QOS_PARAM_SET_NUMERIC_UNLIMITED(DURABILITYSERVICE, RESOURCE_LIMIT_MAX_SAMPLES, resource_limits.max_samples, int32) +QOS_PARAM_SET_NUMERIC_UNLIMITED(DURABILITYSERVICE, RESOURCE_LIMIT_MAX_INSTANCES, resource_limits.max_instances, int32) +QOS_PARAM_SET_NUMERIC_UNLIMITED(DURABILITYSERVICE, RESOURCE_LIMIT_MAX_SAMPLES_PER_INSTANCE, resource_limits.max_samples_per_instance, int32) +QOS_PARAM_SET_BOOLEAN(ENTITYFACTORY, AUTOENABLE_CREATED_ENTITIES, autoenable_created_entities) +QOS_PARAM_SET_NUMERIC(HISTORY, DEPTH, depth, int32) +QOS_PARAM_SET_NUMERIC(OWNERSHIPSTRENGTH, VALUE, value, int32) +QOS_PARAM_SET_BOOLEAN(PRESENTATION, COHERENT_ACCESS, coherent_access) +QOS_PARAM_SET_BOOLEAN(PRESENTATION, ORDERED_ACCESS, ordered_access) +QOS_PARAM_SET_NUMERIC_UNLIMITED(RESOURCELIMITS, MAX_SAMPLES, max_samples, int32) +QOS_PARAM_SET_NUMERIC_UNLIMITED(RESOURCELIMITS, MAX_INSTANCES, max_instances, int32) +QOS_PARAM_SET_NUMERIC_UNLIMITED(RESOURCELIMITS, MAX_SAMPLES_PER_INSTANCE, max_samples_per_instance, int32) +QOS_PARAM_SET_NUMERIC(TRANSPORTPRIORITY, VALUE, value, int32) +QOS_PARAM_SET_BOOLEAN(WRITERDATALIFECYCLE, AUTODISPOSE_UNREGISTERED_INSTANCES, autodispose_unregistered_instances) +QOS_PARAM_SET_BASE64(GROUPDATA, VALUE, value, length) +QOS_PARAM_SET_BASE64(TOPICDATA, VALUE, value, length) +QOS_PARAM_SET_BASE64(USERDATA, VALUE, value, length) + +static int parse_tsn_traffic_transmission_selection (struct parse_sysdef_state * const pstate, enum dds_sysdef_tsn_traffic_transmission_selection *s, const char *value, int line) +{ + int ret = SD_PARSE_RESULT_OK; + if (strcmp (value, "STRICT_PRIORITY") == 0) { + *s = DDS_SYSDEF_TSN_TRAFFIC_TRANSMISSION_STRICT_PRIORITY; + } else if (strcmp (value, "CREDIT_BASED_SHAPER") == 0) { + *s = DDS_SYSDEF_TSN_TRAFFIC_TRANSMISSION_CREDIT_BASED_SHAPER; + } else if (strcmp (value, "ENHANCED_TRANSMISSION_SELECTION") == 0) { + *s = DDS_SYSDEF_TSN_TRAFFIC_TRANSMISSION_ENHANCED_TRANSMISSION_SELECTION; + } else if (strcmp (value, "ATS_TRANSMISSION_SELECTION") == 0) { + *s = DDS_SYSDEF_TSN_TRAFFIC_TRANSMISSION_ATS_TRANSMISSION_SELECTION; + } else { + PARSER_ERROR (pstate, line, "Invalid value '%s'", value); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + return ret; +} + +#define QOS_PARAM_DATA(policy,param) \ + do { \ + struct dds_sysdef_QOS_POLICY_ ## policy *qp = (struct dds_sysdef_QOS_POLICY_ ## policy *) pstate->current->parent; \ + assert (qp->xmlnode.kind == ELEMENT_KIND_QOS_POLICY_ ## policy); \ + if (qp->populated & QOS_POLICY_ ## policy ## _PARAM_ ## param) { \ + PARSER_ERROR (pstate, line, "Parameter '%s' already set", STR(param)); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } else { \ + ret = set_## policy ## _ ## param (pstate, qp, value, line); \ + qp->populated |= QOS_POLICY_ ## policy ## _PARAM_ ## param; \ + } \ + } while (0) + +#define PARENT_PARAM_DATA_STRING(parent_kind, parent_type, param_field) \ + do { \ + assert (pstate->current->parent->kind == parent_kind); \ + struct parent_type *parent = (struct parent_type *) pstate->current->parent; \ + if (parent->param_field != NULL) { \ + PARSER_ERROR (pstate, line, "Parameter '%s' already set", STR(param_field)); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } else { \ + parent->param_field = ddsrt_strdup (value); \ + } \ + } while (0) + +#define PARENT_PARAM_DATA_NUMERIC(parent_kind, parent_type, type, param_field, param_populated_bit) \ + do { \ + assert (pstate->current->parent->kind == parent_kind); \ + struct parent_type *parent = (struct parent_type *) pstate->current->parent; \ + if (parent->populated & param_populated_bit) { \ + PARSER_ERROR (pstate, line, "Parameter '%s' already set", STR(param_field)); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } else { \ + type ## _t s; \ + if (str_to_ ## type (value, &s)) { \ + parent->param_field = s; \ + parent->populated |= param_populated_bit; \ + } else { \ + PARSER_ERROR (pstate, line, "Invalid value '%s'", value); \ + ret = SD_PARSE_RESULT_SYNTAX_ERR; \ + } \ + } \ + } while (0) + + + +static int parse_mac_addr (const char *value, struct dds_sysdef_mac_addr **mac_addr) +{ + DDSRT_STATIC_ASSERT (sizeof ((*mac_addr)->addr) == 6); + if (strlen (value) != 17 || value[2] != ':' || value[5] != ':' || value[8] != ':' || value[11] != ':' || value[14] != ':') + return SD_PARSE_RESULT_ERR; + + *mac_addr = ddsrt_malloc (sizeof (**mac_addr)); + char v[13] = {'\0'}; + for (uint32_t i = 0; i < 6; i++) + memcpy (v + 2 * i, value + 3 * i, 2); + v[12] = '\0'; + + if (dds_sysdef_parse_hex (v, (*mac_addr)->addr) != SD_PARSE_RESULT_OK) + return SD_PARSE_RESULT_ERR; + return SD_PARSE_RESULT_OK; +} + +static int parse_ipv4_addr (const char *value, struct dds_sysdef_ip_addr **ipv4_addr) +{ + *ipv4_addr = ddsrt_malloc (sizeof (**ipv4_addr)); + if (ddsrt_sockaddrfromstr (AF_INET, value, (struct sockaddr *) &(*ipv4_addr)->addr) != 0) + return SD_PARSE_RESULT_ERR; + return SD_PARSE_RESULT_OK; +} + +static int parse_ipv6_addr (const char *value, struct dds_sysdef_ip_addr **ipv6_addr) +{ + *ipv6_addr = ddsrt_malloc (sizeof (**ipv6_addr)); + if (ddsrt_sockaddrfromstr (AF_INET6, value, (struct sockaddr *) &(*ipv6_addr)->addr) != 0) + return SD_PARSE_RESULT_ERR; + return SD_PARSE_RESULT_OK; +} + +static int proc_elem_data (void *varg, UNUSED_ARG (uintptr_t eleminfo), const char *value, int line) +{ + struct parse_sysdef_state * const pstate = varg; + int ret = SD_PARSE_RESULT_OK; + if (pstate == NULL) { + return SD_PARSE_RESULT_ERR; + } + + if (!pstate->current) { + PARSER_ERROR (pstate, line, "Current element NULL in processing element data"); + return SD_PARSE_RESULT_ERR; + } + + switch (pstate->current->kind) + { + case ELEMENT_KIND_QOS_DURATION_SEC: + case ELEMENT_KIND_QOS_DURATION_NSEC: { + assert (pstate->current->parent->data_type == ELEMENT_DATA_TYPE_DURATION); + struct dds_sysdef_qos_duration_property *qp = (struct dds_sysdef_qos_duration_property *) pstate->current->parent; + int64_t v; + bool res = true; + if ((pstate->current->kind == ELEMENT_KIND_QOS_DURATION_SEC && (!strcmp(value, QOS_DURATION_INFINITY) || !strcmp(value, QOS_DURATION_INFINITY_SEC))) || + (pstate->current->kind == ELEMENT_KIND_QOS_DURATION_NSEC && (!strcmp(value, QOS_DURATION_INFINITY) || !strcmp(value, QOS_DURATION_INFINITY_NSEC)))) + v = DDS_INFINITY; + else + res = str_to_int64(value, &v); + + if (res) + { + if (qp->populated & (pstate->current->kind == ELEMENT_KIND_QOS_DURATION_SEC ? QOS_DURATION_PARAM_SEC : QOS_DURATION_PARAM_NSEC)) + { + PARSER_ERROR (pstate, line, "Already set"); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + else + { + if (pstate->current->kind == ELEMENT_KIND_QOS_DURATION_SEC && (v != DDS_INFINITY)) { + qp->sec = v; + } else { + qp->nsec = v; + } + qp->populated |= (pstate->current->kind == ELEMENT_KIND_QOS_DURATION_SEC ? QOS_DURATION_PARAM_SEC : QOS_DURATION_PARAM_NSEC); + } + } + else + { + PARSER_ERROR (pstate, line, "Invalid value '%s'", value); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + break; + } + case ELEMENT_KIND_QOS_POLICY_DESTINATIONORDER_KIND: + QOS_PARAM_DATA (DESTINATIONORDER, KIND); + break; + case ELEMENT_KIND_QOS_POLICY_DURABILITY_KIND: + QOS_PARAM_DATA (DURABILITY, KIND); + break; + case ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_HISTORY_KIND: + QOS_PARAM_DATA (DURABILITYSERVICE, HISTORY_KIND); + break; + case ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_HISTORY_DEPTH: + QOS_PARAM_DATA (DURABILITYSERVICE, HISTORY_DEPTH); + break; + case ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_RESOURCE_LIMIT_MAX_SAMPLES: + QOS_PARAM_DATA (DURABILITYSERVICE, RESOURCE_LIMIT_MAX_SAMPLES); + break; + case ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_RESOURCE_LIMIT_MAX_INSTANCES: + QOS_PARAM_DATA (DURABILITYSERVICE, RESOURCE_LIMIT_MAX_INSTANCES); + break; + case ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_RESOURCE_LIMIT_MAX_SAMPLES_PER_INSTANCE: + QOS_PARAM_DATA (DURABILITYSERVICE, RESOURCE_LIMIT_MAX_SAMPLES_PER_INSTANCE); + break; + case ELEMENT_KIND_QOS_POLICY_ENTITYFACTORY_AUTOENABLE_CREATED_ENTITIES: + QOS_PARAM_DATA (ENTITYFACTORY, AUTOENABLE_CREATED_ENTITIES); + break; + case ELEMENT_KIND_QOS_POLICY_GROUPDATA_VALUE: + QOS_PARAM_DATA (GROUPDATA, VALUE); + break; + case ELEMENT_KIND_QOS_POLICY_HISTORY_KIND: + QOS_PARAM_DATA (HISTORY, KIND); + break; + case ELEMENT_KIND_QOS_POLICY_HISTORY_DEPTH: + QOS_PARAM_DATA (HISTORY, DEPTH); + break; + case ELEMENT_KIND_QOS_POLICY_LIVELINESS_KIND: + QOS_PARAM_DATA (LIVELINESS, KIND); + break; + case ELEMENT_KIND_QOS_POLICY_OWNERSHIP_KIND: + QOS_PARAM_DATA (OWNERSHIP, KIND); + break; + case ELEMENT_KIND_QOS_POLICY_OWNERSHIPSTRENGTH_VALUE: + QOS_PARAM_DATA (OWNERSHIPSTRENGTH, VALUE); + break; + case ELEMENT_KIND_QOS_POLICY_PARTITION_NAME_ELEMENT: { + struct dds_sysdef_QOS_POLICY_PARTITION *qp = (struct dds_sysdef_QOS_POLICY_PARTITION *) pstate->current->parent->parent; + struct dds_sysdef_QOS_POLICY_PARTITION_NAME_ELEMENT *p = (struct dds_sysdef_QOS_POLICY_PARTITION_NAME_ELEMENT *) pstate->current; + if (dds_sysdef_is_valid_identifier_syntax (value)) + { + p->element = ddsrt_strdup (value); + qp->populated = true; + } + else + { + // free_node (qp); + // pstate->current = NULL; + PARSER_ERROR (pstate, line, "Invalid partition name '%s'", value); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + break; + } + case ELEMENT_KIND_QOS_POLICY_RELIABILITY_KIND: + QOS_PARAM_DATA (RELIABILITY, KIND); + break; + case ELEMENT_KIND_QOS_POLICY_PRESENTATION_ACCESS_SCOPE: + QOS_PARAM_DATA (PRESENTATION, ACCESS_SCOPE); + break; + case ELEMENT_KIND_QOS_POLICY_PRESENTATION_COHERENT_ACCESS: + QOS_PARAM_DATA (PRESENTATION, COHERENT_ACCESS); + break; + case ELEMENT_KIND_QOS_POLICY_PRESENTATION_ORDERED_ACCESS: + QOS_PARAM_DATA (PRESENTATION, ORDERED_ACCESS); + break; + // case ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_INITIAL_INSTANCES: + // QOS_PARAM_DATA (RESOURCELIMITS, INITIAL_INSTANCES); + // break; + // case ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_INITIAL_SAMPLES: + // QOS_PARAM_DATA (RESOURCELIMITS, INITIAL_SAMPLES); + // break; + case ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_MAX_SAMPLES: + QOS_PARAM_DATA (RESOURCELIMITS, MAX_SAMPLES); + break; + case ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_MAX_INSTANCES: + QOS_PARAM_DATA (RESOURCELIMITS, MAX_INSTANCES); + break; + case ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_MAX_SAMPLES_PER_INSTANCE: + QOS_PARAM_DATA (RESOURCELIMITS, MAX_SAMPLES_PER_INSTANCE); + break; + case ELEMENT_KIND_QOS_POLICY_TOPICDATA_VALUE: + QOS_PARAM_DATA (TOPICDATA, VALUE); + break; + case ELEMENT_KIND_QOS_POLICY_TRANSPORTPRIORITY_VALUE: + QOS_PARAM_DATA (TRANSPORTPRIORITY, VALUE); + break; + case ELEMENT_KIND_QOS_POLICY_WRITERDATALIFECYCLE_AUTODISPOSE_UNREGISTERED_INSTANCES: + QOS_PARAM_DATA (WRITERDATALIFECYCLE, AUTODISPOSE_UNREGISTERED_INSTANCES); + break; + case ELEMENT_KIND_QOS_POLICY_USERDATA_VALUE: + QOS_PARAM_DATA (USERDATA, VALUE); + break; + case ELEMENT_KIND_NODE_HOSTNAME: + PARENT_PARAM_DATA_STRING(ELEMENT_KIND_NODE, dds_sysdef_node, hostname); + break; + case ELEMENT_KIND_NODE_IPV4_ADDRESS: { + assert (pstate->current->parent->kind == ELEMENT_KIND_NODE); + struct dds_sysdef_node *node = (struct dds_sysdef_node *) pstate->current->parent; + if (node->ipv4_addr != NULL) + { + PARSER_ERROR (pstate, line, "Parameter 'ipv4_addr' already set"); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + else if (parse_ipv4_addr (value, &node->ipv4_addr) != SD_PARSE_RESULT_OK) + { + PARSER_ERROR (pstate, line, "Invalid value for parameter 'ipv4_addr'"); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + break; + } + case ELEMENT_KIND_NODE_IPV6_ADDRESS: { + assert (pstate->current->parent->kind == ELEMENT_KIND_NODE); + struct dds_sysdef_node *node = (struct dds_sysdef_node *) pstate->current->parent; + if (node->ipv6_addr != NULL) + { + PARSER_ERROR (pstate, line, "Parameter 'ipv6_addr' already set"); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + else if (parse_ipv6_addr (value, &node->ipv6_addr) != SD_PARSE_RESULT_OK) + { + PARSER_ERROR (pstate, line, "Invalid value for parameter 'ipv6_addr'"); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + break; + } + case ELEMENT_KIND_NODE_MAC_ADDRESS: { + assert (pstate->current->parent->kind == ELEMENT_KIND_NODE); + struct dds_sysdef_node *node = (struct dds_sysdef_node *) pstate->current->parent; + if (node->mac_addr != NULL) + { + PARSER_ERROR (pstate, line, "Parameter 'mac_addr' already set"); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + else if (parse_mac_addr (value, &node->mac_addr) != SD_PARSE_RESULT_OK) + { + PARSER_ERROR (pstate, line, "Invalid value for parameter 'mac_addr'"); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + break; + } + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_SOURCE_IP_ADDRESS: + PARENT_PARAM_DATA_STRING(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, dds_sysdef_tsn_ip_tuple, source_ip_address); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_DESTINATION_IP_ADDRESS: + PARENT_PARAM_DATA_STRING(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, dds_sysdef_tsn_ip_tuple, destination_ip_address); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_DSCP: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, dds_sysdef_tsn_ip_tuple, uint8, dscp, SYSDEF_TSN_IP_TUPLE_DSCP_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_PROTOCOL: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, dds_sysdef_tsn_ip_tuple, uint16, protocol, SYSDEF_TSN_IP_TUPLE_PROTOCOL_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_SOURCE_PORT: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, dds_sysdef_tsn_ip_tuple, uint16, source_port, SYSDEF_TSN_IP_TUPLE_SOURCE_PORT_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_DESTINATION_PORT: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, dds_sysdef_tsn_ip_tuple, uint16, destination_port, SYSDEF_TSN_IP_TUPLE_DESTINATION_PORT_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_SOURCE_IP_ADDRESS: + PARENT_PARAM_DATA_STRING(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, dds_sysdef_tsn_ip_tuple, source_ip_address); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_DESTINATION_IP_ADDRESS: + PARENT_PARAM_DATA_STRING(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, dds_sysdef_tsn_ip_tuple, destination_ip_address); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_DSCP: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, dds_sysdef_tsn_ip_tuple, uint8, dscp, SYSDEF_TSN_IP_TUPLE_DSCP_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_PROTOCOL: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, dds_sysdef_tsn_ip_tuple, uint16, protocol, SYSDEF_TSN_IP_TUPLE_PROTOCOL_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_SOURCE_PORT: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, dds_sysdef_tsn_ip_tuple, uint16, source_port, SYSDEF_TSN_IP_TUPLE_SOURCE_PORT_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_DESTINATION_PORT: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, dds_sysdef_tsn_ip_tuple, uint16, destination_port, SYSDEF_TSN_IP_TUPLE_DESTINATION_PORT_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_SAMPLES_PER_PERIOD: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC, dds_sysdef_tsn_traffic_specification, uint16, samples_per_period, SYSDEF_TSN_TRAFFIC_SPEC_SAMPLES_PER_PERIOD_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_MAX_BYTES_PER_SAMPLE: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC, dds_sysdef_tsn_traffic_specification, uint16, max_bytes_per_sample, SYSDEF_TSN_TRAFFIC_SPEC_MAX_BYTES_PER_SAMPLE_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TRANSMISSION_SELECTION: { + assert (pstate->current->parent->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC); + struct dds_sysdef_tsn_traffic_specification *parent = (struct dds_sysdef_tsn_traffic_specification *) pstate->current->parent; + if (parent->populated & SYSDEF_TSN_TRAFFIC_SPEC_TRANSMISSION_SELECTION_PARAM_VALUE) + { + PARSER_ERROR (pstate, line, "Parameter 'transmission_selection' already set"); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + else + { + enum dds_sysdef_tsn_traffic_transmission_selection s; + if ((ret = parse_tsn_traffic_transmission_selection (pstate, &s, value, line)) == SD_PARSE_RESULT_OK) { + parent->transmission_selection = s; + parent->populated |= SYSDEF_TSN_TRAFFIC_SPEC_TRANSMISSION_SELECTION_PARAM_VALUE; + } + } + break; + } + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE_EARLIEST_TRANSMIT_OFFSET: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE, dds_sysdef_tsn_time_aware, uint32, earliest_transmit_offset, SYSDEF_TSN_TIME_AWARE_EARLIEST_TRANSMIT_OFFSET_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE_LATEST_TRANSMIT_OFFSET: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE, dds_sysdef_tsn_time_aware, uint32, latest_transmit_offset, SYSDEF_TSN_TIME_AWARE_LATEST_TRANSMIT_OFFSET_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE_JITTER: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE, dds_sysdef_tsn_time_aware, uint32, jitter, SYSDEF_TSN_TIME_JITTER_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_NETWORK_REQUIREMENTS_NUM_SEAMLESS_TREES: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_NETWORK_REQUIREMENTS, dds_sysdef_tsn_network_requirements, uint8, num_seamless_trees, SYSDEF_TSN_NETWORK_REQ_NUM_SEAMLESS_TREES_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_NETWORK_REQUIREMENTS_MAX_LATENCY: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_NETWORK_REQUIREMENTS, dds_sysdef_tsn_network_requirements, uint32, max_latency, SYSDEF_TSN_NETWORK_REQ_MAX_LATENCY_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER_NETWORK_REQUIREMENTS_NUM_SEAMLESS_TREES: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER_NETWORK_REQUIREMENTS, dds_sysdef_tsn_network_requirements, uint8, num_seamless_trees, SYSDEF_TSN_NETWORK_REQ_NUM_SEAMLESS_TREES_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER_NETWORK_REQUIREMENTS_MAX_LATENCY: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER_NETWORK_REQUIREMENTS, dds_sysdef_tsn_network_requirements, uint32, max_latency, SYSDEF_TSN_NETWORK_REQ_MAX_LATENCY_PARAM_VALUE); + break; + default: + PARSER_ERROR (pstate, line, "Element data not allowed"); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + break; + } + + if (ret != SD_PARSE_RESULT_OK) + { + struct xml_element *n = pstate->current, *tmp; + while (n != NULL) + { + tmp = n->parent; + if (!n->retain) + free_node (n); + n = tmp; + } + } + + return ret; +} + +#define PARSER_ERROR_INVALID_PARENT_KIND() \ + do { \ + PARSER_ERROR (pstate, line, "Invalid parent kind (%d) for element '%s'", pstate->current->kind, name); \ + return SD_PARSE_RESULT_SYNTAX_ERR; \ + } while (0) + +static int proc_elem_open (void *varg, UNUSED_ARG (uintptr_t parentinfo), UNUSED_ARG (uintptr_t *eleminfo), const char *name, int line) +{ + if (varg == NULL) + return SD_PARSE_RESULT_ERR; + + struct parse_sysdef_state * const pstate = varg; + int ret = SD_PARSE_RESULT_OK; + + if (ddsrt_strcasecmp (name, "dds") == 0) + { + if (pstate->current != NULL || pstate->sysdef != NULL) { + PARSER_ERROR (pstate, line, "Nested element '%s' not supported", name); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + else if ((pstate->current = new_node (pstate, ELEMENT_KIND_DDS, ELEMENT_DATA_TYPE_GENERIC, NULL, sizeof(struct dds_sysdef_system), NO_INIT, fini_sysdef)) == NULL) + { + PARSER_ERROR (pstate, line, "Error creating root node"); + ret = SD_PARSE_RESULT_ERR; + } + else + { + pstate->sysdef = (struct dds_sysdef_system *) pstate->current; + goto status_ok; + } + } + else + { + CHECK_PARENT_NULL (pstate, pstate->current); + if (pstate->scope & SYSDEF_SCOPE_TYPE_LIB) + { + // Type library + if (ddsrt_strcasecmp (name, "types") == 0) + CREATE_NODE_SINGLE (pstate, dds_sysdef_type_lib, ELEMENT_KIND_TYPE_LIB, NO_INIT, fini_type_lib, type_libs, dds_sysdef_system, ELEMENT_KIND_DDS, pstate->current); + else if (ddsrt_strcasecmp (name, "struct") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_type, ELEMENT_KIND_TYPE, NO_INIT, fini_type, types, dds_sysdef_type_lib, ELEMENT_KIND_TYPE_LIB, pstate->current); + } + + if (pstate->scope & SYSDEF_SCOPE_QOS_LIB) + { + // QoS library + if (ddsrt_strcasecmp (name, "qos_library") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_qos_lib, ELEMENT_KIND_QOS_LIB, NO_INIT, fini_qos_lib, qos_libs, dds_sysdef_system, ELEMENT_KIND_DDS, pstate->current); + else if (ddsrt_strcasecmp (name, "qos_profile") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_qos_profile, ELEMENT_KIND_QOS_PROFILE, NO_INIT, fini_qos_profile, qos_profiles, dds_sysdef_qos_lib, ELEMENT_KIND_QOS_LIB, pstate->current); + + else if (ddsrt_strcasecmp (name, "domain_participant_qos") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_QOS_PROFILE) + CREATE_NODE_LIST (pstate, dds_sysdef_qos, ELEMENT_KIND_QOS_PARTICIPANT, init_qos, fini_qos, qos, dds_sysdef_qos_profile, ELEMENT_KIND_QOS_PROFILE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_PARTICIPANT) + CREATE_NODE_SINGLE (pstate, dds_sysdef_qos, ELEMENT_KIND_QOS_PARTICIPANT, init_qos, fini_qos, qos, dds_sysdef_participant, ELEMENT_KIND_PARTICIPANT, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "publisher_qos") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_QOS_PROFILE) + CREATE_NODE_LIST (pstate, dds_sysdef_qos, ELEMENT_KIND_QOS_PUBLISHER, init_qos, fini_qos, qos, dds_sysdef_qos_profile, ELEMENT_KIND_QOS_PROFILE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_PUBLISHER) + CREATE_NODE_SINGLE (pstate, dds_sysdef_qos, ELEMENT_KIND_QOS_PUBLISHER, init_qos, fini_qos, qos, dds_sysdef_publisher, ELEMENT_KIND_PUBLISHER, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "subscriber_qos") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_QOS_PROFILE) + CREATE_NODE_LIST (pstate, dds_sysdef_qos, ELEMENT_KIND_QOS_SUBSCRIBER, init_qos, fini_qos, qos, dds_sysdef_qos_profile, ELEMENT_KIND_QOS_PROFILE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_SUBSCRIBER) + CREATE_NODE_SINGLE (pstate, dds_sysdef_qos, ELEMENT_KIND_QOS_SUBSCRIBER, init_qos, fini_qos, qos, dds_sysdef_subscriber, ELEMENT_KIND_SUBSCRIBER, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "topic_qos") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_QOS_PROFILE) + CREATE_NODE_LIST (pstate, dds_sysdef_qos, ELEMENT_KIND_QOS_TOPIC, init_qos, fini_qos, qos, dds_sysdef_qos_profile, ELEMENT_KIND_QOS_PROFILE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_TOPIC) + CREATE_NODE_SINGLE (pstate, dds_sysdef_qos, ELEMENT_KIND_QOS_TOPIC, init_qos, fini_qos, qos, dds_sysdef_topic, ELEMENT_KIND_TOPIC, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "datawriter_qos") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_QOS_PROFILE) + CREATE_NODE_LIST (pstate, dds_sysdef_qos, ELEMENT_KIND_QOS_WRITER, init_qos, fini_qos, qos, dds_sysdef_qos_profile, ELEMENT_KIND_QOS_PROFILE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_WRITER) + CREATE_NODE_SINGLE (pstate, dds_sysdef_qos, ELEMENT_KIND_QOS_WRITER, init_qos, fini_qos, qos, dds_sysdef_writer, ELEMENT_KIND_WRITER, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "datareader_qos") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_QOS_PROFILE) + CREATE_NODE_LIST (pstate, dds_sysdef_qos, ELEMENT_KIND_QOS_READER, init_qos, fini_qos, qos, dds_sysdef_qos_profile, ELEMENT_KIND_QOS_PROFILE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_READER) + CREATE_NODE_SINGLE (pstate, dds_sysdef_qos, ELEMENT_KIND_QOS_READER, init_qos, fini_qos, qos, dds_sysdef_reader, ELEMENT_KIND_READER, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + + // QoS policies + else if (ddsrt_strcasecmp (name, "deadline") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_DEADLINE, ELEMENT_KIND_QOS_POLICY_DEADLINE, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "destination_order") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_DESTINATIONORDER, ELEMENT_KIND_QOS_POLICY_DESTINATIONORDER, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "durability") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_DURABILITY, ELEMENT_KIND_QOS_POLICY_DURABILITY, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "durability_service") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_DURABILITYSERVICE, ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "entity_factory") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_ENTITYFACTORY, ELEMENT_KIND_QOS_POLICY_ENTITYFACTORY, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "group_data") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_GROUPDATA, ELEMENT_KIND_QOS_POLICY_GROUPDATA, NO_INIT, fini_qos_groupdata, pstate->current); + else if (ddsrt_strcasecmp (name, "history") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_HISTORY, ELEMENT_KIND_QOS_POLICY_HISTORY, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "latency_budget") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_LATENCYBUDGET, ELEMENT_KIND_QOS_POLICY_LATENCYBUDGET, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "lifespan") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_LIFESPAN, ELEMENT_KIND_QOS_POLICY_LIFESPAN, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "liveliness") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_LIVELINESS, ELEMENT_KIND_QOS_POLICY_LIVELINESS, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "ownership") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_OWNERSHIP, ELEMENT_KIND_QOS_POLICY_OWNERSHIP, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "ownership_strength") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_OWNERSHIPSTRENGTH, ELEMENT_KIND_QOS_POLICY_OWNERSHIPSTRENGTH, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "partition") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_PARTITION, ELEMENT_KIND_QOS_POLICY_PARTITION, NO_INIT, fini_qos_partition, pstate->current); + else if (ddsrt_strcasecmp (name, "presentation") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_PRESENTATION, ELEMENT_KIND_QOS_POLICY_PRESENTATION, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "reader_data_lifecycle") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_READERDATALIFECYCLE, ELEMENT_KIND_QOS_POLICY_READERDATALIFECYCLE, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "reliability") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_RELIABILITY, ELEMENT_KIND_QOS_POLICY_RELIABILITY, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "resource_limits") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_RESOURCELIMITS, ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "time_based_filter") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_TIMEBASEDFILTER, ELEMENT_KIND_QOS_POLICY_TIMEBASEDFILTER, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "topic_data") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_TOPICDATA, ELEMENT_KIND_QOS_POLICY_TOPICDATA, NO_INIT, fini_qos_topicdata, pstate->current); + else if (ddsrt_strcasecmp (name, "transport_priority") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_TRANSPORTPRIORITY, ELEMENT_KIND_QOS_POLICY_TRANSPORTPRIORITY, NO_INIT, NO_FINI, pstate->current); + else if (ddsrt_strcasecmp (name, "user_data") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_USERDATA, ELEMENT_KIND_QOS_POLICY_USERDATA, NO_INIT, fini_qos_userdata, pstate->current); + else if (ddsrt_strcasecmp (name, "writer_data_lifecycle") == 0) + CREATE_NODE_QOS (pstate, dds_sysdef_QOS_POLICY_WRITERDATALIFECYCLE, ELEMENT_KIND_QOS_POLICY_WRITERDATALIFECYCLE, NO_INIT, NO_FINI, pstate->current); + + // QoS policy parameters + else if (ddsrt_strcasecmp (name, "period") == 0) + CREATE_NODE_DURATION (pstate, dds_sysdef_qos_duration_property, ELEMENT_KIND_QOS_POLICY_DEADLINE_PERIOD, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_DEADLINE, pstate->current); + else if (ddsrt_strcasecmp (name, "duration") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_LATENCYBUDGET) + CREATE_NODE_DURATION (pstate, dds_sysdef_qos_duration_property, ELEMENT_KIND_QOS_POLICY_LATENCYBUDGET_DURATION, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_LATENCYBUDGET, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_LIFESPAN) + CREATE_NODE_DURATION (pstate, dds_sysdef_qos_duration_property, ELEMENT_KIND_QOS_POLICY_LIFESPAN_DURATION, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_LIFESPAN, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "service_cleanup_delay") == 0) + CREATE_NODE_DURATION (pstate, dds_sysdef_qos_duration_property, ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_SERVICE_CLEANUP_DELAY, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE, pstate->current); + else if (ddsrt_strcasecmp (name, "history_kind") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_HISTORY_KIND, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE, pstate->current); + else if (ddsrt_strcasecmp (name, "history_depth") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_HISTORY_DEPTH, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE, pstate->current); + else if (ddsrt_strcasecmp (name, "depth") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_HISTORY_DEPTH, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_HISTORY, pstate->current); + else if (ddsrt_strcasecmp (name, "max_samples") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_RESOURCE_LIMIT_MAX_SAMPLES, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_MAX_SAMPLES, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "max_instances") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_RESOURCE_LIMIT_MAX_INSTANCES, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_MAX_INSTANCES, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "max_samples_per_instance") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_RESOURCE_LIMIT_MAX_SAMPLES_PER_INSTANCE, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_MAX_SAMPLES_PER_INSTANCE, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "max_blocking_time") == 0) + CREATE_NODE_DURATION (pstate, dds_sysdef_qos_duration_property, ELEMENT_KIND_QOS_POLICY_RELIABILITY_MAX_BLOCKING_DELAY, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_RELIABILITY, pstate->current); + else if (ddsrt_strcasecmp (name, "lease_duration") == 0) + CREATE_NODE_DURATION (pstate, dds_sysdef_qos_duration_property, ELEMENT_KIND_QOS_POLICY_LIVELINESS_LEASE_DURATION, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_LIVELINESS, pstate->current); + else if (ddsrt_strcasecmp (name, "access_scope") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_PRESENTATION_ACCESS_SCOPE, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_PRESENTATION, pstate->current); + else if (ddsrt_strcasecmp (name, "coherent_access") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_PRESENTATION_COHERENT_ACCESS, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_PRESENTATION, pstate->current); + else if (ddsrt_strcasecmp (name, "ordered_access") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_PRESENTATION_ORDERED_ACCESS, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_PRESENTATION, pstate->current); + else if (ddsrt_strcasecmp (name, "autopurge_nowriter_samples_delay") == 0) + CREATE_NODE_DURATION (pstate, dds_sysdef_qos_duration_property, ELEMENT_KIND_QOS_POLICY_READERDATALIFECYCLE_AUTOPURGE_NOWRITER_SAMPLES_DELAY, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_READERDATALIFECYCLE, pstate->current); + else if (ddsrt_strcasecmp (name, "autopurge_disposed_samples_delay") == 0) + CREATE_NODE_DURATION (pstate, dds_sysdef_qos_duration_property, ELEMENT_KIND_QOS_POLICY_READERDATALIFECYCLE_AUTOPURGE_DISPOSED_SAMPLES_DELAY, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_READERDATALIFECYCLE, pstate->current); + // else if (ddsrt_strcasecmp (name, "initial_instances") == 0) + // CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_INITIAL_INSTANCES, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS, pstate->current); + // else if (ddsrt_strcasecmp (name, "initial_samples") == 0) + // CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS_INITIAL_SAMPLES, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_RESOURCELIMITS, pstate->current); + else if (ddsrt_strcasecmp (name, "ordered_access") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_PRESENTATION_ORDERED_ACCESS, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_PRESENTATION, pstate->current); + else if (ddsrt_strcasecmp (name, "minimum_separation") == 0) + CREATE_NODE_DURATION (pstate, dds_sysdef_qos_duration_property, ELEMENT_KIND_QOS_POLICY_TIMEBASEDFILTER_MINIMUM_SEPARATION, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_TIMEBASEDFILTER, pstate->current); + else if (ddsrt_strcasecmp (name, "autodispose_unregistered_instances") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_WRITERDATALIFECYCLE_AUTODISPOSE_UNREGISTERED_INSTANCES, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_WRITERDATALIFECYCLE, pstate->current); + else if (ddsrt_strcasecmp (name, "autoenable_created_entities") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_ENTITYFACTORY_AUTOENABLE_CREATED_ENTITIES, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_ENTITYFACTORY, pstate->current); + else if (ddsrt_strcasecmp (name, "kind") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_DESTINATIONORDER) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_DESTINATIONORDER_KIND, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_DESTINATIONORDER, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_DURABILITY) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_DURABILITY_KIND, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_DURABILITY, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_HISTORY) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_HISTORY_KIND, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_HISTORY, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_LIVELINESS) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_LIVELINESS_KIND, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_LIVELINESS, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_OWNERSHIP) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_OWNERSHIP_KIND, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_OWNERSHIP, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_RELIABILITY) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_RELIABILITY_KIND, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_RELIABILITY, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "value") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_GROUPDATA) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_GROUPDATA_VALUE, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_GROUPDATA, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_TOPICDATA) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_TOPICDATA_VALUE, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_TOPICDATA, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_USERDATA) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_USERDATA_VALUE, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_USERDATA, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_OWNERSHIPSTRENGTH) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_OWNERSHIPSTRENGTH_VALUE, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_OWNERSHIPSTRENGTH, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_QOS_POLICY_TRANSPORTPRIORITY) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_QOS_POLICY_TRANSPORTPRIORITY_VALUE, NO_INIT, NO_FINI, ELEMENT_KIND_QOS_POLICY_TRANSPORTPRIORITY, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "name") == 0) + CREATE_NODE_SINGLE (pstate, dds_sysdef_QOS_POLICY_PARTITION_NAME, ELEMENT_KIND_QOS_POLICY_PARTITION_NAME, NO_INIT, fini_qos_partition_name, name, dds_sysdef_QOS_POLICY_PARTITION, ELEMENT_KIND_QOS_POLICY_PARTITION, pstate->current); + else if (ddsrt_strcasecmp (name, "element") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_QOS_POLICY_PARTITION_NAME_ELEMENT, ELEMENT_KIND_QOS_POLICY_PARTITION_NAME_ELEMENT, NO_INIT, fini_qos_partition_name_element, elements, dds_sysdef_QOS_POLICY_PARTITION_NAME, ELEMENT_KIND_QOS_POLICY_PARTITION_NAME, pstate->current); + else if (ddsrt_strcasecmp (name, "sec") == 0) + { + if (pstate->current->data_type == ELEMENT_DATA_TYPE_DURATION) + CREATE_NODE_DURATION_SEC (pstate, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "nanosec") == 0) + { + if (pstate->current->data_type == ELEMENT_DATA_TYPE_DURATION) + CREATE_NODE_DURATION_NSEC (pstate, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + } + + if (pstate->scope & SYSDEF_SCOPE_DOMAIN_LIB) + { + // Domain library + if (ddsrt_strcasecmp (name, "domain_library") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_domain_lib, ELEMENT_KIND_DOMAIN_LIB, NO_INIT, fini_domain_lib, domain_libs, dds_sysdef_system, ELEMENT_KIND_DDS, pstate->current); + else if (ddsrt_strcasecmp (name, "domain") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_domain, ELEMENT_KIND_DOMAIN, NO_INIT, fini_domain, domains, dds_sysdef_domain_lib, ELEMENT_KIND_DOMAIN_LIB, pstate->current); + else if (ddsrt_strcasecmp (name, "register_type") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_DOMAIN) + CREATE_NODE_LIST (pstate, dds_sysdef_register_type, ELEMENT_KIND_REGISTER_TYPE, NO_INIT, fini_register_type, register_types, dds_sysdef_domain, ELEMENT_KIND_DOMAIN, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_PARTICIPANT) + CREATE_NODE_LIST (pstate, dds_sysdef_register_type, ELEMENT_KIND_REGISTER_TYPE, NO_INIT, fini_register_type, register_types, dds_sysdef_participant, ELEMENT_KIND_PARTICIPANT, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "topic") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_DOMAIN) + CREATE_NODE_LIST (pstate, dds_sysdef_topic, ELEMENT_KIND_TOPIC, NO_INIT, fini_topic, topics, dds_sysdef_domain, ELEMENT_KIND_DOMAIN, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_PARTICIPANT) + CREATE_NODE_LIST (pstate, dds_sysdef_topic, ELEMENT_KIND_TOPIC, NO_INIT, fini_topic, topics, dds_sysdef_participant, ELEMENT_KIND_PARTICIPANT, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + } + + if (pstate->scope & SYSDEF_SCOPE_PARTICIPANT_LIB) + { + // Domain participant library + if (ddsrt_strcasecmp (name, "domain_participant_library") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_participant_lib, ELEMENT_KIND_PARTICIPANT_LIB, NO_INIT, fini_participant_lib, participant_libs, dds_sysdef_system, ELEMENT_KIND_DDS, pstate->current); + else if (ddsrt_strcasecmp (name, "domain_participant") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_PARTICIPANT_LIB) + CREATE_NODE_LIST (pstate, dds_sysdef_participant, ELEMENT_KIND_PARTICIPANT, NO_INIT, fini_participant, participants, dds_sysdef_participant_lib, ELEMENT_KIND_PARTICIPANT_LIB, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_APPLICATION) + CREATE_NODE_LIST (pstate, dds_sysdef_participant, ELEMENT_KIND_PARTICIPANT, NO_INIT, fini_participant, participants, dds_sysdef_application, ELEMENT_KIND_APPLICATION, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "publisher") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_publisher, ELEMENT_KIND_PUBLISHER, NO_INIT, fini_publisher, publishers, dds_sysdef_participant, ELEMENT_KIND_PARTICIPANT, pstate->current); + else if (ddsrt_strcasecmp (name, "data_writer") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_writer, ELEMENT_KIND_WRITER, NO_INIT, fini_writer, writers, dds_sysdef_publisher, ELEMENT_KIND_PUBLISHER, pstate->current); + else if (ddsrt_strcasecmp (name, "subscriber") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_subscriber, ELEMENT_KIND_SUBSCRIBER, NO_INIT, fini_subscriber, subscribers, dds_sysdef_participant, ELEMENT_KIND_PARTICIPANT, pstate->current); + else if (ddsrt_strcasecmp (name, "data_reader") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_reader, ELEMENT_KIND_READER, NO_INIT, fini_reader, readers, dds_sysdef_subscriber, ELEMENT_KIND_SUBSCRIBER, pstate->current); + } + + if (pstate->scope & SYSDEF_SCOPE_APPLICATION_LIB) + { + // Application library + if (ddsrt_strcasecmp (name, "application_library") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_application_lib, ELEMENT_KIND_APPLICATION_LIB, NO_INIT, fini_application_lib, application_libs, dds_sysdef_system, ELEMENT_KIND_DDS, pstate->current); + else if (ddsrt_strcasecmp (name, "application") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_APPLICATION_LIB) + CREATE_NODE_LIST (pstate, dds_sysdef_application, ELEMENT_KIND_APPLICATION, NO_INIT, fini_application, applications, dds_sysdef_application_lib, ELEMENT_KIND_APPLICATION_LIB, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_APPLICATION_LIST) + CREATE_NODE_LIST (pstate, dds_sysdef_application_ref, ELEMENT_KIND_DEPLOYMENT_APPLICATION_REF, NO_INIT, NO_FINI, application_refs, dds_sysdef_application_list, ELEMENT_KIND_DEPLOYMENT_APPLICATION_LIST, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + } + + if (pstate->scope & SYSDEF_SCOPE_NODE_LIB) + { + // Node library + if (ddsrt_strcasecmp (name, "node_library") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_node_lib, ELEMENT_KIND_NODE_LIB, NO_INIT, fini_node_lib, node_libs, dds_sysdef_system, ELEMENT_KIND_DDS, pstate->current); + else if (ddsrt_strcasecmp (name, "node") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_NODE_LIB) + CREATE_NODE_LIST (pstate, dds_sysdef_node, ELEMENT_KIND_NODE, NO_INIT, fini_node, nodes, dds_sysdef_node_lib, ELEMENT_KIND_NODE_LIB, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_NODE_REF, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "hostname") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_NODE_HOSTNAME, NO_INIT, NO_FINI, ELEMENT_KIND_NODE, pstate->current); + else if (ddsrt_strcasecmp (name, "ipv4_address") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_NODE_IPV4_ADDRESS, NO_INIT, NO_FINI, ELEMENT_KIND_NODE, pstate->current); + else if (ddsrt_strcasecmp (name, "ipv6_address") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_NODE_IPV6_ADDRESS, NO_INIT, NO_FINI, ELEMENT_KIND_NODE, pstate->current); + else if (ddsrt_strcasecmp (name, "mac_address") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_NODE_MAC_ADDRESS, NO_INIT, NO_FINI, ELEMENT_KIND_NODE, pstate->current); + } + + if (pstate->scope & SYSDEF_SCOPE_DEPLOYMENT_LIB) + { + // Deployment library + if (ddsrt_strcasecmp (name, "deployment_library") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_deployment_lib, ELEMENT_KIND_DEPLOYMENT_LIB, NO_INIT, fini_deployment_lib, deployment_libs, dds_sysdef_system, ELEMENT_KIND_DDS, pstate->current); + else if (ddsrt_strcasecmp (name, "deployment") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_deployment, ELEMENT_KIND_DEPLOYMENT, NO_INIT, fini_deployment, deployments, dds_sysdef_deployment_lib, ELEMENT_KIND_DEPLOYMENT_LIB, pstate->current); + else if (ddsrt_strcasecmp (name, "application_list") == 0) + CREATE_NODE_SINGLE (pstate, dds_sysdef_application_list, ELEMENT_KIND_DEPLOYMENT_APPLICATION_LIST, NO_INIT, fini_application_list, application_list, dds_sysdef_deployment, ELEMENT_KIND_DEPLOYMENT, pstate->current); + else if (ddsrt_strcasecmp (name, "configuration") == 0) + CREATE_NODE_SINGLE (pstate, dds_sysdef_configuration, ELEMENT_KIND_DEPLOYMENT_CONF, NO_INIT, fini_conf, configuration, dds_sysdef_deployment, ELEMENT_KIND_DEPLOYMENT, pstate->current); + else if (ddsrt_strcasecmp (name, "tsn") == 0) + CREATE_NODE_SINGLE (pstate, dds_sysdef_tsn_configuration, ELEMENT_KIND_DEPLOYMENT_CONF_TSN, NO_INIT, fini_conf_tsn, tsn_configuration, dds_sysdef_configuration, ELEMENT_KIND_DEPLOYMENT_CONF, pstate->current); + else if (ddsrt_strcasecmp (name, "tsn_talker") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_tsn_talker_configuration, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER, NO_INIT, fini_conf_tsn_talker, tsn_talker_configurations, dds_sysdef_tsn_configuration, ELEMENT_KIND_DEPLOYMENT_CONF_TSN, pstate->current); + else if (ddsrt_strcasecmp (name, "tsn_listener") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_tsn_listener_configuration, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER, NO_INIT, fini_conf_tsn_listener, tsn_listener_configurations, dds_sysdef_tsn_configuration, ELEMENT_KIND_DEPLOYMENT_CONF_TSN, pstate->current); + else if (ddsrt_strcasecmp (name, "data_frame_specification") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_tsn_data_frame_specification, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC, NO_INIT, fini_conf_tsn_data_frame_specification, data_frame_specification, dds_sysdef_tsn_talker_configuration, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER, pstate->current); + else if (ddsrt_strcasecmp (name, "ipv4_tuple") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_tsn_ip_tuple, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, NO_INIT, fini_conf_tsn_ip_tuple, ipv4_tuple, dds_sysdef_tsn_data_frame_specification, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC, pstate->current); + else if (ddsrt_strcasecmp (name, "ipv6_tuple") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_tsn_ip_tuple, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, NO_INIT, fini_conf_tsn_ip_tuple, ipv6_tuple, dds_sysdef_tsn_data_frame_specification, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC, pstate->current); + else if (ddsrt_strcasecmp (name, "source_ip_address") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_SOURCE_IP_ADDRESS, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_SOURCE_IP_ADDRESS, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "destination_ip_address") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_DESTINATION_IP_ADDRESS, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_DESTINATION_IP_ADDRESS, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "dscp") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_DSCP, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_DSCP, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "protocol") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_PROTOCOL, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_PROTOCOL, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "source_port") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_SOURCE_PORT, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_SOURCE_PORT, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "destination_port") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_DESTINATION_PORT, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE_DESTINATION_PORT, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "traffic_specification") == 0) + CREATE_NODE_LIST (pstate, dds_sysdef_tsn_traffic_specification, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC, NO_INIT, fini_conf_tsn_traffic_specification, traffic_specification, dds_sysdef_tsn_talker_configuration, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER, pstate->current); + else if (ddsrt_strcasecmp (name, "periodicity") == 0) + CREATE_NODE_DURATION (pstate, dds_sysdef_qos_duration_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_PERIODICITY, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC, pstate->current); + else if (ddsrt_strcasecmp (name, "samples_per_period") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_SAMPLES_PER_PERIOD, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC, pstate->current); + else if (ddsrt_strcasecmp (name, "max_bytes_per_sample") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_MAX_BYTES_PER_SAMPLE, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC, pstate->current); + else if (ddsrt_strcasecmp (name, "transmission_selection") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TRANSMISSION_SELECTION, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC, pstate->current); + else if (ddsrt_strcasecmp (name, "time_aware") == 0) + CREATE_NODE_SINGLE (pstate, dds_sysdef_tsn_time_aware, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE, NO_INIT, NO_FINI, time_aware, dds_sysdef_tsn_traffic_specification, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC, pstate->current); + else if (ddsrt_strcasecmp (name, "earliest_transmit_offset") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE_EARLIEST_TRANSMIT_OFFSET, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE, pstate->current); + else if (ddsrt_strcasecmp (name, "latest_transmit_offset") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE_LATEST_TRANSMIT_OFFSET, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE, pstate->current); + else if (ddsrt_strcasecmp (name, "jitter") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE_JITTER, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_TRAFFIC_SPEC_TIME_AWARE, pstate->current); + else if (ddsrt_strcasecmp (name, "network_requirements") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER) + CREATE_NODE_LIST (pstate, dds_sysdef_tsn_network_requirements, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_NETWORK_REQUIREMENTS, NO_INIT, NO_FINI, network_requirements, dds_sysdef_tsn_talker_configuration, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER) + CREATE_NODE_LIST (pstate, dds_sysdef_tsn_network_requirements, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER_NETWORK_REQUIREMENTS, NO_INIT, NO_FINI, network_requirements, dds_sysdef_tsn_listener_configuration, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "num_seamless_trees") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_NETWORK_REQUIREMENTS) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_NETWORK_REQUIREMENTS_NUM_SEAMLESS_TREES, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_NETWORK_REQUIREMENTS, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER_NETWORK_REQUIREMENTS) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER_NETWORK_REQUIREMENTS_NUM_SEAMLESS_TREES, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER_NETWORK_REQUIREMENTS, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + else if (ddsrt_strcasecmp (name, "max_latency") == 0) + { + if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_NETWORK_REQUIREMENTS) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_NETWORK_REQUIREMENTS_MAX_LATENCY, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_NETWORK_REQUIREMENTS, pstate->current); + else if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER_NETWORK_REQUIREMENTS) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER_NETWORK_REQUIREMENTS_MAX_LATENCY, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER_NETWORK_REQUIREMENTS, pstate->current); + else + PARSER_ERROR_INVALID_PARENT_KIND (); + } + } + } + + if (ret == SD_PARSE_RESULT_OK) + { + PARSER_ERROR (pstate, line, "Unknown element '%s'", name); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + + struct xml_element *e = pstate->current; + while (e != NULL) + { + struct xml_element *tmp = e->parent; + if (!e->retain) + free_node (e); + e = tmp; + } +status_ok: + return ret; +} + +static void proc_error (void *varg, const char *msg, int line) +{ + struct parse_sysdef_state * const pstate = varg; + if (!pstate->has_err) + { + PARSER_ERROR (pstate, line, "Syntax error '%s'", msg); + } +} + +static dds_return_t sysdef_parse(struct ddsrt_xmlp_state *xmlps, struct parse_sysdef_state *pstate, struct dds_sysdef_system **sysdef) +{ + dds_return_t ret = DDS_RETCODE_OK; + if ((ret = ddsrt_xmlp_parse (xmlps)) != SD_PARSE_RESULT_OK) + { + SYSDEF_ERROR ("Error parsing system definition XML: %s (error code %d, line %d)\n", pstate->err_msg, ret, pstate->err_line); + ret = DDS_RETCODE_ERROR; + if (pstate->sysdef != NULL) + dds_sysdef_fini_sysdef (pstate->sysdef); + } + else + { + *sysdef = pstate->sysdef; + } + + return ret; +} + +dds_return_t dds_sysdef_init_sysdef (FILE *fp, struct dds_sysdef_system **sysdef, uint32_t lib_scope) +{ + dds_return_t ret = DDS_RETCODE_OK; + struct parse_sysdef_state pstate = { .sysdef = NULL, .scope = lib_scope}; + struct ddsrt_xmlp_callbacks cb = { + .attr = proc_attr, + .elem_close = proc_elem_close, + .elem_data = proc_elem_data, + .elem_open = proc_elem_open, + .error = proc_error + }; + + struct ddsrt_xmlp_state *xmlps = ddsrt_xmlp_new_file (fp, &pstate, &cb); + ret = sysdef_parse(xmlps, &pstate, sysdef); + ddsrt_xmlp_free (xmlps); + return ret; +} + +dds_return_t dds_sysdef_init_sysdef_str (const char *raw, struct dds_sysdef_system **sysdef, uint32_t lib_scope) +{ + dds_return_t ret = DDS_RETCODE_OK; + struct parse_sysdef_state pstate = { .sysdef = NULL, .scope = lib_scope}; + struct ddsrt_xmlp_callbacks cb = { + .attr = proc_attr, + .elem_close = proc_elem_close, + .elem_data = proc_elem_data, + .elem_open = proc_elem_open, + .error = proc_error + }; + + struct ddsrt_xmlp_state *xmlps = ddsrt_xmlp_new_string (raw, &pstate, &cb); + ret = sysdef_parse(xmlps, &pstate, sysdef); + ddsrt_xmlp_free (xmlps); + return ret; +} + +void dds_sysdef_fini_sysdef (struct dds_sysdef_system *sysdef) +{ + free_node (sysdef); +} + +enum parse_type_scope { + PARSE_TYPE_SCOPE_ROOT, + PARSE_TYPE_SCOPE_TYPES, + PARSE_TYPE_SCOPE_TYPE_ENTRY, + PARSE_TYPE_SCOPE_TYPE_INFO, + PARSE_TYPE_SCOPE_TYPE_MAP +}; + +struct parse_type_state { + bool has_err; + int err_line; + char err_msg[MAX_ERRMSG_SZ]; + enum parse_type_scope scope; + struct dds_sysdef_type_metadata_admin *type_meta_data; + struct dds_sysdef_type_metadata *current; +}; + +static bool type_equal (const void *a, const void *b) +{ + const struct dds_sysdef_type_metadata *type_a = a, *type_b = b; + return memcmp (type_a->type_hash, type_b->type_hash, sizeof (TYPE_HASH_LENGTH)) == 0; +} + +static uint32_t type_hash (const void *t) +{ + const struct dds_sysdef_type_metadata *type = t; + uint32_t hash32; + memcpy (&hash32, type->type_hash, sizeof (hash32)); + return hash32; +} + +static void free_type_meta_data (struct dds_sysdef_type_metadata *tmd) +{ + if (tmd->type_hash != NULL) + ddsrt_free (tmd->type_hash); + if (tmd->type_info_cdr != NULL) + ddsrt_free (tmd->type_info_cdr); + if (tmd->type_map_cdr != NULL) + ddsrt_free (tmd->type_map_cdr); + ddsrt_free (tmd); +} + +static int proc_type_elem_open (void *varg, UNUSED_ARG (uintptr_t parentinfo), UNUSED_ARG (uintptr_t *eleminfo), const char *name, int line) +{ + struct parse_type_state * const pstate = varg; + int ret = SD_PARSE_RESULT_OK; + + if (ddsrt_strcasecmp (name, "types") == 0) + { + if (pstate->scope != PARSE_TYPE_SCOPE_ROOT) + { + PARSER_ERROR (pstate, line, "Unexpected element '%s'", name); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + else + { + pstate->scope = PARSE_TYPE_SCOPE_TYPES; + pstate->type_meta_data = ddsrt_malloc (sizeof (*pstate->type_meta_data)); + pstate->type_meta_data->m = ddsrt_hh_new (1, type_hash, type_equal); + } + } + else if (ddsrt_strcasecmp (name, "type") == 0) + { + if (pstate->scope != PARSE_TYPE_SCOPE_TYPES) + { + PARSER_ERROR (pstate, line, "Unexpected element '%s'", name); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + else + { + pstate->scope = PARSE_TYPE_SCOPE_TYPE_ENTRY; + struct dds_sysdef_type_metadata *t = ddsrt_calloc (1, sizeof (*t)); + if (t == NULL) + { + PARSER_ERROR (pstate, line, "Error allocating type meta-data"); + ret = SD_PARSE_RESULT_ERR; + } + else + { + pstate->current = t; + } + } + } + else if (ddsrt_strcasecmp (name, "type_info") == 0) + { + if (pstate->scope != PARSE_TYPE_SCOPE_TYPE_ENTRY) + { + PARSER_ERROR (pstate, line, "Unexpected element '%s'", name); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + else + { + pstate->scope = PARSE_TYPE_SCOPE_TYPE_INFO; + } + } + else if (ddsrt_strcasecmp (name, "type_map") == 0) + { + if (pstate->scope != PARSE_TYPE_SCOPE_TYPE_ENTRY) + { + PARSER_ERROR (pstate, line, "Unexpected element '%s'", name); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + } + else + { + pstate->scope = PARSE_TYPE_SCOPE_TYPE_MAP; + } + } + else + { + PARSER_ERROR (pstate, line, "Unexpected element '%s'", name); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + if (pstate->scope == PARSE_TYPE_SCOPE_TYPE_ENTRY) + free_type_meta_data (pstate->current); + } + + return ret; +} + +static int proc_type_elem_close (void *varg, UNUSED_ARG (uintptr_t eleminfo), UNUSED_ARG (int line)) +{ + struct parse_type_state * const pstate = varg; + int ret = SD_PARSE_RESULT_OK; + if (pstate->scope == PARSE_TYPE_SCOPE_TYPE_INFO) + { + pstate->scope = PARSE_TYPE_SCOPE_TYPE_ENTRY; + } + else if (pstate->scope == PARSE_TYPE_SCOPE_TYPE_MAP) + { + pstate->scope = PARSE_TYPE_SCOPE_TYPE_ENTRY; + } + else if (pstate->scope == PARSE_TYPE_SCOPE_TYPE_ENTRY) + { + if (pstate->current->type_hash == NULL) + { + PARSER_ERROR (pstate, line, "Type identifier not set"); + ret = SD_PARSE_RESULT_ERR; + free_type_meta_data (pstate->current); + } + else if (pstate->current->type_info_cdr == NULL || pstate->current->type_map_cdr == NULL) + { + PARSER_ERROR (pstate, line, "Incomplete type meta-data"); + ret = SD_PARSE_RESULT_ERR; + free_type_meta_data (pstate->current); + } + else + { + ddsrt_hh_add (pstate->type_meta_data->m, pstate->current); + pstate->scope = PARSE_TYPE_SCOPE_TYPES; + } + pstate->current = NULL; + } + else if (pstate->scope == PARSE_TYPE_SCOPE_TYPES) + { + pstate->scope = PARSE_TYPE_SCOPE_ROOT; + } + return ret; +} + +static int proc_type_elem_data (void *varg, UNUSED_ARG (uintptr_t eleminfo), const char *value, int line) +{ + struct parse_type_state * const pstate = varg; + int ret = SD_PARSE_RESULT_OK; + + switch (pstate->scope) + { + case PARSE_TYPE_SCOPE_TYPE_INFO: + pstate->current->type_info_cdr_sz = strlen (value) / 2; + pstate->current->type_info_cdr = ddsrt_malloc (pstate->current->type_info_cdr_sz); + dds_sysdef_parse_hex (value, pstate->current->type_info_cdr); + break; + case PARSE_TYPE_SCOPE_TYPE_MAP: + pstate->current->type_map_cdr_sz = strlen (value) / 2; + pstate->current->type_map_cdr = ddsrt_malloc (pstate->current->type_map_cdr_sz); + dds_sysdef_parse_hex (value, pstate->current->type_map_cdr); + break; + default: + PARSER_ERROR (pstate, line, "Unexpected data"); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + break; + } + return ret; +} + +static int proc_type_attr (void *varg, UNUSED_ARG (uintptr_t eleminfo), const char *name, const char *value, int line) +{ + struct parse_type_state * const pstate = varg; + int ret = SD_PARSE_RESULT_OK; + bool attr_processed = false; + + if (ddsrt_strcasecmp(name, "xmlns") == 0 || ddsrt_strcasecmp(name, "xmlns:xsi") == 0 || ddsrt_strcasecmp(name, "xsi:schemaLocation") == 0) + return ret; + + switch (pstate->scope) + { + case PARSE_TYPE_SCOPE_TYPE_ENTRY: + if (ddsrt_strcasecmp(name, "type_identifier") == 0) + { + if (strlen (value) != 2 * TYPE_HASH_LENGTH) + { + PARSER_ERROR (pstate, line, "Invalid type identifier length"); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + free_type_meta_data (pstate->current); + } + else + { + pstate->current->type_hash = ddsrt_malloc (TYPE_HASH_LENGTH); + if ((ret = dds_sysdef_parse_hex (value, pstate->current->type_hash)) != SD_PARSE_RESULT_OK) + { + PARSER_ERROR (pstate, line, "Invalid type identifier"); + free_type_meta_data (pstate->current); + } + else + attr_processed = true; + } + } + break; + default: + break; + } + + if (!attr_processed && ret == SD_PARSE_RESULT_OK) + { + PARSER_ERROR (pstate, line, "Unexpected attribute '%s'", name); + ret = SD_PARSE_RESULT_SYNTAX_ERR; + if (pstate->scope == PARSE_TYPE_SCOPE_TYPE_ENTRY || pstate->scope == PARSE_TYPE_SCOPE_TYPE_INFO || pstate->scope == PARSE_TYPE_SCOPE_TYPE_MAP) + free_type_meta_data (pstate->current); + } + + return ret; +} + +static void proc_type_error (void *varg, const char *msg, int line) +{ + struct parse_type_state * const pstate = varg; + if (!pstate->has_err) + { + if (pstate->current != NULL) + free_type_meta_data (pstate->current); + PARSER_ERROR (pstate, line, "Syntax error '%s'", msg); + } +} + +dds_return_t dds_sysdef_init_data_types (FILE *fp, struct dds_sysdef_type_metadata_admin **type_meta_data) +{ + struct parse_type_state pstate = { 0 }; + struct ddsrt_xmlp_callbacks cb = { + .attr = proc_type_attr, + .elem_close = proc_type_elem_close, + .elem_data = proc_type_elem_data, + .elem_open = proc_type_elem_open, + .error = proc_type_error + }; + + struct ddsrt_xmlp_state *xmlps = ddsrt_xmlp_new_file (fp, &pstate, &cb); + + dds_return_t ret = DDS_RETCODE_OK; + if ((ret = ddsrt_xmlp_parse (xmlps)) != SD_PARSE_RESULT_OK) { + SYSDEF_ERROR ("Error parsing data types XML: %s (error code %d, line %d)\n", pstate.err_msg, ret, pstate.err_line); + ret = DDS_RETCODE_ERROR; + if (pstate.type_meta_data != NULL) + dds_sysdef_fini_data_types (pstate.type_meta_data); + } + else + { + *type_meta_data = pstate.type_meta_data; + } + + ddsrt_xmlp_free (xmlps); + return ret; +} + +static void free_type_meta_data_wrap (void *vnode, void *varg) +{ + (void) varg; + struct dds_sysdef_type_metadata *tmd = (struct dds_sysdef_type_metadata *) vnode; + free_type_meta_data (tmd); +} + +void dds_sysdef_fini_data_types (struct dds_sysdef_type_metadata_admin *type_meta_data) +{ + if (type_meta_data->m) + { + ddsrt_hh_enum (type_meta_data->m, free_type_meta_data_wrap, NULL); + ddsrt_hh_free (type_meta_data->m); + } + ddsrt_free (type_meta_data); +} diff --git a/src/core/ddsc/src/dds_sysdef_validation.c b/src/core/ddsc/src/dds_sysdef_validation.c new file mode 100644 index 0000000000..604cee088a --- /dev/null +++ b/src/core/ddsc/src/dds_sysdef_validation.c @@ -0,0 +1,141 @@ +// Copyright(c) 2024 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#include "string.h" +#include "dds/ddsrt/heap.h" +#include "dds__qos.h" +#include "dds__sysdef_validation.h" +#include "dds__sysdef_parser.h" + +#define CHECK_DUPLICATE(lib,element_type,element,element_attr,element_descr) \ + do { \ + for (const struct element_type *e2 = lib; e2 != NULL; e2 = (struct element_type *) e2->xmlnode.next) \ + { \ + if (element != e2 && element->element_attr != NULL && e2->element_attr != NULL && strcmp (element->element_attr, e2->element_attr) == 0) { \ + SYSDEF_ERROR ("Duplicate %s '%s'\n", element_descr, element->element_attr); \ + goto failed; \ + } \ + } \ + } while (0) + +#define CHECK_NULL_ATTR(lib,element_type,element,element_attr,element_descr) \ + do { \ + if (element->element_attr == NULL) { \ + SYSDEF_ERROR ("%s Attribute "#element_attr" is 'NULL'\n", element_descr); \ + goto failed; \ + } \ + } while (0) + +static void free_partitions (uint32_t n_partitions, char **partitions) +{ + for (uint32_t i = 0; i < n_partitions; i++) + ddsrt_free (partitions[i]); + ddsrt_free (partitions); +} + +static int is_wildcard_partition (const char *str) +{ + return strchr (str, '*') || strchr (str, '?'); +} + +static dds_return_t validate_qos (dds_qos_t *qos, const char *qos_location) +{ + // History + dds_history_kind_t history_kind; + int32_t history_depth; + if (dds_qget_history (qos, &history_kind, &history_depth) && (history_kind != DDS_HISTORY_KEEP_LAST || history_depth < 0)) + { + SYSDEF_ERROR ("Unsupported history kind or depth (%s)\n", qos_location); + goto failed; + } + + // Partition + uint32_t n_partitions; + char **partitions; + if (dds_qget_partition (qos, &n_partitions, &partitions)) + { + for (uint32_t i = 0; i < n_partitions; i++) + { + if (is_wildcard_partition (partitions[i])) + { + SYSDEF_ERROR ("Wildcards in partition name not supported (%s)\n", qos_location); + free_partitions (n_partitions, partitions); + goto failed; + } + } + free_partitions (n_partitions, partitions); + } + return DDS_RETCODE_OK; + +failed: + return DDS_RETCODE_BAD_PARAMETER; +} + +dds_return_t dds_validate_qos_lib (const struct dds_sysdef_system *sysdef, uint64_t qos_mask) +{ + for (const struct dds_sysdef_qos_lib *qos_lib = sysdef->qos_libs; qos_lib != NULL; qos_lib = (struct dds_sysdef_qos_lib *) qos_lib->xmlnode.next) + { + CHECK_NULL_ATTR(sysdef->qos_libs, dds_sysdef_qos_lib, qos_lib, name, "QoS library"); + CHECK_DUPLICATE(sysdef->qos_libs, dds_sysdef_qos_lib, qos_lib, name, "QoS library"); + for (const struct dds_sysdef_qos_profile *qos_profile = qos_lib->qos_profiles; qos_profile != NULL; qos_profile = (struct dds_sysdef_qos_profile *) qos_profile->xmlnode.next) + { + CHECK_NULL_ATTR(qos_lib->qos_profiles, dds_sysdef_qos_profile, qos_profile, name, "QoS profile"); + CHECK_DUPLICATE(qos_lib->qos_profiles, dds_sysdef_qos_profile, qos_profile, name, "QoS profile"); + for (const struct dds_sysdef_qos *qos = qos_profile->qos; qos != NULL; qos = (struct dds_sysdef_qos *) qos->xmlnode.next) + { + CHECK_DUPLICATE(qos_profile->qos, dds_sysdef_qos, qos, name, "QoS"); + + uint64_t mask = ~(uint64_t)0U; + const char *kind; + switch (qos->kind) + { + case DDS_SYSDEF_TOPIC_QOS: + mask = DDS_TOPIC_QOS_MASK & qos_mask; + kind = "topic"; + break; + case DDS_SYSDEF_READER_QOS: + mask = DDS_READER_QOS_MASK & qos_mask; + kind = "reader"; + break; + case DDS_SYSDEF_WRITER_QOS: + mask = DDS_WRITER_QOS_MASK & qos_mask; + kind = "writer"; + break; + case DDS_SYSDEF_SUBSCRIBER_QOS: + mask = DDS_SUBSCRIBER_QOS_MASK & qos_mask; + kind = "subscriber"; + break; + case DDS_SYSDEF_PUBLISHER_QOS: + mask = DDS_PUBLISHER_QOS_MASK & qos_mask; + kind = "publisher"; + break; + case DDS_SYSDEF_PARTICIPANT_QOS: + mask = DDS_PARTICIPANT_QOS_MASK & qos_mask; + kind = "participant"; + break; + } + + // Unsupported policies + if (qos->qos->present & ~mask) + { + SYSDEF_ERROR ("Unsupported policy, non-allowed mask: %08" PRIx64 " (%s::%s, %s QoS%s%s)\n", qos->qos->present & ~mask, qos_lib->name, qos_profile->name, kind, (qos->name != NULL ? " " : ""), (qos->name != NULL ? qos->name : "")); + goto failed; + } + + if (validate_qos (qos->qos, qos_profile->name) != DDS_RETCODE_OK) + goto failed; + } + } + } + return DDS_RETCODE_OK; + +failed: + return DDS_RETCODE_BAD_PARAMETER; +} diff --git a/src/core/ddsc/tests/CMakeLists.txt b/src/core/ddsc/tests/CMakeLists.txt index 91b8af18d8..7f246cb03c 100644 --- a/src/core/ddsc/tests/CMakeLists.txt +++ b/src/core/ddsc/tests/CMakeLists.txt @@ -151,6 +151,11 @@ if(ENABLE_TOPIC_DISCOVERY) "topic_find_global.c") endif() +if(ENABLE_QOS_PROVIDER) + list(APPEND ddsc_test_sources + "qos_provider.c") +endif() + add_cunit_executable(cunit_ddsc ${ddsc_test_sources}) target_include_directories( cunit_ddsc PRIVATE diff --git a/src/core/ddsc/tests/qos_provider.c b/src/core/ddsc/tests/qos_provider.c new file mode 100644 index 0000000000..edf261e699 --- /dev/null +++ b/src/core/ddsc/tests/qos_provider.c @@ -0,0 +1,1205 @@ +// Copyright(c) 2024 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause +#include "CUnit/Theory.h" +#include "dds/dds.h" + +#include "dds/ddsc/dds_public_qos_provider.h" + +#include "dds/ddsrt/hopscotch.h" +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/random.h" +#include "dds/ddsrt/string.h" +#include "dds/ddsrt/time.h" +#include "dds/ddsrt/io.h" + +#include "dds__qos.h" +#include "dds__sysdef_model.h" +#include "dds__qos_provider.h" + +#define DEF(libs) \ + "\n"libs"\n" +#define LIB(lib_name,profiles) \ + "\n "profiles"\n " +#define N_LIB(profiles) \ + "\n "profiles"\n " +#define PRO(prof_name,ents) \ + "\n "ents"\n " +#define N_PRO(ents) \ + "\n "ents"\n " +#define ENT(qos,kind) \ + "\n <" #kind "_qos>"qos"\n " +#define ENT_N(nm,qos,kind) \ + "\n <" #kind "_qos name=\""#nm"\">"qos"\n " + + +CU_TheoryDataPoints(qos_provider, create) = { + // The various of sysdef configuration files + CU_DataPoints(char *, + DEF(LIB(lib0,PRO(pro0,ENT("",datareader)ENT("",datawriter) + ENT("",publisher)ENT("",subscriber) + ENT("",domain_participant)ENT("",topic)))), + DEF(LIB(lib0,PRO(pro0,ENT("",datareader) + ENT_N(rd0,"",datareader)))), + DEF(LIB(lib0,PRO(pro0,ENT_N(rd0,"",datareader) + ENT_N(rd0,"",datareader)))), + DEF(LIB(lib0,PRO(pro0,ENT("",datareader) + ENT("",datareader)))), + DEF(LIB(lib0,PRO(pro0,ENT("",datareader)) + PRO(pro1,ENT("",datareader)))), + DEF(LIB(lib0,PRO(pro0,ENT("",datareader))) + LIB(lib1,PRO(pro0,ENT("",datareader)))), + DEF(LIB(lib0,PRO(pro0,ENT("",datareader)) + PRO(pro0,ENT("",datareader)))), + DEF(LIB(lib0,PRO(pro0,ENT("",datareader))) + LIB(lib0,PRO(pro1,ENT("",datareader)))), + DEF(LIB(lib0,N_PRO( ENT("",datareader)))), + DEF(N_LIB( PRO(pro0,ENT("",datareader)))), + ), + // Expected retcodes + CU_DataPoints(int32_t, + DDS_RETCODE_OK, + DDS_RETCODE_OK, + DDS_RETCODE_BAD_PARAMETER, + DDS_RETCODE_BAD_PARAMETER, + DDS_RETCODE_OK, + DDS_RETCODE_OK, + DDS_RETCODE_BAD_PARAMETER, + DDS_RETCODE_BAD_PARAMETER, + DDS_RETCODE_ERROR, + DDS_RETCODE_ERROR, + ) +}; +// @brief This tests creating qos_provider with different sysdef files. +CU_Theory((char *configuration, dds_return_t ret), qos_provider, create) +{ + dds_qos_provider_t *provider = NULL; + // init qos provider with given configuration file + dds_return_t ret_ac = dds_create_qos_provider(configuration, &provider); + if (ret_ac == DDS_RETCODE_OK) + dds_delete_qos_provider(provider); + CU_ASSERT_EQUAL(ret, ret_ac); +} + +#define NO_QOS_PROVIDER_CONF \ + DEF( \ + LIB(lib0, \ + PRO(pro00, \ + ENT("",datareader)ENT("",datawriter) \ + ENT_N(rd1,"",datareader) \ + ENT("",publisher)ENT("",subscriber) \ + ENT("",domain_participant)ENT("",topic)) \ + PRO(pro01, \ + ENT_N(rd0,"",datareader)ENT("",datawriter) \ + ENT("",publisher)ENT("",subscriber) \ + ENT("",domain_participant)ENT("",topic)) \ + PRO(pro02, \ + ENT_N(rd0,"",datareader)ENT_N(wr0,"",datawriter) \ + ENT("",publisher)ENT("",subscriber) \ + ENT("",domain_participant)ENT("",topic)) \ + PRO(pro03, \ + ENT_N(rd0,"",datareader)ENT_N(wr0,"",datawriter) \ + ENT_N(rd1,"",datareader)ENT_N(wr1,"",datawriter) \ + ENT_N(pb0,"",publisher)ENT("",subscriber) \ + ENT("",domain_participant)ENT("",topic)) \ + ) \ + LIB(lib1, \ + PRO(pro00, \ + ENT("",datareader)ENT("",datawriter) \ + ENT("",publisher)ENT("",subscriber) \ + ENT("",domain_participant)ENT("",topic)) \ + PRO(pro01, \ + ENT("",datareader)ENT("",datawriter) \ + ENT("",publisher)ENT("",subscriber) \ + ENT("",domain_participant)ENT_N(tp0,"",topic)) \ + PRO(pro02, \ + ENT("",datareader)ENT("",datawriter) \ + ENT("",publisher)ENT("",subscriber) \ + ENT_N(pp0,"",domain_participant)ENT_N(tp0,"",topic)) \ + PRO(pro03, \ + ENT("",datareader)ENT("",datawriter) \ + ENT("",publisher)ENT_N(sb0,"",subscriber) \ + ENT_N(pp0,"",domain_participant)ENT_N(tp0,"",topic)) \ + ) \ + LIB(lib2, \ + PRO(pro01, \ + ENT_N(rd0,"",datareader)ENT_N(tp0,"",topic)) \ + PRO(pro02, \ + ENT_N(rd0,"",datareader)ENT_N(wr0,"",datawriter) \ + ENT_N(pp0,"",domain_participant)ENT_N(tp0,"",topic)) \ + PRO(pro03, \ + ENT_N(rd0,"",datareader)ENT_N(wr0,"",datawriter) \ + ENT_N(pb0,"",publisher)ENT_N(sb0,"",subscriber) \ + ENT_N(pp0,"",domain_participant)ENT_N(tp0,"",topic)) \ + ) \ + ) \ + +typedef struct cscope_tokens +{ + char *scope; + char *expct; +} cscope_tokens_t; + +#define SCOPE(scp,exp) {.scope=scp, .expct=exp} +#define N NO_QOS_PROVIDER_CONF +CU_TheoryDataPoints(qos_provider, create_scope) = { + // The sysdef file with multiple libs/profiles/entity qos. + CU_DataPoints(char *, + N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N), + // The scopes for initialize qos_provider (scope) + // and pattern that all qos in qos_provider should match with (pattern) + // SCOPE(,) + CU_DataPoints(cscope_tokens_t, + SCOPE("*","::"), SCOPE("lib1","lib1::"), SCOPE("lib0::*","lib0::"), + SCOPE("lib0::pro00","lib0::pro00"), SCOPE("lib0::pro00::","lib0::pro00"), + SCOPE("*::","::"), SCOPE("*::pro00::*","::pro00"), SCOPE("::pro00","::pro00"), + SCOPE("*::*::rd0","::rd0"), SCOPE("::::::","::"), SCOPE("::","::"), + SCOPE("::::rd0","::rd0"), SCOPE("lib3",""), SCOPE("lib2::pro10",""), + SCOPE("lib0::pro01::rd0","lib0::pro01::rd0"), SCOPE("lib2::*::tp0","::tp0"), + SCOPE("lib2::*::sb0","lib2::pro03::sb0"), SCOPE("::pro03::rd0", "::pro03::rd0"), + SCOPE("**", "::"), SCOPE("::!:absolutely:***::wrong*scope;", "")), + // The number of expected qos that qos_provider contains when created with (scope) above. + CU_DataPoints(int32_t, + 63, 24, 27, + 7, 7, + 63, 13, 13, + 6, 63, 63, + 6, 0, 0, + 1, 3, + 1, 2, + 63, 0) +}; +#undef N +#undef SCOPE + +struct cscope_inspect_arg +{ + char *scope; + int32_t n; +}; + +static void inspect_qos_items(void *vnode, void *vargs) +{ + dds_qos_item_t *item = (dds_qos_item_t *) vnode; + struct cscope_inspect_arg *arg = (struct cscope_inspect_arg *)vargs; + CU_ASSERT_NOT_EQUAL(strstr(item->full_name, arg->scope), NULL); + --arg->n; +} + +// @brief This tests creating qos_provider with the same sysdef file but with different scope. +CU_Theory((char * configuration, cscope_tokens_t tok, int32_t n),qos_provider, create_scope) +{ + dds_qos_provider_t *provider = NULL; + // init qos provider with given scope + dds_return_t ret = dds_create_qos_provider_scope(configuration, &provider, tok.scope); + CU_ASSERT_EQUAL(ret, DDS_RETCODE_OK); + struct cscope_inspect_arg arg = {.scope = tok.expct, .n = n}; + // examinate qos in qos provider + ddsrt_hh_enum(provider->keyed_qos, inspect_qos_items, &arg); + CU_ASSERT_EQUAL(arg.n, 0); + dds_delete_qos_provider(provider); +} + +#define N NO_QOS_PROVIDER_CONF +#define RD DDS_READER_QOS +#define WR DDS_WRITER_QOS +#define PP DDS_PARTICIPANT_QOS +#define PB DDS_PUBLISHER_QOS +#define SB DDS_SUBSCRIBER_QOS +#define TP DDS_TOPIC_QOS +#define OK DDS_RETCODE_OK +#define BAD DDS_RETCODE_BAD_PARAMETER +CU_TheoryDataPoints(qos_provider, get_qos) = { + // The sysdef file with multiple libs/profiles/entity qos + CU_DataPoints(char *, + N,N,N,N,N,N, + N,N,N,N,N, + N,N,N,N,N), + // Keys which qos we would like to get + CU_DataPoints(char *, + "lib0::pro00","lib0::pro00","lib0::pro00","lib0::pro00","lib0::pro00","lib0::pro00", + "lib0::pro00::pb0","lib2::pro01::sb0","lib0::pro01::rd0","lib0::pro03","lib0::pro03::rd1", + "lib0::pro00","lib0::*","*::pro00::rd1","*","lib2::pro01"), + // Type of entity for which qos we try to get + CU_DataPoints(dds_qos_kind_t, + RD,WR,PP,PB,SB,TP, + PB,SB,RD,RD,RD, + RD,WR,RD,PP,PP), + // Expected retcodes + CU_DataPoints(dds_return_t, + OK,OK,OK,OK,OK,OK, + BAD,BAD,OK,BAD,OK, + OK,BAD,BAD,BAD,BAD) +}; +#undef BAD +#undef OK +#undef TP +#undef SB +#undef PB +#undef PP +#undef WR +#undef RD +#undef N + +CU_Theory((char *configuration, char *key, dds_qos_kind_t kind, dds_return_t code),qos_provider, get_qos) +{ + dds_qos_provider_t *provider = NULL; + // init qos provider with provided configuration + dds_return_t ret = dds_create_qos_provider(configuration, &provider); + CU_ASSERT_EQUAL(ret, DDS_RETCODE_OK); + const dds_qos_t *qos; + // try to get qos with `key`, `kind` + ret = dds_qos_provider_get_qos(provider, kind, key, &qos); + CU_ASSERT_EQUAL(ret, code); + // check that retcode eq to expected + dds_delete_qos_provider(provider); +} + +#define QOS_DURATION_FMT(unit) \ + "<"#unit">%lli" +#define QOS_DURATION_FMT_STR(unit) \ + "<"#unit">%s" +#define QOS_POLICY_DEADLINE_PERIOD_FMT(duration_fmt) \ + ""duration_fmt"" +#define QOS_POLICY_DEADLINE_FMT(unit) \ + ""QOS_POLICY_DEADLINE_PERIOD_FMT(unit)"" +#define QOS_POLICY_DESTINATION_ORDER_FMT(k) \ + ""#k"" +#define QOS_POLICY_DURABILITY_FMT(k) \ + ""#k"" +#define QOS_HISTORY_FMT(hk) \ + ""#hk"%d" +#define QOS_SERVICE_CLEANUP_DELAY_FMT(duration_fmt) \ + ""duration_fmt"" +#define QOS_RESOURCE_LIMITS_MS(ms_f) \ + ""ms_f"" +#define QOS_RESOURCE_LIMITS_MI(mi_f) \ + ""mi_f"" +#define QOS_RESOURCE_LIMITS_MSPI(mspi_f) \ + ""mspi_f"" +#define QOS_RESOURCE_LIMITS \ + "%s%s%s" +#define QOS_DURABILITY_SERVICE_HISTORY(hk) \ + ""#hk"%d" +#define QOS_POLICY_DURABILITY_SERVICE_FMT \ + "%s%s"QOS_RESOURCE_LIMITS"" +#define QOS_POLICY_ENTITYFACTORY_FMT(val) \ + "" \ + ""#val"" \ + "" +#define QOS_BASE64_VALUE \ + "%s" +#define QOS_POLICY_GOUPDATA_FMT \ + ""QOS_BASE64_VALUE"" +#define QOS_POLICY_HISTORY_FMT(hk) \ + QOS_HISTORY_FMT(hk) +#define QOS_POLICY_LATENCYBUDGET_FMT(duration_fmt) \ + ""duration_fmt"" +#define QOS_POLICY_LIFESPAN_FMT(duration_fmt) \ + ""duration_fmt"" +#define QOS_LIVELINESS_KIND(lk) \ + ""#lk"" +#define QOS_LIVELINESS_DURATION(duration_fmt) \ + ""duration_fmt"" +#define QOS_POLICY_LIVELINESS_FMT \ + "%s%s" +#define QOS_POLICY_OWNERSHIP_FMT(ok) \ + ""#ok"" +#define QOS_POLICY_OWNERSHIPSTRENGTH_FMT \ + "%d" +#define QOS_PARTITION_ELEMENT \ + "%s" +#define QOS_POLIC_PARTITION_FMT \ + "%s" +#define QOS_ACCESS_SCOPE_KIND(ask) \ + ""#ask"" +#define QOS_COHERENT_ACCESS(ca) \ + ""#ca"" +#define QOS_ORDERED_ACCESS(oa) \ + ""#oa"" +#define QOS_POLICY_PRESENTATION_FMT \ + "%s%s%s" +#define QOS_RELIABILITY_KIND(rk) \ + ""#rk"" +#define QOS_RELIABILITY_DURATION(duration_fmt) \ + ""duration_fmt"" +#define QOS_POLICY_RELIABILITY_FMT \ + "%s%s" +#define QOS_POLICY_RESOURCE_LIMITS_FMT \ + ""QOS_RESOURCE_LIMITS"" +#define QOS_POLICY_TIMEBASEDFILTER_FMT(duration_fmt) \ + "" \ + duration_fmt \ + "" +#define QOS_POLICY_TOPICDATA_FMT \ + ""QOS_BASE64_VALUE"" +#define QOS_POLICY_TRANSPORTPRIORITY_FMT \ + "%d" +#define QOS_POLICY_USERDATA_FMT \ + ""QOS_BASE64_VALUE"" +#define QOS_NOWRITER_DELAY(duration_fmt) \ + ""duration_fmt"" +#define QOS_DISPOSED_DELAY(duration_fmt) \ + "" \ + duration_fmt \ + "" +#define QOS_POLICY_READERDATALIFECYCLE_FMT \ + "%s%s" +#define QOS_POLICY_WRITERDATA_LIFECYCLE_FMT(aui) \ + "" \ + ""#aui"" \ + "" + +enum duration_unit +{ + sec = 0, + nsec = 1 +}; + +typedef struct sysdef_qos_conf +{ + enum duration_unit deadline_unit; + enum duration_unit durability_serv_unit; + enum duration_unit latency_budget_unit; + enum duration_unit lifespan_unit; + enum duration_unit liveliness_unit; + enum duration_unit reliability_unit; + enum duration_unit time_based_filter_unit; + enum duration_unit reader_data_lifecycle_nowriter_unit; + enum duration_unit reader_data_lifecycle_disposed_unit; +} sysdef_qos_conf_t; + +#define QOS_FORMAT " " +#define CHECK_RET_OK(ret) \ + if (ret < 0) goto fail; +static inline dds_return_t qos_to_conf(dds_qos_t *qos, const sysdef_qos_conf_t *conf, char **out, dds_qos_kind_t kind, uint64_t *validate_mask, const bool ignore_ent) +{ + char *sysdef_qos = ddsrt_strdup(""); + dds_return_t ret = DDS_RETCODE_OK; + if ((ignore_ent || (kind == DDS_TOPIC_QOS || kind == DDS_READER_QOS || kind == DDS_WRITER_QOS)) && + (ret >= 0) && (qos->present & DDSI_QP_DEADLINE)) + { + char *deadline; + if (qos->deadline.deadline == DDS_INFINITY) + { + if (conf->deadline_unit == sec) + ret = ddsrt_asprintf(&deadline, QOS_POLICY_DEADLINE_FMT(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&deadline, QOS_POLICY_DEADLINE_FMT(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->deadline_unit == sec) + ret = ddsrt_asprintf(&deadline, QOS_POLICY_DEADLINE_FMT(QOS_DURATION_FMT(sec)), + (long long)(qos->deadline.deadline/DDS_NSECS_IN_SEC)); + else + ret = ddsrt_asprintf(&deadline, QOS_POLICY_DEADLINE_FMT(QOS_DURATION_FMT(nanosec)), + (long long)qos->deadline.deadline); + } + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, deadline); + ddsrt_free(tmp); + ddsrt_free(deadline); + *validate_mask |= DDSI_QP_DEADLINE; + } + if ((ignore_ent || (kind == DDS_TOPIC_QOS || kind == DDS_READER_QOS || kind == DDS_WRITER_QOS)) && + (ret >= 0) && (qos->present & DDSI_QP_DESTINATION_ORDER)) + { + char *dest_order; + if (qos->destination_order.kind == DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP) + ret = ddsrt_asprintf(&dest_order, "%s", QOS_POLICY_DESTINATION_ORDER_FMT(BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS)); + else + ret = ddsrt_asprintf(&dest_order, "%s", QOS_POLICY_DESTINATION_ORDER_FMT(BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS)); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, dest_order); + ddsrt_free(tmp); + ddsrt_free(dest_order); + *validate_mask |= DDSI_QP_DESTINATION_ORDER; + } + if ((ignore_ent || (kind != DDS_SUBSCRIBER_QOS && kind != DDS_PUBLISHER_QOS && kind != DDS_PARTICIPANT_QOS)) && + (ret >= 0) && (qos->present & DDSI_QP_DURABILITY)) + { + char *durability; + if (qos->durability.kind == DDS_DURABILITY_VOLATILE) + ret = ddsrt_asprintf(&durability, "%s", QOS_POLICY_DURABILITY_FMT(VOLATILE_DURABILITY_QOS)); + else if (qos->durability.kind == DDS_DURABILITY_TRANSIENT_LOCAL) + ret = ddsrt_asprintf(&durability, "%s", QOS_POLICY_DURABILITY_FMT(TRANSIENT_LOCAL_DURABILITY_QOS)); + else if (qos->durability.kind == DDS_DURABILITY_TRANSIENT) + ret = ddsrt_asprintf(&durability, "%s", QOS_POLICY_DURABILITY_FMT(TRANSIENT_DURABILITY_QOS)); + else + ret = ddsrt_asprintf(&durability, "%s", QOS_POLICY_DURABILITY_FMT(PERSISTENT_DURABILITY_QOS)); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, durability); + ddsrt_free(tmp); + ddsrt_free(durability); + *validate_mask |= DDSI_QP_DURABILITY; + } + if ((ignore_ent || (kind == DDS_WRITER_QOS || kind == DDS_TOPIC_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_DURABILITY_SERVICE) + { + char *service_cleanup_delay; + if (qos->durability_service.service_cleanup_delay == DDS_INFINITY) + { + if (conf->durability_serv_unit == sec) + ret = ddsrt_asprintf(&service_cleanup_delay, QOS_SERVICE_CLEANUP_DELAY_FMT(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&service_cleanup_delay, QOS_SERVICE_CLEANUP_DELAY_FMT(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->durability_serv_unit == sec) + ret = ddsrt_asprintf(&service_cleanup_delay, QOS_SERVICE_CLEANUP_DELAY_FMT(QOS_DURATION_FMT(sec)), + (long long)qos->durability_service.service_cleanup_delay/DDS_NSECS_IN_SEC); + else + ret = ddsrt_asprintf(&service_cleanup_delay, QOS_SERVICE_CLEANUP_DELAY_FMT(QOS_DURATION_FMT(nanosec)), + (long long)qos->durability_service.service_cleanup_delay); + } + CHECK_RET_OK(ret); + char *history; + if (qos->durability_service.history.kind == DDS_HISTORY_KEEP_LAST) + ret = ddsrt_asprintf(&history, QOS_DURABILITY_SERVICE_HISTORY(KEEP_LAST_HISTORY_QOS), qos->durability_service.history.depth); + else + ret = ddsrt_asprintf(&history, QOS_DURABILITY_SERVICE_HISTORY(KEEP_ALL_HISTORY_QOS), qos->durability_service.history.depth); + CHECK_RET_OK(ret); + char *durability_service; + int32_t ms,mi,mspi; + ms = qos->durability_service.resource_limits.max_samples; + mi = qos->durability_service.resource_limits.max_instances; + mspi = qos->durability_service.resource_limits.max_samples_per_instance; + char *ms_f,*mi_f,*mspi_f; + (void) ddsrt_asprintf(&ms_f,(ms<0? QOS_RESOURCE_LIMITS_MS(QOS_LENGTH_UNLIMITED): QOS_RESOURCE_LIMITS_MS("%d")), ms); + (void) ddsrt_asprintf(&mi_f,(mi<0? QOS_RESOURCE_LIMITS_MI(QOS_LENGTH_UNLIMITED): QOS_RESOURCE_LIMITS_MI("%d")), mi); + (void) ddsrt_asprintf(&mspi_f,(mspi<0? QOS_RESOURCE_LIMITS_MSPI(QOS_LENGTH_UNLIMITED): QOS_RESOURCE_LIMITS_MSPI("%d")), mspi); + ret = ddsrt_asprintf(&durability_service, QOS_POLICY_DURABILITY_SERVICE_FMT, service_cleanup_delay, history, ms_f, mi_f, mspi_f); + ddsrt_free(ms_f);ddsrt_free(mi_f);ddsrt_free(mspi_f); + ddsrt_free(service_cleanup_delay); + ddsrt_free(history); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, durability_service); + ddsrt_free(tmp); + ddsrt_free(durability_service); + *validate_mask |= DDSI_QP_DURABILITY_SERVICE; + } + if ((ignore_ent || (kind == DDS_PARTICIPANT_QOS || kind == DDS_PUBLISHER_QOS || kind == DDS_SUBSCRIBER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_ADLINK_ENTITY_FACTORY) + { + char *entity_factory; + if (qos->entity_factory.autoenable_created_entities == 0) + ret = ddsrt_asprintf(&entity_factory, "%s", QOS_POLICY_ENTITYFACTORY_FMT(false)); + else + ret = ddsrt_asprintf(&entity_factory, "%s", QOS_POLICY_ENTITYFACTORY_FMT(true)); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, entity_factory); + ddsrt_free(tmp); + ddsrt_free(entity_factory); + *validate_mask |= DDSI_QP_ADLINK_ENTITY_FACTORY; + } + if ((ignore_ent || (kind == DDS_PUBLISHER_QOS || kind == DDS_SUBSCRIBER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_GROUP_DATA) + { + if (qos->group_data.length > 0) + { + char *data = ddsrt_strdup(""); + for (uint32_t i = 0; i < qos->group_data.length; i++) { + char *tmp = data; + ret = ddsrt_asprintf(&data, "%s%c", data, qos->group_data.value[i]); + ddsrt_free(tmp); + CHECK_RET_OK(ret); + } + char *group_data; + ret = ddsrt_asprintf(&group_data, QOS_POLICY_GOUPDATA_FMT, data); + ddsrt_free(data); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, group_data); + ddsrt_free(tmp); + ddsrt_free(group_data); + *validate_mask |= DDSI_QP_GROUP_DATA; + } + } + if ((ignore_ent || (kind == DDS_TOPIC_QOS || kind == DDS_READER_QOS || kind == DDS_WRITER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_HISTORY) + { + char *history; + if (qos->history.kind == DDS_HISTORY_KEEP_LAST) + ret = ddsrt_asprintf(&history, QOS_POLICY_HISTORY_FMT(KEEP_LAST_HISTORY_QOS), qos->history.depth); + else + ret = ddsrt_asprintf(&history, QOS_POLICY_HISTORY_FMT(KEEP_ALL_HISTORY_QOS), qos->history.depth); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, history); + ddsrt_free(tmp); + ddsrt_free(history); + *validate_mask |= DDSI_QP_HISTORY; + } + if ((ignore_ent || (kind == DDS_TOPIC_QOS || kind == DDS_WRITER_QOS || kind == DDS_READER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_LATENCY_BUDGET) + { + char *latency_budget; + if (qos->latency_budget.duration == DDS_INFINITY) + { + if (conf->latency_budget_unit == sec) + ret = ddsrt_asprintf(&latency_budget, QOS_POLICY_LATENCYBUDGET_FMT(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&latency_budget, QOS_POLICY_LATENCYBUDGET_FMT(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->latency_budget_unit == sec) + ret = ddsrt_asprintf(&latency_budget, QOS_POLICY_LATENCYBUDGET_FMT(QOS_DURATION_FMT(sec)), + (long long)qos->latency_budget.duration/DDS_NSECS_IN_SEC); + else + ret = ddsrt_asprintf(&latency_budget, QOS_POLICY_LATENCYBUDGET_FMT(QOS_DURATION_FMT(nanosec)), + (long long)qos->latency_budget.duration); + } + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, latency_budget); + ddsrt_free(tmp); + ddsrt_free(latency_budget); + *validate_mask |= DDSI_QP_LATENCY_BUDGET; + } + if ((ignore_ent || (kind == DDS_WRITER_QOS || kind == DDS_TOPIC_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_LIFESPAN) + { + char *lifespan; + if (qos->lifespan.duration == DDS_INFINITY) + { + if (conf->lifespan_unit == sec) + ret = ddsrt_asprintf(&lifespan, QOS_POLICY_LIFESPAN_FMT(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&lifespan, QOS_POLICY_LIFESPAN_FMT(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->lifespan_unit == sec) + ret = ddsrt_asprintf(&lifespan, QOS_POLICY_LIFESPAN_FMT(QOS_DURATION_FMT(sec)), + (long long)qos->lifespan.duration/DDS_NSECS_IN_SEC); + else + ret = ddsrt_asprintf(&lifespan, QOS_POLICY_LIFESPAN_FMT(QOS_DURATION_FMT(nanosec)), + (long long)qos->lifespan.duration); + } + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, lifespan); + ddsrt_free(tmp); + ddsrt_free(lifespan); + *validate_mask |= DDSI_QP_LIFESPAN; + } + if ((ignore_ent || (kind != DDS_PUBLISHER_QOS && kind != DDS_SUBSCRIBER_QOS && kind != DDS_PARTICIPANT_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_LIVELINESS) + { + char *duration; + if (qos->liveliness.lease_duration == DDS_INFINITY) + { + if (conf->liveliness_unit == sec) + ret = ddsrt_asprintf(&duration, QOS_LIVELINESS_DURATION(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&duration, QOS_LIVELINESS_DURATION(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->liveliness_unit == sec) + ret = ddsrt_asprintf(&duration, QOS_LIVELINESS_DURATION(QOS_DURATION_FMT(sec)), + (long long)qos->liveliness.lease_duration/DDS_NSECS_IN_SEC); + else + ret = ddsrt_asprintf(&duration, QOS_LIVELINESS_DURATION(QOS_DURATION_FMT(nanosec)), + (long long)qos->liveliness.lease_duration); + } + CHECK_RET_OK(ret); + char *liveliness_kind; + if (qos->liveliness.kind == DDS_LIVELINESS_AUTOMATIC) + ret = ddsrt_asprintf(&liveliness_kind, "%s", QOS_LIVELINESS_KIND(AUTOMATIC_LIVELINESS_QOS)); + else if (qos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_PARTICIPANT) + ret = ddsrt_asprintf(&liveliness_kind, "%s", QOS_LIVELINESS_KIND(MANUAL_BY_PARTICIPANT_LIVELINESS_QOS)); + else + ret = ddsrt_asprintf(&liveliness_kind, "%s", QOS_LIVELINESS_KIND(MANUAL_BY_TOPIC_LIVELINESS_QOS)); + CHECK_RET_OK(ret); + char *liveliness; + ret = ddsrt_asprintf(&liveliness, QOS_POLICY_LIVELINESS_FMT, duration, liveliness_kind); + ddsrt_free(duration); + ddsrt_free(liveliness_kind); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, liveliness); + ddsrt_free(tmp); + ddsrt_free(liveliness); + *validate_mask |= DDSI_QP_LIVELINESS; + } + if ((ignore_ent || (kind != DDS_PUBLISHER_QOS && kind != DDS_SUBSCRIBER_QOS && kind != DDS_PARTICIPANT_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_OWNERSHIP) + { + char *ownership; + if (qos->ownership.kind == DDS_OWNERSHIP_SHARED) + ret = ddsrt_asprintf(&ownership, "%s", QOS_POLICY_OWNERSHIP_FMT(SHARED_OWNERSHIP_QOS)); + else + ret = ddsrt_asprintf(&ownership, "%s", QOS_POLICY_OWNERSHIP_FMT(EXCLUSIVE_OWNERSHIP_QOS)); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, ownership); + ddsrt_free(tmp); + ddsrt_free(ownership); + *validate_mask |= DDSI_QP_OWNERSHIP; + } + if ((ignore_ent || (kind == DDS_WRITER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_OWNERSHIP_STRENGTH) + { + char *ownership_strength; + ret = ddsrt_asprintf(&ownership_strength, QOS_POLICY_OWNERSHIPSTRENGTH_FMT, qos->ownership_strength.value); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, ownership_strength); + ddsrt_free(tmp); + ddsrt_free(ownership_strength); + *validate_mask |= DDSI_QP_OWNERSHIP_STRENGTH; + } + if ((ignore_ent || (kind == DDS_PUBLISHER_QOS || kind == DDS_SUBSCRIBER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_PARTITION) + { + if (qos->partition.n > 0) + { + char *part_elems = ddsrt_strdup(""); + for (uint32_t i = 0; i < qos->partition.n; i++) { + char *tmp = part_elems; + ret = ddsrt_asprintf(&part_elems, "%s"QOS_PARTITION_ELEMENT, part_elems, qos->partition.strs[i]); + CHECK_RET_OK(ret); + ddsrt_free(tmp); + } + CHECK_RET_OK(ret); + char *partition; + ret = ddsrt_asprintf(&partition, QOS_POLIC_PARTITION_FMT, part_elems); + ddsrt_free(part_elems); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, partition); + ddsrt_free(tmp); + ddsrt_free(partition); + *validate_mask |= DDSI_QP_PARTITION; + } + } + if ((ignore_ent || (kind == DDS_PUBLISHER_QOS || kind == DDS_SUBSCRIBER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_PRESENTATION) + { + char *access_scope_kind; + if (qos->presentation.access_scope == DDS_PRESENTATION_INSTANCE) + ret = ddsrt_asprintf(&access_scope_kind, QOS_ACCESS_SCOPE_KIND(INSTANCE_PRESENTATION_QOS)); + else if (qos->presentation.access_scope == DDS_PRESENTATION_TOPIC) + ret = ddsrt_asprintf(&access_scope_kind, QOS_ACCESS_SCOPE_KIND(TOPIC_PRESENTATION_QOS)); + else + ret = ddsrt_asprintf(&access_scope_kind, QOS_ACCESS_SCOPE_KIND(GROUP_PRESENTATION_QOS)); + CHECK_RET_OK(ret); + char *coherent_access; + if (qos->presentation.coherent_access) + ret = ddsrt_asprintf(&coherent_access, "%s", QOS_COHERENT_ACCESS(true)); + else + ret = ddsrt_asprintf(&coherent_access, "%s", QOS_COHERENT_ACCESS(false)); + CHECK_RET_OK(ret); + char *ordered_access; + if (qos->presentation.ordered_access) + ret = ddsrt_asprintf(&ordered_access, "%s", QOS_ORDERED_ACCESS(true)); + else + ret = ddsrt_asprintf(&ordered_access, "%s", QOS_ORDERED_ACCESS(false)); + CHECK_RET_OK(ret); + char *presentation; + ret = ddsrt_asprintf(&presentation, QOS_POLICY_PRESENTATION_FMT, access_scope_kind, coherent_access, ordered_access); + ddsrt_free(access_scope_kind); + ddsrt_free(coherent_access); + ddsrt_free(ordered_access); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, presentation); + ddsrt_free(tmp); + ddsrt_free(presentation); + *validate_mask |= DDSI_QP_PRESENTATION; + } + if ((ignore_ent || (kind == DDS_TOPIC_QOS || kind == DDS_READER_QOS || kind == DDS_WRITER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_RELIABILITY) + { + char *max_blocking_time; + if (qos->reliability.max_blocking_time == DDS_INFINITY) + { + if (conf->reliability_unit == sec) + ret = ddsrt_asprintf(&max_blocking_time, QOS_RELIABILITY_DURATION(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&max_blocking_time, QOS_RELIABILITY_DURATION(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->reliability_unit == sec) + ret = ddsrt_asprintf(&max_blocking_time, QOS_RELIABILITY_DURATION(QOS_DURATION_FMT(sec)), + (long long)qos->reliability.max_blocking_time/DDS_NSECS_IN_SEC); + else + ret = ddsrt_asprintf(&max_blocking_time, QOS_RELIABILITY_DURATION(QOS_DURATION_FMT(nanosec)), + (long long)qos->reliability.max_blocking_time); + } + CHECK_RET_OK(ret); + char *reliability_kind; + if (qos->reliability.kind == DDS_RELIABILITY_BEST_EFFORT) + ret = ddsrt_asprintf(&reliability_kind, "%s", QOS_RELIABILITY_KIND(BEST_EFFORT_RELIABILITY_QOS)); + else + ret = ddsrt_asprintf(&reliability_kind, "%s", QOS_RELIABILITY_KIND(RELIABLE_RELIABILITY_QOS)); + CHECK_RET_OK(ret); + char *reliability; + ret = ddsrt_asprintf(&reliability, QOS_POLICY_RELIABILITY_FMT, max_blocking_time, reliability_kind); + ddsrt_free(max_blocking_time); + ddsrt_free(reliability_kind); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, reliability); + ddsrt_free(tmp); + ddsrt_free(reliability); + *validate_mask |= DDSI_QP_RELIABILITY; + } + if ((ignore_ent || (kind == DDS_TOPIC_QOS || kind == DDS_READER_QOS || kind == DDS_WRITER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_RESOURCE_LIMITS) + { + int32_t ms,mi,mspi; + ms = qos->resource_limits.max_samples; + mi = qos->resource_limits.max_instances; + mspi = qos->resource_limits.max_samples_per_instance; + char *ms_f,*mi_f,*mspi_f; + (void) ddsrt_asprintf(&ms_f,(ms<0? QOS_RESOURCE_LIMITS_MS(QOS_LENGTH_UNLIMITED): QOS_RESOURCE_LIMITS_MS("%d")), ms); + (void) ddsrt_asprintf(&mi_f,(mi<0? QOS_RESOURCE_LIMITS_MI(QOS_LENGTH_UNLIMITED): QOS_RESOURCE_LIMITS_MI("%d")), mi); + (void) ddsrt_asprintf(&mspi_f,(mspi<0? QOS_RESOURCE_LIMITS_MSPI(QOS_LENGTH_UNLIMITED): QOS_RESOURCE_LIMITS_MSPI("%d")), mspi); + char *resource_limits; + ret = ddsrt_asprintf(&resource_limits, QOS_POLICY_RESOURCE_LIMITS_FMT, ms_f, mi_f, mspi_f); + ddsrt_free(ms_f);ddsrt_free(mi_f);ddsrt_free(mspi_f); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, resource_limits); + ddsrt_free(tmp); + ddsrt_free(resource_limits); + *validate_mask |= DDSI_QP_RESOURCE_LIMITS; + } + if ((ignore_ent || (kind == DDS_READER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_TIME_BASED_FILTER) + { + char *time_based_filter; + if (qos->time_based_filter.minimum_separation == DDS_INFINITY) + { + if (conf->time_based_filter_unit == sec) + ret = ddsrt_asprintf(&time_based_filter, QOS_POLICY_TIMEBASEDFILTER_FMT(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&time_based_filter, QOS_POLICY_TIMEBASEDFILTER_FMT(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->time_based_filter_unit == sec) + ret = ddsrt_asprintf(&time_based_filter, QOS_POLICY_TIMEBASEDFILTER_FMT(QOS_DURATION_FMT(sec)), + (long long)qos->time_based_filter.minimum_separation/DDS_NSECS_IN_SEC); + else + ret = ddsrt_asprintf(&time_based_filter, QOS_POLICY_TIMEBASEDFILTER_FMT(QOS_DURATION_FMT(nanosec)), + (long long)qos->time_based_filter.minimum_separation); + } + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, time_based_filter); + ddsrt_free(tmp); + ddsrt_free(time_based_filter); + *validate_mask |= DDSI_QP_TIME_BASED_FILTER; + } + if ((ignore_ent || (kind == DDS_TOPIC_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_TOPIC_DATA) + { + if (qos->topic_data.length > 0) + { + char *data = ddsrt_strdup(""); + for (uint32_t i = 0; i < qos->topic_data.length; i++) { + char *tmp = data; + ret = ddsrt_asprintf(&data, "%s%c", data, qos->topic_data.value[i]); + ddsrt_free(tmp); + CHECK_RET_OK(ret); + } + char *topic_data; + ret = ddsrt_asprintf(&topic_data, QOS_POLICY_TOPICDATA_FMT, data); + ddsrt_free(data); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, topic_data); + ddsrt_free(tmp); + ddsrt_free(topic_data); + *validate_mask |= DDSI_QP_TOPIC_DATA; + } + } + if ((ignore_ent || (kind == DDS_TOPIC_QOS || kind == DDS_WRITER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_TRANSPORT_PRIORITY) + { + char *priority; + ret = ddsrt_asprintf(&priority, QOS_POLICY_TRANSPORTPRIORITY_FMT, qos->transport_priority.value); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, priority); + ddsrt_free(tmp); + ddsrt_free(priority); + *validate_mask |= DDSI_QP_TRANSPORT_PRIORITY; + } + if ((ignore_ent || (kind == DDS_PARTICIPANT_QOS || kind == DDS_READER_QOS || kind == DDS_WRITER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_USER_DATA) + { + if (qos->user_data.length > 0) + { + char *data = ddsrt_strdup(""); + for (uint32_t i = 0; i < qos->user_data.length; i++) { + char *tmp = data; + ret = ddsrt_asprintf(&data, "%s%c", data, qos->user_data.value[i]); + ddsrt_free(tmp); + CHECK_RET_OK(ret); + } + char *user_data; + ret = ddsrt_asprintf(&user_data, QOS_POLICY_USERDATA_FMT, data); + ddsrt_free(data); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, user_data); + ddsrt_free(tmp); + ddsrt_free(user_data); + *validate_mask |= DDSI_QP_USER_DATA; + } + } + if ((ignore_ent || (kind == DDS_READER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_ADLINK_READER_DATA_LIFECYCLE) + { + char *nowriter_delay; + if (qos->reader_data_lifecycle.autopurge_nowriter_samples_delay == DDS_INFINITY) + { + if (conf->reader_data_lifecycle_nowriter_unit == sec) + ret = ddsrt_asprintf(&nowriter_delay, QOS_NOWRITER_DELAY(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&nowriter_delay, QOS_NOWRITER_DELAY(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->reader_data_lifecycle_nowriter_unit == sec) + ret = ddsrt_asprintf(&nowriter_delay, QOS_NOWRITER_DELAY(QOS_DURATION_FMT(sec)), + (long long)qos->reader_data_lifecycle.autopurge_nowriter_samples_delay/DDS_NSECS_IN_SEC); + else + ret = ddsrt_asprintf(&nowriter_delay, QOS_NOWRITER_DELAY(QOS_DURATION_FMT(nanosec)), + (long long)qos->reader_data_lifecycle.autopurge_nowriter_samples_delay); + } + CHECK_RET_OK(ret); + char *disposed_delay; + if (qos->reader_data_lifecycle.autopurge_disposed_samples_delay == DDS_INFINITY) + { + if (conf->reader_data_lifecycle_disposed_unit == sec) + ret = ddsrt_asprintf(&disposed_delay, QOS_DISPOSED_DELAY(QOS_DURATION_FMT_STR(sec)), + QOS_DURATION_INFINITY_SEC); + else + ret = ddsrt_asprintf(&disposed_delay, QOS_DISPOSED_DELAY(QOS_DURATION_FMT_STR(nanosec)), + QOS_DURATION_INFINITY_NSEC); + } else { + if (conf->reader_data_lifecycle_disposed_unit == sec) + ret = ddsrt_asprintf(&disposed_delay, QOS_DISPOSED_DELAY(QOS_DURATION_FMT(sec)), + (long long)qos->reader_data_lifecycle.autopurge_disposed_samples_delay/DDS_NSECS_IN_SEC); + else + ret = ddsrt_asprintf(&disposed_delay, QOS_DISPOSED_DELAY(QOS_DURATION_FMT(nanosec)), + (long long)qos->reader_data_lifecycle.autopurge_disposed_samples_delay); + } + CHECK_RET_OK(ret); + char *reader_data_lifecycle; + ret = ddsrt_asprintf(&reader_data_lifecycle, QOS_POLICY_READERDATALIFECYCLE_FMT, nowriter_delay, disposed_delay); + ddsrt_free(nowriter_delay); + ddsrt_free(disposed_delay); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, reader_data_lifecycle); + ddsrt_free(tmp); + ddsrt_free(reader_data_lifecycle); + *validate_mask |= DDSI_QP_ADLINK_READER_DATA_LIFECYCLE; + } + if ((ignore_ent || (kind == DDS_WRITER_QOS)) && + (ret >= 0) && qos->present & DDSI_QP_ADLINK_WRITER_DATA_LIFECYCLE) + { + char *writer_data_lifecycle; + if (qos->writer_data_lifecycle.autodispose_unregistered_instances) + ret = ddsrt_asprintf(&writer_data_lifecycle, "%s", QOS_POLICY_WRITERDATA_LIFECYCLE_FMT(true)); + else + ret = ddsrt_asprintf(&writer_data_lifecycle, "%s", QOS_POLICY_WRITERDATA_LIFECYCLE_FMT(false)); + CHECK_RET_OK(ret); + char *tmp = sysdef_qos; + ret = ddsrt_asprintf(&sysdef_qos, QOS_FORMAT"%s\n"QOS_FORMAT"%s", sysdef_qos, writer_data_lifecycle); + ddsrt_free(tmp); + ddsrt_free(writer_data_lifecycle); + *validate_mask |= DDSI_QP_ADLINK_WRITER_DATA_LIFECYCLE; + } + + *out = sysdef_qos; +fail: + return ret; +} + +#undef QOS_FORMAT + +static dds_qos_t get_supported_qos(dds_qos_t qos) +{ + qos.present &= ~DDSI_QP_ADLINK_ENTITY_FACTORY; + return qos; +} + +static dds_return_t get_single_configuration(dds_qos_t *qos, sysdef_qos_conf_t *conf, dds_qos_kind_t kind, char **out_conf, uint64_t *validate_mask) +{ + dds_return_t ret = DDS_RETCODE_OK; + char *qos_conf = NULL; + ret = qos_to_conf(qos, conf, &qos_conf, kind, validate_mask, false); + CU_ASSERT_TRUE(ret >= 0); + char *def = NULL; + switch(kind) + { + case DDS_PARTICIPANT_QOS: + def = DEF(LIB(lib1,PRO(pro00,ENT("%s",domain_participant)))); + break; + case DDS_PUBLISHER_QOS: + def = DEF(LIB(lib1,PRO(pro00,ENT("%s",publisher)))); + break; + case DDS_SUBSCRIBER_QOS: + def = DEF(LIB(lib1,PRO(pro00,ENT("%s",subscriber)))); + break; + case DDS_TOPIC_QOS: + def = DEF(LIB(lib1,PRO(pro00,ENT("%s",topic)))); + break; + case DDS_READER_QOS: + def = DEF(LIB(lib1,PRO(pro00,ENT("%s",datareader)))); + break; + case DDS_WRITER_QOS: + def = DEF(LIB(lib1,PRO(pro00,ENT("%s",datawriter)))); + break; + default: + ddsrt_free(qos_conf); + CU_FAIL("unsupported QOS_KIND"); + } + ret = ddsrt_asprintf(out_conf, def, qos_conf); + ddsrt_free(qos_conf); + CU_ASSERT_TRUE(ret >= 0); + + return ret; +} + +#define N nsec +#define S sec +CU_TheoryDataPoints(qos_provider, get_qos_default) = { + // The type of entity_qos that will be tested with it default qos. + CU_DataPoints(dds_qos_kind_t, + DDS_TOPIC_QOS,DDS_READER_QOS,DDS_WRITER_QOS), + // In which format / `duration` will be presented in sysdef file. + CU_DataPoints(sysdef_qos_conf_t, + {N,N,S,S,N,N,S,S,N},{S,S,S,S,S,N,S,S,N},{S,N,S,N,S,N,S,N,S}, + ), +}; +#undef N +#undef S + +// @brief This test check sysdef file qos created correctly by qos_provider (in this case with default qos). +CU_Theory((dds_qos_kind_t kind, sysdef_qos_conf_t dur_conf), qos_provider, get_qos_default) +{ + dds_return_t ret = DDS_RETCODE_OK; + char *full_configuration = NULL; + dds_qos_t qos; + switch(kind) + { + case DDS_PARTICIPANT_QOS: + qos = get_supported_qos(ddsi_default_qos_participant); + break; + case DDS_PUBLISHER_QOS: + qos = get_supported_qos(ddsi_default_qos_publisher_subscriber); + break; + case DDS_SUBSCRIBER_QOS: + qos = get_supported_qos(ddsi_default_qos_publisher_subscriber); + break; + case DDS_TOPIC_QOS: + qos = get_supported_qos(ddsi_default_qos_topic); + break; + case DDS_READER_QOS: + qos = get_supported_qos(ddsi_default_qos_reader); + break; + case DDS_WRITER_QOS: + qos = get_supported_qos(ddsi_default_qos_writer); + break; + default: + CU_FAIL("oops"); + break; + } + uint64_t validate_mask = 0; + // init configuraiton with qos of `kind` in sysdef format + ret = get_single_configuration(&qos, &dur_conf, kind, &full_configuration, &validate_mask); + CU_ASSERT_TRUE(ret >= 0); + dds_qos_provider_t *provider; + // init qos provider with create configuration + ret = dds_create_qos_provider(full_configuration, &provider); + ddsrt_free(full_configuration); + CU_ASSERT_EQUAL(ret, DDS_RETCODE_OK); + const dds_qos_t *act_qos; + // get qos from provider + ret = dds_qos_provider_get_qos(provider, kind, "lib1::pro00", &act_qos); + CU_ASSERT_EQUAL(ret, DDS_RETCODE_OK); + // calculate the difference between defined qos and qos from provider + uint64_t res = ddsi_xqos_delta(&qos, act_qos, validate_mask); + CU_ASSERT_EQUAL(act_qos->present, validate_mask); + CU_ASSERT_EQUAL(res, 0); + dds_delete_qos_provider(provider); + +} + +#define _C "abcdefghijklmnopqrstuvwxyz" +#define RND_UCHAR (unsigned char)(_C[ddsrt_random () % (uint32_t)(strlen(_C)-1)]) +#define RND_UCHAR3 (unsigned char[]){RND_UCHAR, RND_UCHAR, RND_UCHAR} +#define RND_CHAR (char)(_C[ddsrt_random () % (uint32_t)(strlen(_C)-1)]) +#define RND_CHAR4 (char[]){RND_CHAR, RND_CHAR, RND_CHAR, '\0'} +#define RND_CHAR3x4 (char *[]){RND_CHAR4, RND_CHAR4, RND_CHAR4} + +#define Q_DATA4(kind) .kind##_data={.value=RND_UCHAR3,.length=3}, +#define Q_DURABILITY(knd) .durability={.kind=knd}, +#define Q_DEADLINE(tm) .deadline={.deadline=tm}, +#define Q_LATENCYBUDGET(tm) .latency_budget={.duration=tm}, +#define Q_OWNERSHIP(knd) .ownership={.kind=knd}, +#define Q_LIVELINESS(knd,dur) .liveliness={.kind=knd,.lease_duration=dur}, +#define Q_RELIABILITY(knd,tm) .reliability={.kind=knd,.max_blocking_time=tm}, +#define Q_TRANSPORTPRIO(vl) .transport_priority={.value=vl}, +#define Q_LIFESPAN(dur) .lifespan={.duration=dur}, +#define Q_DESTINATIONORDER(knd) .destination_order={.kind=knd}, +#define Q_HISTORY(knd,dp) .history={.kind=knd,.depth=dp}, +#define Q_RESOURCELIMITS(ms,mi,mspmi) .resource_limits={.max_samples=ms,.max_instances=mi,.max_samples_per_instance=mspmi}, +#define Q_DATA3x4(kind) .kind={.strs=RND_CHAR3x4,.n=3}, +#define Q_PRESENATION(ask,oa,ca) .presentation={.access_scope=ask,.ordered_access=oa,.coherent_access=ca}, +#define Q_TIMEBASEDFILTER(dur) .time_based_filter={.minimum_separation=dur}, +#define Q_READERLIFECYCLE(adsd,ansd) .reader_data_lifecycle={.autopurge_disposed_samples_delay=adsd,.autopurge_nowriter_samples_delay=ansd}, +#define Q_OWNERSHIPSTRENGTH(vl) .ownership_strength={.value=vl}, +#define Q_WRITERLIFECYCLE(aui) .writer_data_lifecycle={.autodispose_unregistered_instances=aui}, +#define Q_DURABILITYSERVICE(dur,hk,hd,ms,mi,mspi) .durability_service={.service_cleanup_delay=dur,Q_HISTORY(hk,hd)Q_RESOURCELIMITS(ms,mi,mspi)}, + +#define QOS_ALL_PRESENT .present = DDSI_QP_TOPIC_DATA | DDSI_QP_DURABILITY | \ + DDSI_QP_DEADLINE | DDSI_QP_LATENCY_BUDGET | \ + DDSI_QP_OWNERSHIP | DDSI_QP_LIVELINESS | \ + DDSI_QP_RELIABILITY | DDSI_QP_TRANSPORT_PRIORITY | \ + DDSI_QP_LIFESPAN | DDSI_QP_DESTINATION_ORDER | \ + DDSI_QP_HISTORY | DDSI_QP_RESOURCE_LIMITS | \ + DDSI_QP_USER_DATA | DDSI_QP_PARTITION | \ + DDSI_QP_PRESENTATION | DDSI_QP_GROUP_DATA | \ + DDSI_QP_TIME_BASED_FILTER | DDSI_QP_ADLINK_READER_DATA_LIFECYCLE | \ + DDSI_QP_OWNERSHIP_STRENGTH | DDSI_QP_ADLINK_WRITER_DATA_LIFECYCLE | \ + DDSI_QP_DURABILITY_SERVICE, + +#define QOS_ALL_BASE { \ + QOS_ALL_PRESENT \ + Q_DATA4(topic)Q_DURABILITY(DDS_DURABILITY_VOLATILE) \ + Q_DEADLINE(DDS_SECS(1))Q_LATENCYBUDGET(DDS_SECS(1)) \ + Q_OWNERSHIP(DDS_OWNERSHIP_EXCLUSIVE)Q_LIVELINESS(DDS_LIVELINESS_AUTOMATIC,DDS_INFINITY) \ + Q_RELIABILITY(DDS_RELIABILITY_RELIABLE, DDS_SECS(1))Q_TRANSPORTPRIO(1000) \ + Q_LIFESPAN(DDS_SECS(1))Q_DESTINATIONORDER(DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP) \ + Q_HISTORY(DDS_HISTORY_KEEP_LAST,1)Q_RESOURCELIMITS(1,1,1) \ + Q_DATA4(user)Q_DATA3x4(partition) \ + Q_PRESENATION(DDS_PRESENTATION_TOPIC,1,1)Q_DATA4(group) \ + Q_TIMEBASEDFILTER(DDS_SECS(1))Q_READERLIFECYCLE(DDS_SECS(1), DDS_SECS(1)) \ + Q_OWNERSHIPSTRENGTH(100)Q_WRITERLIFECYCLE(1) \ + Q_DURABILITYSERVICE(DDS_SECS(1),DDS_HISTORY_KEEP_ALL,-1,1,1,1) \ + } + +CU_TheoryDataPoints(qos_provider, get_qos_all) = { + // The type of entity_qos that will be tested with custom qos. + CU_DataPoints(dds_qos_kind_t, + DDS_PARTICIPANT_QOS,DDS_PUBLISHER_QOS,DDS_SUBSCRIBER_QOS, + DDS_TOPIC_QOS,DDS_READER_QOS,DDS_WRITER_QOS), +}; + +#define Q QOS_ALL_BASE +// @brief This test check sysdef file qos created correctly by qos_provider +// (in this case with custom qos with all possible values presented). +CU_Theory((dds_qos_kind_t kind),qos_provider, get_qos_all) +{ + dds_return_t ret = DDS_RETCODE_OK; + char *full_configuration = NULL; + dds_qos_t qos = Q; + sysdef_qos_conf_t dur_conf = {sec,sec,sec,sec,sec,sec,sec,sec,sec}; + uint64_t validate_mask = 0; + // init configuraiton with qos of `kind` in sysdef format + ret = get_single_configuration(&qos, &dur_conf, kind, &full_configuration, &validate_mask); + CU_ASSERT_TRUE(ret >= 0); + dds_qos_provider_t *provider; + // init qos provider with create configuration + ret = dds_create_qos_provider(full_configuration, &provider); + ddsrt_free(full_configuration); + CU_ASSERT_EQUAL(ret, DDS_RETCODE_OK); + const dds_qos_t *act_qos; + ret = dds_qos_provider_get_qos(provider, kind, "lib1::pro00", &act_qos); + CU_ASSERT_EQUAL(ret, DDS_RETCODE_OK); + // calculate the difference between defined qos and qos from provider + uint64_t res = ddsi_xqos_delta(&qos, act_qos, validate_mask); + CU_ASSERT_EQUAL(act_qos->present, validate_mask); + CU_ASSERT_EQUAL(res, 0); + dds_delete_qos_provider(provider); +} + +CU_TheoryDataPoints(qos_provider, create_wrong_qos) = { + // The type of entity_qos that will be tested with wrong qos + CU_DataPoints(dds_qos_kind_t, + DDS_PARTICIPANT_QOS,DDS_PUBLISHER_QOS,DDS_SUBSCRIBER_QOS, + DDS_TOPIC_QOS,DDS_READER_QOS,DDS_WRITER_QOS), + // Expected retcodes + CU_DataPoints(dds_return_t, + DDS_RETCODE_ERROR,DDS_RETCODE_ERROR,DDS_RETCODE_ERROR, + DDS_RETCODE_ERROR,DDS_RETCODE_ERROR,DDS_RETCODE_ERROR), +}; + +#define QOS_TO_CONF_SNGL(excl_msk,knd) \ + def = DEF(LIB(lib1,PRO(pro00,ENT("%s",knd)))); \ + qos.present ^= (excl_msk); \ + ret = qos_to_conf(&qos, &conf, &qos_conf, kind, &validate_mask, true); + +CU_Theory((dds_qos_kind_t kind, dds_return_t code),qos_provider, create_wrong_qos) +{ + dds_return_t ret = DDS_RETCODE_OK; + char *full_configuration = NULL; + dds_qos_t qos = Q; + sysdef_qos_conf_t conf = {sec,sec,sec,sec,sec,sec,sec,sec,sec}; + uint64_t validate_mask = 0; + char *def = NULL; + char *qos_conf = NULL; + // init sysdef configuration that contains qos that not related for this `kind` of entity + // (wrong for this entity kind) + switch(kind) + { + case DDS_PARTICIPANT_QOS: + QOS_TO_CONF_SNGL(DDS_PARTICIPANT_QOS_MASK,domain_participant); + break; + case DDS_PUBLISHER_QOS: + QOS_TO_CONF_SNGL(DDS_PUBLISHER_QOS_MASK,publisher); + break; + case DDS_SUBSCRIBER_QOS: + QOS_TO_CONF_SNGL(DDS_SUBSCRIBER_QOS_MASK,subscriber); + break; + case DDS_TOPIC_QOS: + QOS_TO_CONF_SNGL(DDS_TOPIC_QOS_MASK,topic); + break; + case DDS_READER_QOS: + QOS_TO_CONF_SNGL(DDS_READER_QOS_MASK,datareader); + break; + case DDS_WRITER_QOS: + QOS_TO_CONF_SNGL(DDS_WRITER_QOS_MASK,datawriter); + break; + default: + CU_FAIL("unsupported QOS_KIND"); + } + CU_ASSERT_TRUE(ret >= 0); + ret = ddsrt_asprintf(&full_configuration, def, qos_conf); + ddsrt_free(qos_conf); + CU_ASSERT_TRUE(ret >= 0); + dds_qos_provider_t *provider = NULL; + // init qos provider with create configuration + ret = dds_create_qos_provider(full_configuration, &provider); + ddsrt_free(full_configuration); + // check that retcode eq to expected + CU_ASSERT_EQUAL(ret, code); + // provider not initialized + CU_ASSERT_PTR_NULL(provider); +} +#undef QOS_TO_CONF_SNGL +#undef Q diff --git a/src/core/xtests/symbol_export/symbol_export.c b/src/core/xtests/symbol_export/symbol_export.c index c425a740d5..a6ef6a4970 100644 --- a/src/core/xtests/symbol_export/symbol_export.c +++ b/src/core/xtests/symbol_export/symbol_export.c @@ -63,6 +63,10 @@ #include "dds/security/core/dds_security_shared_secret.h" #endif +#ifdef DDS_HAS_QOS_PROVIDER +#include "dds/ddsc/dds_public_qos_provider.h" +#endif + #include "dds/ddsc/dds_internal_api.h" #include "dds/ddsc/dds_loaned_sample.h" #include "dds/ddsc/dds_rhc.h" @@ -615,6 +619,13 @@ int main (int argc, char **argv) DDS_Security_get_secret_size_from_secret_handle (1); #endif +#ifdef DDS_HAS_QOS_PROVIDER + dds_create_qos_provider(ptr,ptr); + dds_create_qos_provider_scope(ptr,ptr,ptr); + dds_qos_provider_get_qos(ptr,0,ptr,ptr); + dds_delete_qos_provider(ptr); +#endif + // ddsi_sertype.h struct dds_type_consistency_enforcement_qospolicy tce = { 0, false, false, false, false, false }; ddsi_sertype_v0 (ptr); diff --git a/src/ddsrt/CMakeLists.txt b/src/ddsrt/CMakeLists.txt index 94a724760b..441a5fbfdb 100644 --- a/src/ddsrt/CMakeLists.txt +++ b/src/ddsrt/CMakeLists.txt @@ -311,7 +311,7 @@ set(DDSRT_WITH_LWIP ${WITH_LWIP}) set(DDSRT_WITH_FREERTOS ${WITH_FREERTOS}) foreach(feature TCP_TLS SECURITY LIFESPAN DEADLINE_MISSED NETWORK_PARTITIONS - SSM TYPELIB TYPE_DISCOVERY TOPIC_DISCOVERY) + SSM TYPELIB TYPE_DISCOVERY TOPIC_DISCOVERY QOS_PROVIDER) set(DDS_HAS_${feature} ${ENABLE_${feature}}) endforeach() diff --git a/src/ddsrt/include/dds/ddsrt/log.h b/src/ddsrt/include/dds/ddsrt/log.h index 42f905f508..8e05864ff4 100644 --- a/src/ddsrt/include/dds/ddsrt/log.h +++ b/src/ddsrt/include/dds/ddsrt/log.h @@ -78,6 +78,10 @@ extern "C" { #define DDS_LC_CONTENT (131072u) /** Output full dump of malformed messages as warnings */ #define DDS_LC_MALFORMED (262144u) +/** Debug/trace messages related to sysdef parser. */ +#define DDS_LC_SYSDEF (524288u) +/** Debug/trace messages related to qos provider. */ +#define DDS_LC_QOSPROV (1048576u) /** All common trace categories. */ #define DDS_LC_ALL \ (DDS_LC_FATAL | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_INFO | \ diff --git a/src/ddsrt/include/dds/features.h.in b/src/ddsrt/include/dds/features.h.in index 9f687d405d..1320863aaf 100644 --- a/src/ddsrt/include/dds/features.h.in +++ b/src/ddsrt/include/dds/features.h.in @@ -44,4 +44,8 @@ /* Not intended for general use, whether building a static library, specifically testing psmx and security */ #cmakedefine DDS_IS_STATIC_LIBRARY 1 +/* Whether or not support for qos provider is included */ +#cmakedefine DDS_HAS_QOS_PROVIDER 1 + + #endif From cb46d84fa022f9df9104c4e7019043fbfb4d8c29 Mon Sep 17 00:00:00 2001 From: Robert Femmer Date: Wed, 3 Apr 2024 14:02:36 +0000 Subject: [PATCH 060/207] fuzz_handshake: now builds in the oss-fuzz docker container --- fuzz/fuzz_handshake/CMakeLists.txt | 7 +++++++ fuzz/fuzz_handshake/prepare.sh | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/fuzz/fuzz_handshake/CMakeLists.txt b/fuzz/fuzz_handshake/CMakeLists.txt index bd2d293ed4..b7d7b76403 100644 --- a/fuzz/fuzz_handshake/CMakeLists.txt +++ b/fuzz/fuzz_handshake/CMakeLists.txt @@ -27,9 +27,13 @@ add_library(fuzz_handshake_harness fuzz_handshake_harness.c) target_include_directories( fuzz_handshake_harness PRIVATE "$" + "$" "$" + "$" "$" "$" + "$" + "$" "$" "$" "$" @@ -46,6 +50,8 @@ target_include_directories( "$" "$") + +find_package(OpenSSL REQUIRED) target_link_libraries(fuzz_handshake fuzz_handshake_harness ${CMAKE_BINARY_DIR}/../LPM/src/libfuzzer/libprotobuf-mutator-libfuzzer.a @@ -53,4 +59,5 @@ target_link_libraries(fuzz_handshake protobuf::libprotobuf CycloneDDS::ddsc $ENV{LIB_FUZZING_ENGINE} + OpenSSL::SSL stdc++) diff --git a/fuzz/fuzz_handshake/prepare.sh b/fuzz/fuzz_handshake/prepare.sh index 5b463f41d9..630aefacdd 100644 --- a/fuzz/fuzz_handshake/prepare.sh +++ b/fuzz/fuzz_handshake/prepare.sh @@ -15,4 +15,4 @@ prepare_fuzz_handshake() { } export -f prepare_fuzz_handshake -env -u CFLAGS -u LIB_FUZZING_ENGINE CXXFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -stdlib=libc++" bash -euc prepare_fuzz_handshake +env -u CFLAGS -u CXXFLAGS -u LIB_FUZZING_ENGINE CXXFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -stdlib=libc++" bash -euc prepare_fuzz_handshake From 44ca08e0c200ee6188373c8bc5c17edcf06c0b54 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 4 Apr 2024 13:28:29 +0200 Subject: [PATCH 061/207] Fix padding issue in authentication plugin The discovery data is to be serialized as a parameter list, serialising each parameter in turn as a 4-byte aligned, 32-bit header followed by arbitrary payload, itself serialised according to the rules of the original CDR spec (i.e., XCDR1 in XTypes' Newspeak) as-if that payload starts at offset 0. There is never any padding other than that required by these rules. The code for handling strings and octet sequences used by the authentication plugin got this wrong by (inconsistently) padding out strings and octet sequences to the next multiple of 4. In the deserialization this also interferes with the bounds checking. In principle this can lead to a failure to read/write well-formed discovery data. In practice, the types happen to be such that that padding always ends up being present because of the next field. Signed-off-by: Erik Boasson --- .../core/src/dds_security_serialize.c | 35 ++++-------- src/security/core/tests/CMakeLists.txt | 1 + src/security/core/tests/deserialize.c | 57 +++++++++++++++++++ 3 files changed, 68 insertions(+), 25 deletions(-) create mode 100644 src/security/core/tests/deserialize.c diff --git a/src/security/core/src/dds_security_serialize.c b/src/security/core/src/dds_security_serialize.c index 4ed26f439a..1a8c4faa84 100644 --- a/src/security/core/src/dds_security_serialize.c +++ b/src/security/core/src/dds_security_serialize.c @@ -250,7 +250,6 @@ DDS_Security_Serialize_string( memcpy(&(ser->buffer[ser->offset]), str, len); ser->offset += len; - serbuffer_align(ser, sizeof(uint32_t)); } static void @@ -553,8 +552,6 @@ DDS_Security_Deserialize_string( if (sz > 0 && (dser->cursor[sz-1] == 0)) { *value = ddsrt_strdup((char *)dser->cursor); - /* Consider padding */ - sz = alignup_size(sz, sizeof(uint32_t)); dser->cursor += sz; dser->remain -= sz; } else { @@ -593,12 +590,10 @@ DDS_Security_Deserialize_OctetSeq( } if (seq->_length > 0) { - /* Consider padding */ - size_t a_size = alignup_size(seq->_length, sizeof(uint32_t)); seq->_buffer = ddsrt_malloc(seq->_length); memcpy(seq->_buffer, dser->cursor, seq->_length); - dser->cursor += a_size; - dser->remain -= a_size; + dser->cursor += seq->_length; + dser->remain -= seq->_length; } else { seq->_buffer = NULL; } @@ -749,10 +744,13 @@ DDS_Security_Deserialize_ParticipantBuiltinTopicData( DDS_Security_Deserialize_align(dser, 4); r = DDS_Security_Deserialize_uint16(dser, &pid) && DDS_Security_Deserialize_uint16(dser, &len); - - if (r && (len <= dser->remain)) { - const unsigned char *next_cursor = dser->cursor + len; - + if (!r) { + DDS_Security_Exception_set(ex, "Deserialization", DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, + "Deserialize parameter header failed"); + } else if (len > dser->remain) { + DDS_Security_Exception_set(ex, "Deserialization", DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, + "Deserialize parameter failed: payload too long for buffer"); + } else { switch (pid) { case PID_PARTICIPANT_GUID: r = DDS_Security_Deserialize_BuiltinTopicKey(dser, pdata->key); @@ -780,25 +778,12 @@ DDS_Security_Deserialize_ParticipantBuiltinTopicData( dser->remain -= len; break; } - - if (r) { - if (dser->cursor != next_cursor) { - DDS_Security_Exception_set(ex, "Deserialization", DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "Deserialize PID 0x%x failed: internal_size %d != external_size %d", pid, (int)len + (int)(dser->cursor - next_cursor), (int)len); - r = 0; - } - } else { - DDS_Security_Exception_set(ex, "Deserialization", DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "Deserialize PID 0x%x failed: parsing failed", pid); - } - } else { if (!r) { DDS_Security_Exception_set(ex, "Deserialization", DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "Deserialize parameter header failed"); + "Deserialize PID 0x%x failed: parsing failed", pid); } } } while (r && !ready && dser->remain > 0); - return ready; } diff --git a/src/security/core/tests/CMakeLists.txt b/src/security/core/tests/CMakeLists.txt index f934a23a93..a8a3b90e39 100644 --- a/src/security/core/tests/CMakeLists.txt +++ b/src/security/core/tests/CMakeLists.txt @@ -115,6 +115,7 @@ if(ENABLE_SSL AND OPENSSL_FOUND) "builtintopic.c" "config.c" "crypto.c" + "deserialize.c" "handshake.c" "plugin_loading.c" "secure_communication.c" diff --git a/src/security/core/tests/deserialize.c b/src/security/core/tests/deserialize.c new file mode 100644 index 0000000000..33b278f64d --- /dev/null +++ b/src/security/core/tests/deserialize.c @@ -0,0 +1,57 @@ +// Copyright(c) 2024 Robert Femmer +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause +#include "CUnit/CUnit.h" +#include "CUnit/Test.h" + +#include "dds/security/core/dds_security_serialize.h" +#include "dds/ddsrt/heap.h" + +CU_Test(dds_security_serialize, deserialize_octet_seq) +{ + unsigned char heapdata[] = + { + // transformation_kind (OctetArray) 4 bytes + 0x0, 0x0, 0x0, 0x0, + // master_salt (OctetSeq) + // length of octet seq + 0x0, 0x0, 0x0, 0x1, + // the octet sequence + 0x0, + // This is all the data we attempt to deserialize + // Three padding bytes that the deserializer will skip + 0x0, 0x0, 0x0, + // Suppose unknown heap memory starts here. This would be parsed into sender_key_id + 0x0, 0x0, 0x0, 0x0, + // This would be the length of the next master_send_key. + 0x0, 0x0, 0x0, 0x0, + // Next would be receiver_specific_key_id. + 0x0, 0x0, 0x0, 0x0, + // master_receiver_specific_key OctetSeq. This could be any size up to 4GB, which will be allocated. + // Here, we allocate 16 bytes, which is longer than the 9 bytes we feed to the deserializer. + 0x0, 0x0, 0x0, 0x10, + // the key + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + }; + + // Pass the pointer to the prepared buffer and claim that length is only 9 bytes. + DDS_Security_Deserializer dser = DDS_Security_Deserializer_new(heapdata, 9); + DDS_Security_KeyMaterial_AES_GCM_GMAC data; + int r = DDS_Security_Deserialize_KeyMaterial_AES_GCM_GMAC(dser, &data); + // This should fail, because 9 bytes is not enough to deserialize the key material + CU_ASSERT_EQUAL(r, 0); + // Specifically, master_receiver_specific_key._buffer should be NULL, because + // the octet sequence itself is longer than the serialized data according to dser->remain + CU_ASSERT_EQUAL(data.master_receiver_specific_key._buffer, NULL); + + ddsrt_free(data.master_salt._buffer); + ddsrt_free(data.master_sender_key._buffer); + ddsrt_free(data.master_receiver_specific_key._buffer); + DDS_Security_Deserializer_free(dser); +} From c82c2236bc2d267dd17ad7b83c17a28e9c9d4b88 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Thu, 4 Apr 2024 22:39:19 +0200 Subject: [PATCH 062/207] First attempt to add CM interface to the idl Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 13 ++++ src/durability/src/durablesupport.c | 77 +++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index 0e5aaf84da..fc42a5a26f 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -257,6 +257,19 @@ extern const dds_topic_descriptor_t DurableSupport_bead_desc; #define DurableSupport_bead_free(d,o) \ dds_sample_free ((d), &DurableSupport_bead_desc, (o)) +typedef struct DurableSupport_control +{ + DurableSupport_id_t id; +} DurableSupport_control; + +extern const dds_topic_descriptor_t DurableSupport_control_desc; + +#define DurableSupport_control__alloc() \ +((DurableSupport_control*) dds_alloc (sizeof (DurableSupport_control))); + +#define DurableSupport_control_free(d,o) \ +dds_sample_free ((d), &DurableSupport_control_desc, (o)) + typedef int64_t DurableSupport_duration_t; #define DurableSupport_duration_t__alloc() \ diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index 44413aaa4f..63a895fcf0 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -622,6 +622,83 @@ const dds_topic_descriptor_t DurableSupport_bead_desc = .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_bead, .sz = TYPE_MAP_CDR_SZ_DurableSupport_bead } }; +static const uint32_t DurableSupport_control_ops [] = +{ + /* control */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_control, id), 16u, + DDS_OP_RTS, + + /* key: id */ + DDS_OP_KOF | 1, 1u /* order: 0 */ +}; + +static const dds_key_descriptor_t DurableSupport_control_keys[1] = +{ + { "id", 5, 0 } +}; + +/* Type Information: + [MINIMAL cb0d133f4534082d16d026f85046] (#deps: 1) + - [MINIMAL 43f53a2be35b432cc735e9431a89] + [COMPLETE 59d57c820de779413f0c29ca47e1] (#deps: 1) + - [COMPLETE aca4d5a256d39713924333e85c6d] +*/ +#define TYPE_INFO_CDR_DurableSupport_control (const unsigned char []){ \ + 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0xcb, 0x0d, 0x13, 0x3f, 0x45, 0x34, 0x08, 0x2d, 0x16, 0xd0, 0x26, \ + 0xf8, 0x50, 0x46, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x59, 0xd5, 0x7c, \ + 0x82, 0x0d, 0xe7, 0x79, 0x41, 0x3f, 0x0c, 0x29, 0xca, 0x47, 0xe1, 0x00, 0x59, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ + 0x40, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_control 148u +#define TYPE_MAP_CDR_DurableSupport_control (const unsigned char []){ \ + 0x76, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0xcb, 0x0d, 0x13, 0x3f, 0x45, 0x34, 0x08, \ + 0x2d, 0x16, 0xd0, 0x26, 0xf8, 0x50, 0x46, 0x00, 0x31, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ + 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0xf2, 0x59, 0xd5, 0x7c, 0x82, 0x0d, 0xe7, 0x79, 0x41, 0x3f, 0x0c, 0x29, \ + 0xca, 0x47, 0xe1, 0x00, 0x55, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x00, \ + 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, \ + 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x3c, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0xf2, 0x59, 0xd5, 0x7c, 0x82, 0x0d, 0xe7, 0x79, 0x41, 0x3f, 0x0c, 0x29, \ + 0xca, 0x47, 0xe1, 0xf1, 0xcb, 0x0d, 0x13, 0x3f, 0x45, 0x34, 0x08, 0x2d, 0x16, 0xd0, 0x26, 0xf8, \ + 0x50, 0x46, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_control 384u +const dds_topic_descriptor_t DurableSupport_control_desc = +{ + .m_size = sizeof (DurableSupport_control), + .m_align = dds_alignof (DurableSupport_control), + .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 1u, + .m_typename = "DurableSupport::control", + .m_keys = DurableSupport_control_keys, + .m_nops = 3, + .m_ops = DurableSupport_control_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_control, .sz = TYPE_INFO_CDR_SZ_DurableSupport_control }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_control, .sz = TYPE_MAP_CDR_SZ_DurableSupport_control } +}; + static const uint32_t DurableSupport_request_ops [] = { /* request */ From 186f3efb2e1a9b527397425b15baa7c0cb48562c Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 4 Apr 2024 15:33:25 +0200 Subject: [PATCH 063/207] Delete some left-over code Hasn't been necessary since 0845337, so for 4 years. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_gc.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/core/ddsi/src/ddsi_gc.c b/src/core/ddsi/src/ddsi_gc.c index 4df45d7564..68d925c306 100644 --- a/src/core/ddsi/src/ddsi_gc.c +++ b/src/core/ddsi/src/ddsi_gc.c @@ -103,7 +103,6 @@ static uint32_t gcreq_queue_thread (struct ddsi_gcreq_queue *q) { struct ddsi_thread_state * const thrst = ddsi_lookup_thread_state (); ddsrt_mtime_t next_thread_cputime = { 0 }; - ddsrt_mtime_t t_ddsi_trigger_recv_threads = { 0 }; int64_t shortsleep = DDS_MSECS (1); int64_t delay = DDS_MSECS (1); /* force evaluation after startup */ struct ddsi_gcreq *gcreq = NULL; @@ -113,19 +112,6 @@ static uint32_t gcreq_queue_thread (struct ddsi_gcreq_queue *q) { LOG_THREAD_CPUTIME (&q->gv->logconfig, next_thread_cputime); - /* While deaf, we need to make sure the receive thread wakes up - every now and then to try recreating sockets & rejoining multicast - groups. Do rate-limit it a bit. */ - if (q->gv->deaf) - { - ddsrt_mtime_t tnow_mt = ddsrt_time_monotonic (); - if (tnow_mt.v > t_ddsi_trigger_recv_threads.v) - { - ddsi_trigger_recv_threads (q->gv); - t_ddsi_trigger_recv_threads.v = tnow_mt.v + DDS_MSECS (100); - } - } - /* If we are waiting for a gcreq to become ready, don't bother looking at the queue; if we aren't, wait for a request to come in. We can't really wait until something came in because we're From e63372ec98dab41a2943bff62276bbe2f2ab7950 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 8 Apr 2024 16:36:56 +0200 Subject: [PATCH 064/207] Add systematic tests for QoS set and match logic This adds table-driven testing that verifies setting something in the QoS object actually affects the created entities and that the QoS matching code respects the values. Signed-off-by: Erik Boasson --- src/core/ddsc/tests/CMakeLists.txt | 1 + src/core/ddsc/tests/qos_set_match.c | 998 ++++++++++++++++++++++++++++ 2 files changed, 999 insertions(+) create mode 100644 src/core/ddsc/tests/qos_set_match.c diff --git a/src/core/ddsc/tests/CMakeLists.txt b/src/core/ddsc/tests/CMakeLists.txt index 7f246cb03c..27007b0357 100644 --- a/src/core/ddsc/tests/CMakeLists.txt +++ b/src/core/ddsc/tests/CMakeLists.txt @@ -66,6 +66,7 @@ set(ddsc_test_sources "publisher.c" "qos.c" "qosmatch.c" + "qos_set_match.c" "querycondition.c" "guardcondition.c" "readcollect.c" diff --git a/src/core/ddsc/tests/qos_set_match.c b/src/core/ddsc/tests/qos_set_match.c new file mode 100644 index 0000000000..d2b1e1c0de --- /dev/null +++ b/src/core/ddsc/tests/qos_set_match.c @@ -0,0 +1,998 @@ +// Copyright(c) 2024 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#include +#include +#include + +#include "dds/dds.h" +#include "dds/ddsrt/environ.h" +#include "test_common.h" + +enum check_mode { + CM_UNSET, + CM_SET, + CM_SET_DEFAULT +}; + +static void durability_set (dds_qos_t * const q, int const * const v) { + assert ((int) DDS_DURABILITY_VOLATILE <= v[0] && v[0] <= (int) DDS_DURABILITY_PERSISTENT); + dds_qset_durability (q, (dds_durability_kind_t) v[0]); +} +static void durability_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + assert ((int) DDS_DURABILITY_VOLATILE <= v[0] && v[0] <= (int) DDS_DURABILITY_PERSISTENT); + dds_durability_kind_t k = (dds_durability_kind_t) ((int) DDS_DURABILITY_PERSISTENT - v[0]); + CU_ASSERT_FATAL (dds_qget_durability (q, &k) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL ((int) k == v[0]); + } +} + +// Use constants derived from line numbers to ensure different QoS settings use different values +// for attributes that can be set reasonably freely. +static const dds_duration_t max_blocking_time_offset = DDS_MSECS (__LINE__); +static void reliability_set (dds_qos_t * const q, int const * const v) { + assert ((int) DDS_RELIABILITY_BEST_EFFORT <= v[0] && v[0] <= (int) DDS_RELIABILITY_RELIABLE); + dds_qset_reliability (q, (dds_reliability_kind_t) v[0], max_blocking_time_offset); +} +static void reliability_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + assert ((int) DDS_RELIABILITY_BEST_EFFORT <= v[0] && v[0] <= (int) DDS_RELIABILITY_RELIABLE); + dds_reliability_kind_t k = (dds_reliability_kind_t) ((int) DDS_RELIABILITY_RELIABLE - v[0]); + dds_duration_t d = -1; + CU_ASSERT_FATAL (dds_qget_reliability (q, &k, &d) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL ((int) k == v[0]); + CU_ASSERT_FATAL (d == max_blocking_time_offset); + } +} + +static const int latency_budget_offset = __LINE__; +static void latency_budget_set (dds_qos_t * const q, int const * const v) { + dds_qset_latency_budget (q, v[0] + latency_budget_offset); +} +static void latency_budget_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + dds_duration_t d = -1; + CU_ASSERT_FATAL (dds_qget_latency_budget (q, &d) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL (d == v[0] + latency_budget_offset); + } +} + +#if DDS_HAS_DEADLINE_MISSED +// deadline >= time_based_filter +static const int deadline_offset = DDS_MSECS (1) + __LINE__; +static void deadline_set (dds_qos_t * const q, int const * const v) { + dds_qset_deadline (q, v[0] + deadline_offset); +} +static void deadline_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + dds_duration_t d = -1; + CU_ASSERT_FATAL (dds_qget_deadline (q, &d) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL (d == v[0] + deadline_offset); + } +} +#endif + +// deadline >= time_based_filter +static const int time_based_filter_offset = __LINE__; +static void time_based_filter_set (dds_qos_t * const q, int const * const v) { + dds_qset_time_based_filter (q, v[0] + time_based_filter_offset); +} +static void time_based_filter_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + dds_duration_t d = -1; + CU_ASSERT_FATAL (dds_qget_time_based_filter (q, &d) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL (d == v[0] + time_based_filter_offset); + } +} + +static void ownership_set (dds_qos_t * const q, int const * const v) { + assert ((int) DDS_OWNERSHIP_SHARED <= v[0] && v[0] <= (int) DDS_OWNERSHIP_EXCLUSIVE); + dds_qset_ownership (q, (dds_ownership_kind_t) v[0]); +} +static void ownership_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + assert ((int) DDS_OWNERSHIP_SHARED <= v[0] && v[0] <= (int) DDS_OWNERSHIP_EXCLUSIVE); + dds_ownership_kind_t k = (dds_ownership_kind_t) ((int) DDS_OWNERSHIP_EXCLUSIVE - v[0]); + CU_ASSERT_FATAL (dds_qget_ownership (q, &k) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL ((int) k == v[0]); + } +} + +static const int ownership_strength_offset = __LINE__; +static void ownership_strength_set (dds_qos_t * const q, int const * const v) { + dds_qset_ownership_strength (q, v[0] + ownership_strength_offset); +} +static void ownership_strength_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + int32_t k = -1; + CU_ASSERT_FATAL (dds_qget_ownership_strength (q, &k) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL (k == v[0] + ownership_strength_offset); + } +} + +static void destination_order_set (dds_qos_t * const q, int const * const v) { + assert ((int) DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP <= v[0] && v[0] <= (int) DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP); + dds_qset_destination_order (q, (dds_destination_order_kind_t) v[0]); +} +static void destination_order_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + assert ((int) DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP <= v[0] && v[0] <= (int) DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP); + dds_destination_order_kind_t k = (dds_destination_order_kind_t) ((int) DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP - v[0]); + CU_ASSERT_FATAL (dds_qget_destination_order (q, &k) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL ((int) k == v[0]); + } +} + +#if DDS_HAS_LIFESPAN +static const int lifespan_offset = __LINE__; +static void lifespan_set (dds_qos_t * const q, int const * const v) { + dds_qset_lifespan (q, v[0] + lifespan_offset); +} +static void lifespan_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + dds_duration_t d = -1; + CU_ASSERT_FATAL (dds_qget_lifespan (q, &d) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL (d == v[0] + lifespan_offset); + } +} +#endif + +static const int transport_priority_offset = __LINE__; +static void transport_priority_set (dds_qos_t * const q, int const * const v) { + dds_qset_transport_priority (q, v[0] + transport_priority_offset); +} +static void transport_priority_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + int32_t d = -1; + CU_ASSERT_FATAL (dds_qget_transport_priority (q, &d) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL (d == v[0] + transport_priority_offset); + } +} + +static const int history_depth = __LINE__; +static void history_set (dds_qos_t * const q, int const * const v) { + assert ((int) DDS_HISTORY_KEEP_LAST <= v[0] && v[0] <= (int) DDS_HISTORY_KEEP_ALL); + dds_qset_history (q, (dds_history_kind_t) v[0], history_depth); +} +static void history_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + assert ((int) DDS_HISTORY_KEEP_LAST <= v[0] && v[0] <= (int) DDS_HISTORY_KEEP_ALL); + dds_history_kind_t k = (dds_history_kind_t) ((int) DDS_HISTORY_KEEP_ALL - v[0]); + int32_t d = -1; + CU_ASSERT_FATAL (dds_qget_history (q, &k, &d) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL ((int) k == v[0]); + CU_ASSERT_FATAL (d == history_depth); + } +} + +static void liveliness_set (dds_qos_t * const q, int const * const v) { + assert ((int) DDS_LIVELINESS_AUTOMATIC <= v[0] && v[0] <= (int) DDS_LIVELINESS_MANUAL_BY_TOPIC && v[1] >= 0); + dds_qset_liveliness (q, (dds_liveliness_kind_t) v[0], DDS_SECS (1) + v[1]); +} +static void liveliness_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + assert ((int) DDS_LIVELINESS_AUTOMATIC <= v[0] && v[0] <= (int) DDS_LIVELINESS_MANUAL_BY_TOPIC && v[1] >= 0); + dds_liveliness_kind_t k = (dds_liveliness_kind_t) ((int) DDS_LIVELINESS_MANUAL_BY_TOPIC - v[0]); + dds_duration_t d = -1; + CU_ASSERT_FATAL (dds_qget_liveliness (q, &k, &d) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL ((int) k == v[0]); + CU_ASSERT_FATAL (d == DDS_SECS (1) + v[1]); + } +} + +static int32_t resource_limits_cnv (const int v, const int f, const int o) +{ + assert (0 <= v && v <= 7); + assert (0 <= f && f <= 2); + int l; + switch (f) { + case 0: l = v % 2; break; + case 1: l = (v/2) % 2; break; + case 2: l = (v/4) % 2; break; + default: abort (); + } + // 1000: so resource limits are always greater than what is required for the history settings used in this test + // o: offset so we can put in unique values for "resource limits" and "durability service resource limits" + return (l == 0) ? DDS_LENGTH_UNLIMITED : 1000 + l + o; +} +static void resource_limits_set (dds_qos_t * const q, int const * const v) { + dds_qset_resource_limits (q, resource_limits_cnv (v[0],0,2), resource_limits_cnv (v[0],1,1), resource_limits_cnv (v[0],2,0)); +} +static void resource_limits_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + int32_t a = 0, b = 0, c = 0; + CU_ASSERT_FATAL (dds_qget_resource_limits (q, &a, &b, &c) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL (a == resource_limits_cnv (v[0],0,2)); + CU_ASSERT_FATAL (b == resource_limits_cnv (v[0],1,1)); + CU_ASSERT_FATAL (c == resource_limits_cnv (v[0],2,0)); + } +} + +static void presentation_set (dds_qos_t * const q, int const * const v) { + assert ((int) DDS_PRESENTATION_INSTANCE <= v[0] && v[0] <= (int) DDS_PRESENTATION_GROUP); + assert ((v[1] == 0 || v[1] == 1) && (v[2] == 0 || v[2] == 1)); + dds_qset_presentation (q, (dds_presentation_access_scope_kind_t) v[0], (bool) v[1], (bool) v[2]); +} +static void presentation_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + assert ((int) DDS_PRESENTATION_INSTANCE <= v[0] && v[0] <= (int) DDS_PRESENTATION_GROUP); + assert ((v[1] == 0 || v[1] == 1) && (v[2] == 0 || v[2] == 1)); + dds_presentation_access_scope_kind_t k = (dds_presentation_access_scope_kind_t) ((int) DDS_PRESENTATION_GROUP - v[0]); + bool w = !v[1], x = !v[2]; + CU_ASSERT_FATAL (dds_qget_presentation (q, &k, &w, &x) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL ((int) k == v[0]); + CU_ASSERT_FATAL (w == v[1]); + CU_ASSERT_FATAL (x == v[2]); + } +} + +static void partition_set (dds_qos_t * const q, int const * const v) { + assert (0 <= v[0] && v[0] <= 2); + if (v[0] == 0) + dds_qset_partition1 (q, NULL); + else + { + char name[13]; + snprintf (name, sizeof (name), "p%d", v[0]); + dds_qset_partition1 (q, name); + } +} +static void partition_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + assert (0 <= v[0] && v[0] <= 2); + uint32_t n = UINT32_MAX; + char dummy, *dummyptr = &dummy, **ps = &dummyptr; + bool r = dds_qget_partition (q, &n, &ps); + CU_ASSERT_FATAL (r == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + if (v[0] == 0) { + CU_ASSERT_FATAL (n == 0 && ps == NULL); // Beware: there is an open PR to change this case! + } else { + char name[13]; + snprintf (name, sizeof (name), "p%d", v[0]); + CU_ASSERT_FATAL (n == 1 && strcmp (ps[0], name) == 0); + } + } + if (r && n > 0) { + dds_free (ps[0]); + dds_free (ps); + } +} + +static void ignorelocal_set (dds_qos_t * const q, int const * const v) { + assert ((int) DDS_IGNORELOCAL_NONE <= v[0] && v[0] <= (int) DDS_IGNORELOCAL_PROCESS); + dds_qset_ignorelocal (q, (dds_ignorelocal_kind_t) v[0]); +} +static void ignorelocal_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + assert ((int) DDS_IGNORELOCAL_NONE <= v[0] && v[0] <= (int) DDS_IGNORELOCAL_PROCESS); + dds_ignorelocal_kind_t k = (dds_ignorelocal_kind_t) ((int) DDS_IGNORELOCAL_PROCESS - v[0]); + CU_ASSERT_FATAL (dds_qget_ignorelocal (q, &k) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL ((int) k == v[0]); + } +} + +static void writer_batching_set (dds_qos_t * const q, int const * const v) { + assert (0 <= v[0] && v[0] <= 1); + dds_qset_writer_batching (q, (bool) v[0]); +} +static void writer_batching_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + assert (0 <= v[0] && v[0] <= 1); + bool k = (bool) (1 - v[0]); + CU_ASSERT_FATAL (dds_qget_writer_batching (q, &k) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL ((int) k == v[0]); + } +} + +static void writer_data_lifecycle_set (dds_qos_t * const q, int const * const v) { + assert (0 <= v[0] && v[0] <= 1); + dds_qset_writer_data_lifecycle (q, (bool) v[0]); +} +static void writer_data_lifecycle_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + assert (0 <= v[0] && v[0] <= 1); + bool k = (bool) (1 - v[0]); + CU_ASSERT_FATAL (dds_qget_writer_data_lifecycle (q, &k) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL ((int) k == v[0]); + } +} + +static void reader_data_lifecycle_set (dds_qos_t * const q, int const * const v) { + assert (0 <= v[0] && 0 <= v[1]); + dds_qset_reader_data_lifecycle (q, DDS_MSECS(100) + v[0], DDS_MSECS(200) + v[1]); +} +static void reader_data_lifecycle_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + assert (0 <= v[0] && 0 <= v[1]); + dds_duration_t k = -1, l = -1; + CU_ASSERT_FATAL (dds_qget_reader_data_lifecycle (q, &k, &l) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL ((int) k == DDS_MSECS(100) + v[0]); + CU_ASSERT_FATAL ((int) l == DDS_MSECS(200) + v[1]); + } +} + +static const dds_duration_t cleanup_service_delay_offset = DDS_MSECS(__LINE__); +static void durability_service_set (dds_qos_t * const q, int const * const v) { + assert ((int) DDS_HISTORY_KEEP_LAST <= v[1] && v[1] <= (int) DDS_HISTORY_KEEP_ALL); + dds_qset_durability_service ( + q, + cleanup_service_delay_offset + v[0], + (dds_history_kind_t) v[1], 2, // history depth & resource limits must be compatible + resource_limits_cnv (v[2],0,12), // which it is with depth = 2 and all resource limits + resource_limits_cnv (v[2],1,11), // either UNLIMITED or plentiful + resource_limits_cnv (v[2],2,10)); +} +static void durability_service_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + assert ((int) DDS_HISTORY_KEEP_LAST <= v[1] && v[1] <= (int) DDS_HISTORY_KEEP_ALL); + dds_duration_t a = -1; + dds_history_kind_t b = (dds_history_kind_t) ((int) DDS_HISTORY_KEEP_ALL - v[1]); + int32_t c = 0, d = 0, e = 0, f = 0; + CU_ASSERT_FATAL (dds_qget_durability_service (q, &a, &b, &c, &d, &e, &f) == (check_mode != CM_UNSET)); + if (check_mode == CM_SET) { + CU_ASSERT_FATAL (a == cleanup_service_delay_offset + v[0]); + CU_ASSERT_FATAL (b == (dds_history_kind_t) v[1]); + CU_ASSERT_FATAL (c == 2); + CU_ASSERT_FATAL (d == resource_limits_cnv (v[2],0,12)); + CU_ASSERT_FATAL (e == resource_limits_cnv (v[2],1,11)); + CU_ASSERT_FATAL (f == resource_limits_cnv (v[2],2,10)); + } +} + +static void entity_name_set (dds_qos_t * const q, int const * const v) { + assert (0 <= v[0] && v[0] <= 1); + char name[13]; + snprintf (name, sizeof (name), "q%d", v[0]); + dds_qset_entity_name (q, name); +} +static void entity_name_check (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v) { + assert (0 <= v[0] && v[0] <= 2); + char dummy, *n = &dummy; + bool r = dds_qget_entity_name (q, &n); + // Deviation from pattern: entity name we expect to see only when we set it explicitly because we run + // with entity auto-naming disabled (the default) + CU_ASSERT_FATAL (r == (check_mode == CM_SET)); + if (check_mode == CM_SET) { + char name[13]; + snprintf (name, sizeof (name), "q%d", v[0]); + CU_ASSERT_FATAL (strcmp (n, name) == 0); + } + if (r) { + dds_free (n); + } +} + +#define QA_TP (1u << 0) +#define QA_PUB (1u << 1) +#define QA_SUB (1u << 2) +#define QA_RD (1u << 3) +#define QA_WR (1u << 4) + +enum rxo_sense { + RXO_INAPPLICABLE, + RXO_IF_EQ, + RXO_IF_RD_LEQ, + RXO_IF_RD_GEQ, + RXO_PARTITION, // special for partition: like IF_EQ, but not really RxO (no incompatible QoS) + RXO_IGNORELOCAL, // special for ignorelocal: weird rules, not really RxO (no incompatible QoS) + RXO_DONTEVENTRY // special for entity name: don't even try RxO matching on this +}; + +#define MAX_VALUES 3 + +struct qostable_elem { + const char *name; + void (*set) (dds_qos_t * const q, int const * const v); + void (*check) (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v); + dds_qos_policy_id_t policy_id; + uint32_t appl; + int max[MAX_VALUES]; + enum rxo_sense rxo[MAX_VALUES]; +}; + +// Note: user/topic/group data covered by ddsc_userdata tests +// FIXME: property (qset_prop, qset_bprop) +// FIXME: type_consistency_enforcement +// FIXME: data_representation +// FIXME: psmx_instances +// FIXME: ignore_local (partial because it can be set on pp/pub/sub/rd/wr, we only apply to once) +#define Q(name) #name, name##_set, name##_check +#define P(NAME) DDS_##NAME##_QOS_POLICY_ID +static const struct qostable_elem qostable[] = { + { Q(durability), P(DURABILITY), QA_TP | QA_RD | QA_WR, {3,0,0}, { RXO_IF_RD_LEQ } }, + { Q(reliability), P(RELIABILITY), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_LEQ } }, + { Q(latency_budget), P(LATENCYBUDGET), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_GEQ } }, +#if DDS_HAS_DEADLINE_MISSED + { Q(deadline), P(DEADLINE), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_GEQ } }, +#endif + { Q(time_based_filter), P(TIMEBASEDFILTER), QA_RD, {1,0,0}, { RXO_INAPPLICABLE } }, + { Q(ownership), P(OWNERSHIP), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_EQ } }, + { Q(ownership_strength), P(OWNERSHIPSTRENGTH), QA_WR, {1,0,0}, { RXO_INAPPLICABLE } }, + { Q(destination_order), P(DESTINATIONORDER), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_LEQ } }, +#if DDS_HAS_LIFESPAN + { Q(lifespan), P(LIFESPAN), QA_TP | QA_WR, {1,0,0}, { RXO_INAPPLICABLE } }, +#endif + { Q(transport_priority), P(TRANSPORTPRIORITY), QA_TP | QA_WR, {1,0,0}, { RXO_INAPPLICABLE } }, + { Q(history), P(HISTORY), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_INAPPLICABLE } }, + { Q(liveliness), P(LIVELINESS), QA_TP | QA_RD | QA_WR, {2,1,0}, { RXO_IF_RD_LEQ, RXO_IF_RD_GEQ } }, + { Q(resource_limits), P(RESOURCELIMITS), QA_TP | QA_RD | QA_WR, {7,0,0}, { RXO_INAPPLICABLE } }, + { Q(presentation), P(PRESENTATION), QA_PUB | QA_SUB, {2,1,1}, { RXO_IF_RD_LEQ, RXO_IF_RD_LEQ, RXO_IF_RD_LEQ } }, + { Q(partition), P(PARTITION), QA_PUB | QA_SUB, {2,0,0}, { RXO_PARTITION } }, + { Q(ignorelocal), P(INVALID), QA_PUB | QA_SUB| QA_RD | QA_WR, {2,0,0}, { RXO_IGNORELOCAL } }, + { Q(writer_batching), P(INVALID), QA_WR, {1,0,0}, { RXO_INAPPLICABLE } }, + { Q(writer_data_lifecycle), P(INVALID), QA_WR, {1,0,0}, { RXO_INAPPLICABLE } }, + { Q(reader_data_lifecycle), P(INVALID), QA_RD, {1,1,0}, { RXO_INAPPLICABLE } }, + { Q(durability_service), P(DURABILITYSERVICE), QA_TP | QA_WR, {1,1,7}, { RXO_INAPPLICABLE } }, + { Q(entity_name), P(INVALID), QA_TP|QA_PUB|QA_SUB|QA_RD|QA_WR, {1,0,0}, { RXO_DONTEVENTRY } }, +}; +#undef P +#undef Q + +CU_Test(ddsc_qos_set, zero) +{ + // Verify a newly created QoS has nothing set + const int v0[MAX_VALUES] = { 0 }; + dds_qos_t *qos = dds_create_qos (); + for (size_t i = 0; i < sizeof (qostable) / sizeof (qostable[0]); i++) + qostable[i].check (CM_UNSET, qos, v0); + dds_delete_qos (qos); +} + +CU_Test(ddsc_qos_set, one) +{ + // Verify set/get on QoS object can handle each individual QoS with multiple values + DDSRT_STATIC_ASSERT(MAX_VALUES == 3); // matters for loop nesting + const int v0[MAX_VALUES] = { 0 }; + for (size_t i = 0; i < sizeof (qostable) / sizeof (qostable[0]); i++) + { + int v[MAX_VALUES]; + for (v[0] = 0; v[0] <= qostable[i].max[0]; v[0]++) + { + for (v[1] = 0; v[1] <= qostable[i].max[1]; v[1]++) + { + for (v[2] = 0; v[2] <= qostable[i].max[2]; v[2]++) + { + dds_qos_t *qos = dds_create_qos (); + qostable[i].set (qos, v); + for (size_t k = 0; k < sizeof (qostable) / sizeof (qostable[0]); k++) + qostable[k].check ((i == k) ? CM_SET : CM_UNSET, qos, (i == k) ? v : v0); + dds_delete_qos (qos); + } + } + } + } +} + +CU_Test(ddsc_qos_set, two) +{ + // Verify we can set all pairs of QoS, setting one to "0" and one to "max" + // to check that we don't accidentally read/write the one QoS's fields in + // two different set/get functions + DDSRT_STATIC_ASSERT(MAX_VALUES == 3); // matters for loop nesting + const int v0[MAX_VALUES] = { 0 }; + for (size_t i = 0; i < sizeof (qostable) / sizeof (qostable[0]); i++) + { + for (size_t j = 0; j < sizeof (qostable) / sizeof (qostable[0]); j++) + { + if (i == j) + continue; + dds_qos_t *qos = dds_create_qos (); + qostable[i].set (qos, v0); + qostable[j].set (qos, qostable[j].max); + for (size_t k = 0; k < sizeof (qostable) / sizeof (qostable[0]); k++) + { + if (k != i && k != j) + qostable[k].check (CM_UNSET, qos, v0); + else if (k == i) + qostable[k].check (CM_SET, qos, v0); + else + qostable[k].check (CM_SET, qos, qostable[k].max); + } + dds_delete_qos (qos); + } + } +} + +static dds_entity_t create_topic_wrapper (dds_entity_t base, const dds_qos_t *qos) +{ + char topicname[100]; + create_unique_topic_name ("ddsc_qosmatch_endpoint", topicname, sizeof (topicname)); + return dds_create_topic (base, &Space_Type1_desc, topicname, qos, NULL); +} + +static dds_entity_t create_reader_wrapper (dds_entity_t base, const dds_qos_t *qos) +{ + return dds_create_reader (dds_get_parent (base), base, qos, NULL); +} + +static dds_entity_t create_writer_wrapper (dds_entity_t base, const dds_qos_t *qos) +{ + return dds_create_writer (dds_get_parent (base), base, qos, NULL); +} + +static dds_entity_t create_subscriber_wrapper (dds_entity_t base, const dds_qos_t *qos) +{ + return dds_create_subscriber (base, qos, NULL); +} + +static dds_entity_t create_publisher_wrapper (dds_entity_t base, const dds_qos_t *qos) +{ + return dds_create_publisher (base, qos, NULL); +} + +static void check_qos_entity_one (uint32_t check_mask, const dds_entity_t entity, const size_t i, int const * const v, const bool sparse_qos) +{ + const int v0[MAX_VALUES] = { 0 }; + dds_qos_t *qos = dds_create_qos (); + const dds_return_t rc = dds_get_qos (entity, qos); + CU_ASSERT_FATAL (rc == 0); + for (size_t k = 0; k < sizeof (qostable) / sizeof (qostable[0]); k++) + { + if ((qostable[k].appl & check_mask) == 0) + qostable[k].check (CM_UNSET, qos, v0); + else if (k != i) + qostable[k].check (sparse_qos ? CM_UNSET : CM_SET_DEFAULT, qos, v0); + else + qostable[k].check (CM_SET, qos, v); + } + dds_delete_qos (qos); +} + +static void do_entity_one (const uint32_t appl_mask, const uint32_t check_mask, const bool sparse_qos, dds_entity_t base, dds_entity_t (* const create) (dds_entity_t base, const dds_qos_t *qos)) +{ + // We just try setting everything to catch things that shouldn't be there + (void)appl_mask; + // Check that for each applicable QoS a create + dds_get_qos pair of operations + // returns the value we set, and that for all other QoS it remains unset/defaulted + // (which of the two depends on "sparse_qos"). + // + // Use various values for each QoS to make sure we are not getting fooled by + // the default values. + for (size_t i = 0; i < sizeof (qostable) / sizeof (qostable[0]); i++) + { + DDSRT_STATIC_ASSERT(MAX_VALUES == 3); // matters for loop nesting + int v[MAX_VALUES]; + for (v[0] = 0; v[0] <= qostable[i].max[0]; v[0]++) + { + for (v[1] = 0; v[1] <= qostable[i].max[1]; v[1]++) + { + for (v[2] = 0; v[2] <= qostable[i].max[2]; v[2]++) + { + printf ("%s: %d %d %d\n", qostable[i].name, v[0], v[1], v[2]); + dds_qos_t *qos = dds_create_qos (); + qostable[i].set (qos, v); + const dds_entity_t ent = create (base, qos); + CU_ASSERT_FATAL (ent > 0); + dds_delete_qos (qos); + check_qos_entity_one (check_mask, ent, i, v, sparse_qos); + const dds_return_t rc = dds_delete (ent); + CU_ASSERT_FATAL (rc == 0); + } + } + } + } +} + +static void check_qos_entity_two (uint32_t check_mask, const dds_entity_t entity, const size_t i, const size_t j, const bool sparse_qos) +{ + const int v0[MAX_VALUES] = { 0 }; + dds_qos_t *qos = dds_create_qos (); + const dds_return_t rc = dds_get_qos (entity, qos); + CU_ASSERT_FATAL (rc == 0); + for (size_t k = 0; k < sizeof (qostable) / sizeof (qostable[0]); k++) + { + if ((qostable[k].appl & check_mask) == 0) + qostable[k].check (CM_UNSET, qos, v0); + else if (k != i && k != j) + qostable[k].check (sparse_qos ? CM_UNSET : CM_SET_DEFAULT, qos, v0); + else if (k == i) + qostable[k].check (CM_SET, qos, v0); + else + qostable[k].check (CM_SET, qos, qostable[k].max); + } + dds_delete_qos (qos); +} + +static void do_entity_two (const uint32_t appl_mask, const uint32_t check_mask, const bool sparse_qos, dds_entity_t base, dds_entity_t (* const create) (dds_entity_t base, const dds_qos_t *qos)) +{ + // Check that each pair QoS applicable to the entity type can be set independently, + // and that a create + dds_get_qos pair of operations returns the correct values. + // + // Use two different values for each QoS to make sure we are not accidentally + // passing a case where the two QoS alias to each other internally. E.g., if QoS + // A and B both map to local L, then setA(1);setB(1) would still pass, but + // setA(0);setB(1) won't. + const int v0[MAX_VALUES] = { 0 }; + for (size_t i = 0; i < sizeof (qostable) / sizeof (qostable[0]); i++) + { + if ((qostable[i].appl & appl_mask) == 0) + continue; + for (size_t j = 0; j < sizeof (qostable) / sizeof (qostable[0]); j++) + { + if ((qostable[j].appl & appl_mask) == 0) + continue; + if (i == j) + continue; + dds_qos_t *qos = dds_create_qos (); + qostable[i].set (qos, v0); + qostable[j].set (qos, qostable[j].max); + const dds_entity_t ent = create (base, qos); + CU_ASSERT_FATAL (ent > 0); + dds_delete_qos (qos); + check_qos_entity_two (check_mask, ent, i, j, sparse_qos); + const dds_return_t rc = dds_delete (ent); + CU_ASSERT_FATAL (rc == 0); + } + } +} + +static void do_nonendpoint (const uint32_t appl_mask, const uint32_t check_mask, bool sparse_qos, void (* const do_entity) (const uint32_t appl_mask, const uint32_t check_mask, const bool sparse_qos, dds_entity_t base, dds_entity_t (* const create) (dds_entity_t base, const dds_qos_t *qos)), dds_entity_t (* const create) (dds_entity_t base, const dds_qos_t *qos)) +{ + // Non-endpoint needs no topic + const dds_entity_t dp = dds_create_participant (0, NULL, NULL); + CU_ASSERT_FATAL (dp > 0); + do_entity (appl_mask, check_mask, sparse_qos, dp, create); + const dds_return_t rc = dds_delete (dp); + CU_ASSERT_FATAL (rc == 0); +} + +static void do_endpoint (const uint32_t appl_mask, const uint32_t check_mask, bool sparse_qos, void (* const do_entity) (const uint32_t appl_mask, const uint32_t check_mask, const bool sparse_qos, dds_entity_t base, dds_entity_t (* const create) (dds_entity_t base, const dds_qos_t *qos)), dds_entity_t (* const create) (dds_entity_t base, const dds_qos_t *qos)) +{ + // Endpoints need a topic, can figure out participant from topic + const dds_entity_t dp = dds_create_participant (0, NULL, NULL); + CU_ASSERT_FATAL (dp > 0); + char topicname[100]; + create_unique_topic_name ("ddsc_qosmatch_endpoint", topicname, sizeof (topicname)); + const dds_entity_t tp = dds_create_topic (dp, &Space_Type1_desc, topicname, NULL, NULL); + CU_ASSERT_FATAL (tp > 0); + do_entity (appl_mask, check_mask, sparse_qos, tp, create); + const dds_return_t rc = dds_delete (dp); + CU_ASSERT_FATAL (rc == 0); +} + +CU_Test(ddsc_qos_set, topic_one) +{ + do_nonendpoint (QA_TP, QA_TP, true, do_entity_one, create_topic_wrapper); +} + +CU_Test(ddsc_qos_set, subscriber_one) +{ + do_nonendpoint (QA_SUB, QA_SUB, false, do_entity_one, create_subscriber_wrapper); +} + +CU_Test(ddsc_qos_set, publisher_one) +{ + do_nonendpoint (QA_PUB, QA_PUB, false, do_entity_one, create_publisher_wrapper); +} + +CU_Test(ddsc_qos_set, reader_one) +{ + do_endpoint (QA_RD, QA_RD | QA_SUB, false, do_entity_one, create_reader_wrapper); +} + +CU_Test(ddsc_qos_set, writer_one) +{ + do_endpoint (QA_WR, QA_WR | QA_PUB, false, do_entity_one, create_writer_wrapper); +} + +CU_Test(ddsc_qos_set, topic_two) +{ + do_nonendpoint (QA_TP, QA_TP, true, do_entity_two, create_topic_wrapper); +} + +CU_Test(ddsc_qos_set, subscriber_two) +{ + do_nonendpoint (QA_SUB, QA_SUB, false, do_entity_two, create_subscriber_wrapper); +} + +CU_Test(ddsc_qos_set, publisher_two) +{ + do_nonendpoint (QA_PUB, QA_PUB, false, do_entity_two, create_publisher_wrapper); +} + +CU_Test(ddsc_qos_set, reader_two) +{ + do_endpoint (QA_RD, QA_RD | QA_SUB, false, do_entity_two, create_reader_wrapper); +} + +CU_Test(ddsc_qos_set, writer_two) +{ + do_endpoint (QA_WR, QA_WR | QA_PUB, false, do_entity_two, create_writer_wrapper); +} + +static void sync_on_discovery (const dds_entity_t dprd, const dds_entity_t dpwr) +{ + // Use a new, unique topic for each pair: the next-easiest way to prevent trouble + // from the discovery running asynchronously and us continuing based on a match + // with an already-deleted remote endpoint. The easiest way would be a unique + // partition name, but the QoS mechanism is the thing we're testing. + char topicname[100]; + dds_return_t rc; + create_unique_topic_name ("ddsc_qosmatch_endpoint_check", topicname, sizeof (topicname)); + const dds_entity_t tpckrd = dds_create_topic (dprd, &Space_Type1_desc, topicname, NULL, NULL); + CU_ASSERT_FATAL (tpckrd > 0); + const dds_entity_t tpckwr = dds_create_topic (dpwr, &Space_Type1_desc, topicname, NULL, NULL); + CU_ASSERT_FATAL (tpckwr > 0); + const dds_entity_t rd = dds_create_reader (dprd, tpckrd, NULL, NULL); + CU_ASSERT_FATAL (rd > 0); + rc = dds_set_status_mask (rd, DDS_SUBSCRIPTION_MATCHED_STATUS); + CU_ASSERT_FATAL (rc == 0); + const dds_entity_t wr = dds_create_writer (dpwr, tpckwr, NULL, NULL); + CU_ASSERT_FATAL (wr > 0); + rc = dds_set_status_mask (wr, DDS_PUBLICATION_MATCHED_STATUS); + CU_ASSERT_FATAL (rc == 0); + const dds_entity_t ws = dds_create_waitset (DDS_CYCLONEDDS_HANDLE); + CU_ASSERT_FATAL (ws > 0); + rc = dds_waitset_attach (ws, rd, 0); + CU_ASSERT_FATAL (rc == 0); + rc = dds_waitset_wait (ws, NULL, 0, DDS_INFINITY); + CU_ASSERT_FATAL (rc == 1); + CU_ASSERT_FATAL (dds_get_matched_publications (rd, NULL, 0) == 1); + rc = dds_waitset_detach (ws, rd); + CU_ASSERT_FATAL (rc == 0); + rc = dds_waitset_attach (ws, wr, 0); + CU_ASSERT_FATAL (rc == 0); + rc = dds_waitset_wait (ws, NULL, 0, DDS_INFINITY); + CU_ASSERT_FATAL (rc == 1); + CU_ASSERT_FATAL (dds_get_matched_subscriptions (wr, NULL, 0) == 1); + rc = dds_waitset_detach (ws, wr); + CU_ASSERT_FATAL (rc == 0); + rc = dds_delete (ws); + CU_ASSERT_FATAL (rc == 0); + rc = dds_delete (rd); + CU_ASSERT_FATAL (rc == 0); + rc = dds_delete (wr); + CU_ASSERT_FATAL (rc == 0); + rc = dds_delete (tpckrd); + CU_ASSERT_FATAL (rc == 0); + rc = dds_delete (tpckwr); + CU_ASSERT_FATAL (rc == 0); +} + +static void check_qos (const bool is_appl, struct qostable_elem const * const te, dds_entity_t entity, int const * const v) +{ + dds_qos_t *qos = dds_create_qos (); + dds_return_t rc; + rc = dds_get_qos (entity, qos); + CU_ASSERT_FATAL (rc == 0); + te->check (is_appl ? CM_SET : CM_UNSET, qos, v); + dds_delete_qos (qos); +} + +static void do_ddsc_qos_set_endpoints_with_rxo (const dds_entity_t dprd, const dds_entity_t dpwr) +{ + // 1. Check that for each QoS applicable to readers/writers that creating endpoints + // and reading back the QoS yields the correct value. Use various values for + // each QoS to make sure we are not getting fooled by the default values. + // + // 2. Check that RxO matching is respected. Technically this ought to be a different + // test but the setup would just be another round through 1. + dds_return_t rc; + for (size_t i = 0; i < sizeof (qostable) / sizeof (qostable[0]); i++) + { + if (qostable[i].rxo[0] == RXO_DONTEVENTRY) + continue; + // All QoS apply to at least a reader, writer, publisher or subscriber + assert ((qostable[i].appl & (QA_RD | QA_WR | QA_PUB | QA_SUB)) != 0); + const bool is_rd = (qostable[i].appl & QA_RD) != 0; + const bool is_wr = (qostable[i].appl & QA_WR) != 0; + const bool is_sub = (qostable[i].appl & QA_SUB) != 0; + const bool is_pub = (qostable[i].appl & QA_PUB) != 0; + // No QoS applies to (reader or writer) and (publisher or subscriber), except + // ignore_local, and there we don't mind setting it on both sub/pub and rd/wr + assert ((is_rd || is_wr) != (is_sub || is_pub) || qostable[i].set == ignorelocal_set); + const bool one_wr = !(is_wr || is_pub); + const bool one_rd = !(is_rd || is_sub); + // Must be looping over multiple values for at least one of { writer, reader } + assert (!(one_wr && one_rd)); + DDSRT_STATIC_ASSERT(MAX_VALUES == 3); // matters for loop nesting + int vrd[3], vwr[3]; + for (vwr[0] = 0; vwr[0] <= (one_wr ? 0 : qostable[i].max[0]); vwr[0]++) + { + for (vwr[1] = 0; vwr[1] <= (one_wr ? 0 : qostable[i].max[1]); vwr[1]++) + { + for (vwr[2] = 0; vwr[2] <= (one_wr ? 0 : qostable[i].max[2]); vwr[2]++) + { + for (vrd[0] = (one_rd ? vwr[0] : 0); vrd[0] <= (one_rd ? vwr[0] : qostable[i].max[0]); vrd[0]++) + { + for (vrd[1] = (one_rd ? vwr[1] : 0); vrd[1] <= (one_rd ? vwr[1] : qostable[i].max[1]); vrd[1]++) + { + for (vrd[2] = (one_rd ? vwr[2] : 0); vrd[2] <= (one_rd ? vwr[2] : qostable[i].max[2]); vrd[2]++) + { + // Use a new, unique topic for each pair: the next-easiest way to prevent trouble + // from the discovery running asynchronously and us continuing based on a match + // with an already-deleted remote endpoint. The easiest way would be a unique + // partition name, but the QoS mechanism is the thing we're testing. + char topicname[100]; + create_unique_topic_name ("ddsc_qosmatch_endpoint", topicname, sizeof (topicname)); + const dds_entity_t tprd = dds_create_topic (dprd, &Space_Type1_desc, topicname, NULL, NULL); + CU_ASSERT_FATAL (tprd > 0); + const dds_entity_t tpwr = dds_create_topic (dpwr, &Space_Type1_desc, topicname, NULL, NULL); + CU_ASSERT_FATAL (tpwr > 0); + + dds_qos_t *qos; + printf ("%s: wr %d %d %d rd %d %d %d", qostable[i].name, vwr[0], vwr[1], vwr[2], vrd[0], vrd[1], vrd[2]); + fflush (stdout); + + qos = dds_create_qos (); + qostable[i].set (qos, vrd); + const dds_entity_t sub = dds_create_subscriber (dprd, is_sub ? qos : NULL, NULL); + CU_ASSERT_FATAL (sub > 0); + const dds_entity_t rd = dds_create_reader (sub, tprd, is_rd ? qos : NULL, NULL); + CU_ASSERT_FATAL (rd > 0); + dds_delete_qos (qos); + + check_qos (is_sub, &qostable[i], sub, vrd); + // reader does store local copies of subscriber QoS for partition, presentation + // and ignorelocal because those are used in discovery + check_qos (is_sub || is_rd, &qostable[i], rd, vrd); + + qos = dds_create_qos (); + qostable[i].set (qos, vwr); + const dds_entity_t pub = dds_create_publisher (dpwr, is_pub ? qos : NULL, NULL); + CU_ASSERT_FATAL (pub > 0); + const dds_entity_t wr = dds_create_writer (pub, tpwr, is_wr ? qos : NULL, NULL); + CU_ASSERT_FATAL (wr > 0); + dds_delete_qos (qos); + check_qos (is_pub, &qostable[i], pub, vwr); + // writer does store local copies of publisher QoS for partition, presentation + // and ignorelocal because those are used in discovery + check_qos (is_pub || is_wr, &qostable[i], wr, vwr); + + // If remote endpoints, wait until matching info is correct. We do this by creating + // an additional rd/wr pair with a different topic. The DDSI discovery protocol has + // to process these after processing the test reader/writer, and so once this second + // pair matches, the matching info for the first pair is also reliable, including in + // the case of an RxO mismatch. + if (dds_get_parent (dprd) != dds_get_parent (dpwr)) + sync_on_discovery (dprd, dpwr); + + // Compute whether the endpoints match based on the RxO rules in the table, and + // whether this will give rise to an "incompatible QoS" notification. The latter + // is usually the case, but not for partition and ignore_local because those are + // considered intentional non-matches. + bool match = true; + bool expect_incompatible_qos = false; + for (size_t m = 0; m < sizeof (qostable[i].rxo) / sizeof (qostable[i].rxo[0]); m++) + { + switch (qostable[i].rxo[m]) + { + case RXO_INAPPLICABLE: + case RXO_DONTEVENTRY: + break; + case RXO_IF_EQ: // match iff rd and wr have same value set + if (vrd[m] != vwr[m]) { + expect_incompatible_qos = true; + match = false; + } + break; + case RXO_IF_RD_GEQ: // match iff rd has at least wr value set + if (vrd[m] < vwr[m]) { + expect_incompatible_qos = true; + match = false; + } + break; + case RXO_IF_RD_LEQ: // match iff rd has at most wr value set + if (vrd[m] > vwr[m]) { + expect_incompatible_qos = true; + match = false; + } + break; + case RXO_PARTITION: // match only if equal, no incompatible QoS + if (vrd[m] != vwr[m]) + match = false; + break; + case RXO_IGNORELOCAL: { // use participant, domain handles to figure it out, no incompatible QoS + bool ilmatch; + if (vrd[m] == (int) DDS_IGNORELOCAL_PROCESS || vwr[m] == (int) DDS_IGNORELOCAL_PROCESS) + ilmatch = (dds_get_parent (dprd) != dds_get_parent (dpwr)); + else if (vrd[m] == (int) DDS_IGNORELOCAL_PARTICIPANT || vwr[m] == (int) DDS_IGNORELOCAL_PARTICIPANT) + ilmatch = (dprd != dpwr); + else + ilmatch = true; + if (!ilmatch) + match = false; + break; + } + } + } + printf (" match %d", match); + fflush (stdout); + rc = dds_get_matched_publications (rd, NULL, 0); + CU_ASSERT_FATAL (rc == (int) match); + rc = dds_get_matched_subscriptions (wr, NULL, 0); + CU_ASSERT_FATAL (rc == (int) match); + if (expect_incompatible_qos) + { + dds_offered_incompatible_qos_status_t oiq; + dds_requested_incompatible_qos_status_t riq; + rc = dds_get_offered_incompatible_qos_status (wr, &oiq); + CU_ASSERT_FATAL (rc == 0); + rc = dds_get_requested_incompatible_qos_status (rd, &riq); + CU_ASSERT_FATAL (rc == 0); + CU_ASSERT_FATAL (oiq.last_policy_id == qostable[i].policy_id); + CU_ASSERT_FATAL (riq.last_policy_id == qostable[i].policy_id); + } + rc = dds_delete (wr); + CU_ASSERT_FATAL (rc == 0); + rc = dds_delete (rd); + CU_ASSERT_FATAL (rc == 0); + rc = dds_delete (tpwr); + CU_ASSERT_FATAL (rc == 0); + rc = dds_delete (tprd); + CU_ASSERT_FATAL (rc == 0); + printf ("\n"); + } + } + } + } + } + } + } +} + +CU_Test(ddsc_qos_set, local_endpoints_with_rxo) +{ + const char *config = "${CYCLONEDDS_URI},${CYCLONEDDS_PID}"; + char *conf = ddsrt_expand_envvars (config, 0); + const dds_entity_t dom = dds_create_domain (0, conf); + CU_ASSERT_FATAL (dom > 0); + ddsrt_free (conf); + const dds_entity_t dp = dds_create_participant (0, NULL, NULL); + CU_ASSERT_FATAL (dp > 0); + dds_return_t rc; + do_ddsc_qos_set_endpoints_with_rxo (dp, dp); + rc = dds_delete (dom); + CU_ASSERT_FATAL (rc == 0); +} + +CU_Test(ddsc_qos_set, semilocal_endpoints_with_rxo) +{ + const char *config = "${CYCLONEDDS_URI},${CYCLONEDDS_PID}"; + char *conf = ddsrt_expand_envvars (config, 0); + const dds_entity_t dom = dds_create_domain (0, conf); + CU_ASSERT_FATAL (dom > 0); + ddsrt_free (conf); + const dds_entity_t dprd = dds_create_participant (0, NULL, NULL); + CU_ASSERT_FATAL (dprd > 0); + const dds_entity_t dpwr = dds_create_participant (0, NULL, NULL); + CU_ASSERT_FATAL (dpwr > 0); + do_ddsc_qos_set_endpoints_with_rxo (dprd, dpwr); + dds_return_t rc = dds_delete (dom); + CU_ASSERT_FATAL (rc == 0); +} + +CU_Test(ddsc_qos_set, remote_endpoints_with_rxo) +{ + /* Domains for pub and sub use a different domain id, but the portgain setting + * in configuration is 0, so that both domains will map to the same port number. + * This allows to create two domains in a single test process. */ + const char *config = "${CYCLONEDDS_URI},${CYCLONEDDS_PID}0"; + char *confrd = ddsrt_expand_envvars (config, 0); + char *confwr = ddsrt_expand_envvars (config, 1); + const dds_entity_t domrd = dds_create_domain (0, confrd); + CU_ASSERT_FATAL (domrd > 0); + const dds_entity_t domwr = dds_create_domain (1, confwr); + CU_ASSERT_FATAL (domwr > 0); + ddsrt_free (confwr); + ddsrt_free (confrd); + + const dds_entity_t dprd = dds_create_participant (0, NULL, NULL); + CU_ASSERT_FATAL (dprd > 0); + const dds_entity_t dpwr = dds_create_participant (1, NULL, NULL); + CU_ASSERT_FATAL (dpwr > 0); + + do_ddsc_qos_set_endpoints_with_rxo (dprd, dpwr); + + dds_return_t rc = dds_delete (domrd); + CU_ASSERT_FATAL (rc == 0); + rc = dds_delete (domwr); + CU_ASSERT_FATAL (rc == 0); +} From 32fcbbb65ceefb675e2fbca680f03c9d99076fe0 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 8 Apr 2024 22:02:16 +0200 Subject: [PATCH 065/207] Fix DDS_IGNORELOCAL_PARTICIPANT matching code The early-out logic did not treat the DDS_IGNORELOCAL_PARTICIPANT case symmetrically and could incorrectly allow communication if one endpoint had PARTICIPANT and the other PROCESS mode selected. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_endpoint_match.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/ddsi/src/ddsi_endpoint_match.c b/src/core/ddsi/src/ddsi_endpoint_match.c index f40a8ba84a..bba60f4c22 100644 --- a/src/core/ddsi/src/ddsi_endpoint_match.c +++ b/src/core/ddsi/src/ddsi_endpoint_match.c @@ -349,7 +349,9 @@ static bool ignore_local_p (const ddsi_guid_t *guid1, const ddsi_guid_t *guid2, case DDS_IGNORELOCAL_NONE: break; case DDS_IGNORELOCAL_PARTICIPANT: - return memcmp (&guid1->prefix, &guid2->prefix, sizeof (guid1->prefix)) == 0; + if (memcmp (&guid1->prefix, &guid2->prefix, sizeof (guid1->prefix)) == 0) + return true; + break; case DDS_IGNORELOCAL_PROCESS: return true; } @@ -358,7 +360,9 @@ static bool ignore_local_p (const ddsi_guid_t *guid1, const ddsi_guid_t *guid2, case DDS_IGNORELOCAL_NONE: break; case DDS_IGNORELOCAL_PARTICIPANT: - return memcmp (&guid1->prefix, &guid2->prefix, sizeof (guid1->prefix)) == 0; + if (memcmp (&guid1->prefix, &guid2->prefix, sizeof (guid1->prefix)) == 0) + return true; + break; case DDS_IGNORELOCAL_PROCESS: return true; } From 2fb85d10a54c95c57c9329728357840f0234851f Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 8 Apr 2024 22:03:22 +0200 Subject: [PATCH 066/207] data reader has no transport priority QoS It was correctly excluded from the data reader QoS Mask definition, but incorrectly included in the set of default QoS settings. The consequence is that it is included in the result of dds_get_qos, with a value fixed at 0. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_plist.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/ddsi/src/ddsi_plist.c b/src/core/ddsi/src/ddsi_plist.c index 89af546baa..6185aa39fe 100644 --- a/src/core/ddsi/src/ddsi_plist.c +++ b/src/core/ddsi/src/ddsi_plist.c @@ -3575,7 +3575,7 @@ void ddsi_xqos_init_empty (dds_qos_t *dest) } const dds_qos_t ddsi_default_qos_reader = { - .present = DDSI_QP_PRESENTATION | DDSI_QP_DURABILITY | DDSI_QP_DEADLINE | DDSI_QP_LATENCY_BUDGET | DDSI_QP_LIVELINESS | DDSI_QP_DESTINATION_ORDER | DDSI_QP_HISTORY | DDSI_QP_RESOURCE_LIMITS | DDSI_QP_TRANSPORT_PRIORITY | DDSI_QP_OWNERSHIP | DDSI_QP_CYCLONE_IGNORELOCAL | DDSI_QP_TOPIC_DATA | DDSI_QP_GROUP_DATA | DDSI_QP_USER_DATA | DDSI_QP_PARTITION | DDSI_QP_RELIABILITY | DDSI_QP_TIME_BASED_FILTER | DDSI_QP_ADLINK_READER_DATA_LIFECYCLE | DDSI_QP_ADLINK_READER_LIFESPAN | DDSI_QP_TYPE_CONSISTENCY_ENFORCEMENT | DDSI_QP_DATA_REPRESENTATION, + .present = DDSI_QP_PRESENTATION | DDSI_QP_DURABILITY | DDSI_QP_DEADLINE | DDSI_QP_LATENCY_BUDGET | DDSI_QP_LIVELINESS | DDSI_QP_DESTINATION_ORDER | DDSI_QP_HISTORY | DDSI_QP_RESOURCE_LIMITS | DDSI_QP_OWNERSHIP | DDSI_QP_CYCLONE_IGNORELOCAL | DDSI_QP_TOPIC_DATA | DDSI_QP_GROUP_DATA | DDSI_QP_USER_DATA | DDSI_QP_PARTITION | DDSI_QP_RELIABILITY | DDSI_QP_TIME_BASED_FILTER | DDSI_QP_ADLINK_READER_DATA_LIFECYCLE | DDSI_QP_ADLINK_READER_LIFESPAN | DDSI_QP_TYPE_CONSISTENCY_ENFORCEMENT | DDSI_QP_DATA_REPRESENTATION, .aliased = DDSI_QP_DATA_REPRESENTATION, .presentation.access_scope = DDS_PRESENTATION_INSTANCE, .presentation.coherent_access = 0, @@ -3591,7 +3591,6 @@ const dds_qos_t ddsi_default_qos_reader = { .resource_limits.max_samples = DDS_LENGTH_UNLIMITED, .resource_limits.max_instances = DDS_LENGTH_UNLIMITED, .resource_limits.max_samples_per_instance = DDS_LENGTH_UNLIMITED, - .transport_priority.value = 0, .ownership.kind = DDS_OWNERSHIP_SHARED, .ignorelocal.value = DDS_IGNORELOCAL_NONE, .topic_data.length = 0, From 94616555b8a59673ae528413c4a8a32616d5c98e Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 9 Apr 2024 09:19:54 +0200 Subject: [PATCH 067/207] Default pub/sub QoS: presentation and ignore_local Not including these is observable via dds_get_qos but has no other effect, it all got defaulted properly in readers and writers and those are the only ones where these really matter, at least while the fancy settings for the presentation QoS are not supported. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_plist.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ddsi/src/ddsi_plist.c b/src/core/ddsi/src/ddsi_plist.c index 6185aa39fe..f02baad38e 100644 --- a/src/core/ddsi/src/ddsi_plist.c +++ b/src/core/ddsi/src/ddsi_plist.c @@ -3695,11 +3695,12 @@ const dds_qos_t ddsi_default_qos_topic = { }; const dds_qos_t ddsi_default_qos_publisher_subscriber = { - .present = DDSI_QP_GROUP_DATA | DDSI_QP_PARTITION | DDSI_QP_ADLINK_ENTITY_FACTORY, + .present = DDSI_QP_GROUP_DATA | DDSI_QP_PARTITION | DDSI_QP_PRESENTATION | DDSI_QP_CYCLONE_IGNORELOCAL | DDSI_QP_ADLINK_ENTITY_FACTORY, .aliased = 0, .presentation.access_scope = DDS_PRESENTATION_INSTANCE, .presentation.coherent_access = 0, .presentation.ordered_access = 0, + .ignorelocal.value = DDS_IGNORELOCAL_NONE, .entity_factory.autoenable_created_entities = 1, .group_data.length = 0, .group_data.value = NULL, From 95bd6ba6f2f1783128c3b4bd9348e596f9169c39 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 9 Apr 2024 13:40:08 +0200 Subject: [PATCH 068/207] Check creating an entity with invalid QoS fails Signed-off-by: Erik Boasson --- src/core/ddsc/tests/qos_set_match.c | 177 ++++++++++++++++++++++++---- 1 file changed, 155 insertions(+), 22 deletions(-) diff --git a/src/core/ddsc/tests/qos_set_match.c b/src/core/ddsc/tests/qos_set_match.c index d2b1e1c0de..47fb24aeda 100644 --- a/src/core/ddsc/tests/qos_set_match.c +++ b/src/core/ddsc/tests/qos_set_match.c @@ -34,6 +34,9 @@ static void durability_check (const enum check_mode check_mode, const dds_qos_t CU_ASSERT_FATAL ((int) k == v[0]); } } +static void durability_invalid (dds_qos_t * const q, int const v) { + dds_qset_durability (q, (dds_durability_kind_t) ((int) DDS_DURABILITY_PERSISTENT + v + 1)); +} // Use constants derived from line numbers to ensure different QoS settings use different values // for attributes that can be set reasonably freely. @@ -52,6 +55,12 @@ static void reliability_check (const enum check_mode check_mode, const dds_qos_t CU_ASSERT_FATAL (d == max_blocking_time_offset); } } +static void reliability_invalid (dds_qos_t * const q, int const v) { + if (v == 0) + dds_qset_reliability (q, DDS_RELIABILITY_RELIABLE, -1); + else + dds_qset_reliability (q, (dds_reliability_kind_t) ((int) DDS_RELIABILITY_RELIABLE + v), 0); +} static const int latency_budget_offset = __LINE__; static void latency_budget_set (dds_qos_t * const q, int const * const v) { @@ -64,6 +73,10 @@ static void latency_budget_check (const enum check_mode check_mode, const dds_qo CU_ASSERT_FATAL (d == v[0] + latency_budget_offset); } } +static void latency_budget_invalid (dds_qos_t * const q, int const v) { + (void)v; + dds_qset_latency_budget (q, -1); +} #if DDS_HAS_DEADLINE_MISSED // deadline >= time_based_filter @@ -78,6 +91,10 @@ static void deadline_check (const enum check_mode check_mode, const dds_qos_t * CU_ASSERT_FATAL (d == v[0] + deadline_offset); } } +static void deadline_invalid (dds_qos_t * const q, int const v) { + (void)v; + dds_qset_deadline (q, -1); +} #endif // deadline >= time_based_filter @@ -92,6 +109,10 @@ static void time_based_filter_check (const enum check_mode check_mode, const dds CU_ASSERT_FATAL (d == v[0] + time_based_filter_offset); } } +static void time_based_filter_invalid (dds_qos_t * const q, int const v) { + (void)v; + dds_qset_time_based_filter (q, -1); +} static void ownership_set (dds_qos_t * const q, int const * const v) { assert ((int) DDS_OWNERSHIP_SHARED <= v[0] && v[0] <= (int) DDS_OWNERSHIP_EXCLUSIVE); @@ -105,6 +126,9 @@ static void ownership_check (const enum check_mode check_mode, const dds_qos_t * CU_ASSERT_FATAL ((int) k == v[0]); } } +static void ownership_invalid (dds_qos_t * const q, int const v) { + dds_qset_ownership (q, (dds_ownership_kind_t) ((int) DDS_OWNERSHIP_EXCLUSIVE + v + 1)); +} static const int ownership_strength_offset = __LINE__; static void ownership_strength_set (dds_qos_t * const q, int const * const v) { @@ -117,6 +141,7 @@ static void ownership_strength_check (const enum check_mode check_mode, const dd CU_ASSERT_FATAL (k == v[0] + ownership_strength_offset); } } +// no invalid value for ownership strength exists static void destination_order_set (dds_qos_t * const q, int const * const v) { assert ((int) DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP <= v[0] && v[0] <= (int) DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP); @@ -130,6 +155,9 @@ static void destination_order_check (const enum check_mode check_mode, const dds CU_ASSERT_FATAL ((int) k == v[0]); } } +static void destination_order_invalid (dds_qos_t * const q, int const v) { + dds_qset_destination_order (q, (dds_destination_order_kind_t) ((int) DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP + v + 1)); +} #if DDS_HAS_LIFESPAN static const int lifespan_offset = __LINE__; @@ -143,6 +171,10 @@ static void lifespan_check (const enum check_mode check_mode, const dds_qos_t * CU_ASSERT_FATAL (d == v[0] + lifespan_offset); } } +static void lifespan_invalid (dds_qos_t * const q, int const v) { + (void)v; + dds_qset_lifespan (q, -1); +} #endif static const int transport_priority_offset = __LINE__; @@ -156,6 +188,7 @@ static void transport_priority_check (const enum check_mode check_mode, const dd CU_ASSERT_FATAL (d == v[0] + transport_priority_offset); } } +// no invalid value for transport priority exists static const int history_depth = __LINE__; static void history_set (dds_qos_t * const q, int const * const v) { @@ -172,6 +205,12 @@ static void history_check (const enum check_mode check_mode, const dds_qos_t * c CU_ASSERT_FATAL (d == history_depth); } } +static void history_invalid (dds_qos_t * const q, int const v) { + if (v == 0) + dds_qset_history (q, DDS_HISTORY_KEEP_LAST, 0); + else + dds_qset_history (q, (dds_history_kind_t) ((int) DDS_HISTORY_KEEP_ALL + v + 1), 0); +} static void liveliness_set (dds_qos_t * const q, int const * const v) { assert ((int) DDS_LIVELINESS_AUTOMATIC <= v[0] && v[0] <= (int) DDS_LIVELINESS_MANUAL_BY_TOPIC && v[1] >= 0); @@ -187,6 +226,12 @@ static void liveliness_check (const enum check_mode check_mode, const dds_qos_t CU_ASSERT_FATAL (d == DDS_SECS (1) + v[1]); } } +static void liveliness_invalid (dds_qos_t * const q, int const v) { + if (v == 0) + dds_qset_liveliness (q, DDS_LIVELINESS_MANUAL_BY_TOPIC, -1); + else + dds_qset_liveliness (q, (dds_liveliness_kind_t) ((int) DDS_LIVELINESS_MANUAL_BY_TOPIC + v + 1), DDS_SECS (1)); +} static int32_t resource_limits_cnv (const int v, const int f, const int o) { @@ -215,6 +260,14 @@ static void resource_limits_check (const enum check_mode check_mode, const dds_q CU_ASSERT_FATAL (c == resource_limits_cnv (v[0],2,0)); } } +static void resource_limits_invalid (dds_qos_t * const q, int const v) { + assert (0 <= v && v <= 2); + switch (v) { + case 0: dds_qset_resource_limits (q, 0, DDS_LENGTH_UNLIMITED, DDS_LENGTH_UNLIMITED); break; + case 1: dds_qset_resource_limits (q, DDS_LENGTH_UNLIMITED, 0, DDS_LENGTH_UNLIMITED); break; + case 2: dds_qset_resource_limits (q, DDS_LENGTH_UNLIMITED, DDS_LENGTH_UNLIMITED, 0); break; + } +} static void presentation_set (dds_qos_t * const q, int const * const v) { assert ((int) DDS_PRESENTATION_INSTANCE <= v[0] && v[0] <= (int) DDS_PRESENTATION_GROUP); @@ -233,6 +286,10 @@ static void presentation_check (const enum check_mode check_mode, const dds_qos_ CU_ASSERT_FATAL (x == v[2]); } } +static void presentation_invalid (dds_qos_t * const q, int const v) { + dds_qset_presentation (q, (dds_presentation_access_scope_kind_t) ((int) DDS_PRESENTATION_GROUP + v + 1), false, false); + // can't pass in non-bools for coherent/ordered access arguments +} static void partition_set (dds_qos_t * const q, int const * const v) { assert (0 <= v[0] && v[0] <= 2); @@ -265,6 +322,7 @@ static void partition_check (const enum check_mode check_mode, const dds_qos_t * dds_free (ps); } } +// no invalid value for partition exists static void ignorelocal_set (dds_qos_t * const q, int const * const v) { assert ((int) DDS_IGNORELOCAL_NONE <= v[0] && v[0] <= (int) DDS_IGNORELOCAL_PROCESS); @@ -278,6 +336,9 @@ static void ignorelocal_check (const enum check_mode check_mode, const dds_qos_t CU_ASSERT_FATAL ((int) k == v[0]); } } +static void ignorelocal_invalid (dds_qos_t * const q, int const v) { + dds_qset_ignorelocal (q, (dds_ignorelocal_kind_t) ((int) DDS_IGNORELOCAL_PROCESS + v + 1)); +} static void writer_batching_set (dds_qos_t * const q, int const * const v) { assert (0 <= v[0] && v[0] <= 1); @@ -291,6 +352,7 @@ static void writer_batching_check (const enum check_mode check_mode, const dds_q CU_ASSERT_FATAL ((int) k == v[0]); } } +// no invalid value for writer batching exists: can't pass in garbage for a bool static void writer_data_lifecycle_set (dds_qos_t * const q, int const * const v) { assert (0 <= v[0] && v[0] <= 1); @@ -304,6 +366,7 @@ static void writer_data_lifecycle_check (const enum check_mode check_mode, const CU_ASSERT_FATAL ((int) k == v[0]); } } +// no invalid value for writer data lifecycle exists: can't pass in garbage for a bool static void reader_data_lifecycle_set (dds_qos_t * const q, int const * const v) { assert (0 <= v[0] && 0 <= v[1]); @@ -318,6 +381,13 @@ static void reader_data_lifecycle_check (const enum check_mode check_mode, const CU_ASSERT_FATAL ((int) l == DDS_MSECS(200) + v[1]); } } +static void reader_data_lifecycle_invalid (dds_qos_t * const q, int const v) { + assert (0 <= v && v <= 1); + switch (v) { + case 0: dds_qset_reader_data_lifecycle (q, -1, 1); break; + case 1: dds_qset_reader_data_lifecycle (q, 1, -1); break; + } +} static const dds_duration_t cleanup_service_delay_offset = DDS_MSECS(__LINE__); static void durability_service_set (dds_qos_t * const q, int const * const v) { @@ -345,6 +415,17 @@ static void durability_service_check (const enum check_mode check_mode, const dd CU_ASSERT_FATAL (f == resource_limits_cnv (v[2],2,10)); } } +static void durability_service_invalid (dds_qos_t * const q, int const v) { + switch (v) { + case 0: dds_qset_durability_service (q, -1, DDS_HISTORY_KEEP_LAST, 1, DDS_LENGTH_UNLIMITED, DDS_LENGTH_UNLIMITED, DDS_LENGTH_UNLIMITED); break; + case 1: dds_qset_durability_service (q, 0, DDS_HISTORY_KEEP_LAST, 0, DDS_LENGTH_UNLIMITED, DDS_LENGTH_UNLIMITED, DDS_LENGTH_UNLIMITED); break; + case 2: dds_qset_durability_service (q, 0, DDS_HISTORY_KEEP_LAST, 1, 0, DDS_LENGTH_UNLIMITED, DDS_LENGTH_UNLIMITED); break; + case 3: dds_qset_durability_service (q, 0, DDS_HISTORY_KEEP_LAST, 1, DDS_LENGTH_UNLIMITED, 0, DDS_LENGTH_UNLIMITED); break; + case 4: dds_qset_durability_service (q, 0, DDS_HISTORY_KEEP_LAST, 1, DDS_LENGTH_UNLIMITED, DDS_LENGTH_UNLIMITED, 0); break; + default: dds_qset_durability_service (q, 0, (dds_history_kind_t) ((int) DDS_HISTORY_KEEP_ALL + 1), 0, DDS_LENGTH_UNLIMITED, DDS_LENGTH_UNLIMITED, DDS_LENGTH_UNLIMITED); break; + + } +} static void entity_name_set (dds_qos_t * const q, int const * const v) { assert (0 <= v[0] && v[0] <= 1); @@ -368,6 +449,7 @@ static void entity_name_check (const enum check_mode check_mode, const dds_qos_t dds_free (n); } } +// no invalid value for entity name exists #define QA_TP (1u << 0) #define QA_PUB (1u << 1) @@ -391,10 +473,12 @@ struct qostable_elem { const char *name; void (*set) (dds_qos_t * const q, int const * const v); void (*check) (const enum check_mode check_mode, const dds_qos_t * const q, int const * const v); + void (*invalid) (dds_qos_t * const q, int const v); dds_qos_policy_id_t policy_id; uint32_t appl; int max[MAX_VALUES]; enum rxo_sense rxo[MAX_VALUES]; + int max_invalid; }; // Note: user/topic/group data covered by ddsc_userdata tests @@ -403,34 +487,35 @@ struct qostable_elem { // FIXME: data_representation // FIXME: psmx_instances // FIXME: ignore_local (partial because it can be set on pp/pub/sub/rd/wr, we only apply to once) -#define Q(name) #name, name##_set, name##_check +#define QI(name) #name, name##_set, name##_check, name##_invalid +#define Q0(name) #name, name##_set, name##_check, NULL #define P(NAME) DDS_##NAME##_QOS_POLICY_ID static const struct qostable_elem qostable[] = { - { Q(durability), P(DURABILITY), QA_TP | QA_RD | QA_WR, {3,0,0}, { RXO_IF_RD_LEQ } }, - { Q(reliability), P(RELIABILITY), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_LEQ } }, - { Q(latency_budget), P(LATENCYBUDGET), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_GEQ } }, + { QI(durability), P(DURABILITY), QA_TP | QA_RD | QA_WR, {3,0,0}, { RXO_IF_RD_LEQ }, 0 }, + { QI(reliability), P(RELIABILITY), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_LEQ }, 1 }, + { QI(latency_budget), P(LATENCYBUDGET), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_GEQ }, 0 }, #if DDS_HAS_DEADLINE_MISSED - { Q(deadline), P(DEADLINE), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_GEQ } }, + { QI(deadline), P(DEADLINE), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_GEQ }, 0 }, #endif - { Q(time_based_filter), P(TIMEBASEDFILTER), QA_RD, {1,0,0}, { RXO_INAPPLICABLE } }, - { Q(ownership), P(OWNERSHIP), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_EQ } }, - { Q(ownership_strength), P(OWNERSHIPSTRENGTH), QA_WR, {1,0,0}, { RXO_INAPPLICABLE } }, - { Q(destination_order), P(DESTINATIONORDER), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_LEQ } }, + { QI(time_based_filter), P(TIMEBASEDFILTER), QA_RD, {1,0,0}, { RXO_INAPPLICABLE }, 0 }, + { QI(ownership), P(OWNERSHIP), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_EQ }, 0 }, + { Q0(ownership_strength), P(OWNERSHIPSTRENGTH), QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0 }, + { QI(destination_order), P(DESTINATIONORDER), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_LEQ }, 0 }, #if DDS_HAS_LIFESPAN - { Q(lifespan), P(LIFESPAN), QA_TP | QA_WR, {1,0,0}, { RXO_INAPPLICABLE } }, + { QI(lifespan), P(LIFESPAN), QA_TP | QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0 }, #endif - { Q(transport_priority), P(TRANSPORTPRIORITY), QA_TP | QA_WR, {1,0,0}, { RXO_INAPPLICABLE } }, - { Q(history), P(HISTORY), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_INAPPLICABLE } }, - { Q(liveliness), P(LIVELINESS), QA_TP | QA_RD | QA_WR, {2,1,0}, { RXO_IF_RD_LEQ, RXO_IF_RD_GEQ } }, - { Q(resource_limits), P(RESOURCELIMITS), QA_TP | QA_RD | QA_WR, {7,0,0}, { RXO_INAPPLICABLE } }, - { Q(presentation), P(PRESENTATION), QA_PUB | QA_SUB, {2,1,1}, { RXO_IF_RD_LEQ, RXO_IF_RD_LEQ, RXO_IF_RD_LEQ } }, - { Q(partition), P(PARTITION), QA_PUB | QA_SUB, {2,0,0}, { RXO_PARTITION } }, - { Q(ignorelocal), P(INVALID), QA_PUB | QA_SUB| QA_RD | QA_WR, {2,0,0}, { RXO_IGNORELOCAL } }, - { Q(writer_batching), P(INVALID), QA_WR, {1,0,0}, { RXO_INAPPLICABLE } }, - { Q(writer_data_lifecycle), P(INVALID), QA_WR, {1,0,0}, { RXO_INAPPLICABLE } }, - { Q(reader_data_lifecycle), P(INVALID), QA_RD, {1,1,0}, { RXO_INAPPLICABLE } }, - { Q(durability_service), P(DURABILITYSERVICE), QA_TP | QA_WR, {1,1,7}, { RXO_INAPPLICABLE } }, - { Q(entity_name), P(INVALID), QA_TP|QA_PUB|QA_SUB|QA_RD|QA_WR, {1,0,0}, { RXO_DONTEVENTRY } }, + { Q0(transport_priority), P(TRANSPORTPRIORITY), QA_TP | QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0 }, + { QI(history), P(HISTORY), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0 }, + { QI(liveliness), P(LIVELINESS), QA_TP | QA_RD | QA_WR, {2,1,0}, { RXO_IF_RD_LEQ, RXO_IF_RD_GEQ }, 1 }, + { QI(resource_limits), P(RESOURCELIMITS), QA_TP | QA_RD | QA_WR, {7,0,0}, { RXO_INAPPLICABLE }, 2 }, + { QI(presentation), P(PRESENTATION), QA_PUB | QA_SUB, {2,1,1}, { RXO_IF_RD_LEQ, RXO_IF_RD_LEQ, RXO_IF_RD_LEQ }, 0 }, + { Q0(partition), P(PARTITION), QA_PUB | QA_SUB, {2,0,0}, { RXO_PARTITION }, 0 }, + { QI(ignorelocal), P(INVALID), QA_PUB | QA_SUB| QA_RD | QA_WR, {2,0,0}, { RXO_IGNORELOCAL }, 0 }, + { Q0(writer_batching), P(INVALID), QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0 }, + { Q0(writer_data_lifecycle), P(INVALID), QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0 }, + { QI(reader_data_lifecycle), P(INVALID), QA_RD, {1,1,0}, { RXO_INAPPLICABLE }, 1 }, + { QI(durability_service), P(DURABILITYSERVICE), QA_TP | QA_WR, {1,1,7}, { RXO_INAPPLICABLE }, 6 }, + { Q0(entity_name), P(INVALID), QA_TP|QA_PUB|QA_SUB|QA_RD|QA_WR, {1,0,0}, { RXO_DONTEVENTRY }, 0 }, }; #undef P #undef Q @@ -707,6 +792,54 @@ CU_Test(ddsc_qos_set, writer_two) do_endpoint (QA_WR, QA_WR | QA_PUB, false, do_entity_two, create_writer_wrapper); } +static void do_entity_one_invalid (uint32_t appl_mask, const uint32_t check_mask, const bool sparse_qos, dds_entity_t base, dds_entity_t (* const create) (dds_entity_t base, const dds_qos_t *qos)) +{ + (void)check_mask; + (void)sparse_qos; + // Check that for each applicable QoS setting garbage will cause the entity + // creation to fail. + for (size_t i = 0; i < sizeof (qostable) / sizeof (qostable[0]); i++) + { + if (qostable[i].invalid == NULL) + continue; + if ((qostable[i].appl & appl_mask) == 0) + continue; + for (int v = 0; v <= qostable[i].max_invalid; v++) + { + dds_qos_t *qos = dds_create_qos (); + qostable[i].invalid (qos, v); + const dds_entity_t ent = create (base, qos); + CU_ASSERT_FATAL (ent < 0); + dds_delete_qos (qos); + } + } +} + +CU_Test(ddsc_qos_set, topic_one_invalid) +{ + do_nonendpoint (QA_TP, QA_TP, true, do_entity_one_invalid, create_topic_wrapper); +} + +CU_Test(ddsc_qos_set, subscriber_one_invalid) +{ + do_nonendpoint (QA_SUB, QA_SUB, false, do_entity_one_invalid, create_subscriber_wrapper); +} + +CU_Test(ddsc_qos_set, publisher_one_invalid) +{ + do_nonendpoint (QA_PUB, QA_PUB, false, do_entity_one_invalid, create_publisher_wrapper); +} + +CU_Test(ddsc_qos_set, reader_one_invalid) +{ + do_endpoint (QA_RD, QA_RD | QA_SUB, false, do_entity_one_invalid, create_reader_wrapper); +} + +CU_Test(ddsc_qos_set, writer_one_invalid) +{ + do_endpoint (QA_WR, QA_WR | QA_PUB, false, do_entity_one_invalid, create_writer_wrapper); +} + static void sync_on_discovery (const dds_entity_t dprd, const dds_entity_t dpwr) { // Use a new, unique topic for each pair: the next-easiest way to prevent trouble From ab648682f7de7dccc992d4f864f639ee96a102ea Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 9 Apr 2024 14:02:23 +0200 Subject: [PATCH 069/207] Check QoS changes are accepted/rejected as planned Signed-off-by: Erik Boasson --- src/core/ddsc/tests/qos_set_match.c | 128 +++++++++++++++++++++------- 1 file changed, 97 insertions(+), 31 deletions(-) diff --git a/src/core/ddsc/tests/qos_set_match.c b/src/core/ddsc/tests/qos_set_match.c index 47fb24aeda..89de54afc9 100644 --- a/src/core/ddsc/tests/qos_set_match.c +++ b/src/core/ddsc/tests/qos_set_match.c @@ -467,6 +467,12 @@ enum rxo_sense { RXO_DONTEVENTRY // special for entity name: don't even try RxO matching on this }; +enum changeable { + C_NO, // immutable QoS + C_YES, // changeable in spec and impl + C_UNSUPP // changeable in spec, not in impl +}; + #define MAX_VALUES 3 struct qostable_elem { @@ -479,6 +485,7 @@ struct qostable_elem { int max[MAX_VALUES]; enum rxo_sense rxo[MAX_VALUES]; int max_invalid; + enum changeable changeable; }; // Note: user/topic/group data covered by ddsc_userdata tests @@ -491,31 +498,31 @@ struct qostable_elem { #define Q0(name) #name, name##_set, name##_check, NULL #define P(NAME) DDS_##NAME##_QOS_POLICY_ID static const struct qostable_elem qostable[] = { - { QI(durability), P(DURABILITY), QA_TP | QA_RD | QA_WR, {3,0,0}, { RXO_IF_RD_LEQ }, 0 }, - { QI(reliability), P(RELIABILITY), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_LEQ }, 1 }, - { QI(latency_budget), P(LATENCYBUDGET), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_GEQ }, 0 }, + { QI(durability), P(DURABILITY), QA_TP | QA_RD | QA_WR, {3,0,0}, { RXO_IF_RD_LEQ }, 0, C_NO }, + { QI(reliability), P(RELIABILITY), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_LEQ }, 1, C_NO }, + { QI(latency_budget), P(LATENCYBUDGET), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_GEQ }, 0, C_UNSUPP }, #if DDS_HAS_DEADLINE_MISSED - { QI(deadline), P(DEADLINE), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_GEQ }, 0 }, + { QI(deadline), P(DEADLINE), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_GEQ }, 0, C_UNSUPP }, #endif - { QI(time_based_filter), P(TIMEBASEDFILTER), QA_RD, {1,0,0}, { RXO_INAPPLICABLE }, 0 }, - { QI(ownership), P(OWNERSHIP), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_EQ }, 0 }, - { Q0(ownership_strength), P(OWNERSHIPSTRENGTH), QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0 }, - { QI(destination_order), P(DESTINATIONORDER), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_LEQ }, 0 }, + { QI(time_based_filter), P(TIMEBASEDFILTER), QA_RD, {1,0,0}, { RXO_INAPPLICABLE }, 0, C_YES }, + { QI(ownership), P(OWNERSHIP), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_EQ }, 0, C_NO }, + { Q0(ownership_strength), P(OWNERSHIPSTRENGTH), QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0, C_YES }, + { QI(destination_order), P(DESTINATIONORDER), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_IF_RD_LEQ }, 0, C_NO }, #if DDS_HAS_LIFESPAN - { QI(lifespan), P(LIFESPAN), QA_TP | QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0 }, + { QI(lifespan), P(LIFESPAN), QA_TP | QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0, C_YES }, #endif - { Q0(transport_priority), P(TRANSPORTPRIORITY), QA_TP | QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0 }, - { QI(history), P(HISTORY), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0 }, - { QI(liveliness), P(LIVELINESS), QA_TP | QA_RD | QA_WR, {2,1,0}, { RXO_IF_RD_LEQ, RXO_IF_RD_GEQ }, 1 }, - { QI(resource_limits), P(RESOURCELIMITS), QA_TP | QA_RD | QA_WR, {7,0,0}, { RXO_INAPPLICABLE }, 2 }, - { QI(presentation), P(PRESENTATION), QA_PUB | QA_SUB, {2,1,1}, { RXO_IF_RD_LEQ, RXO_IF_RD_LEQ, RXO_IF_RD_LEQ }, 0 }, - { Q0(partition), P(PARTITION), QA_PUB | QA_SUB, {2,0,0}, { RXO_PARTITION }, 0 }, - { QI(ignorelocal), P(INVALID), QA_PUB | QA_SUB| QA_RD | QA_WR, {2,0,0}, { RXO_IGNORELOCAL }, 0 }, - { Q0(writer_batching), P(INVALID), QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0 }, - { Q0(writer_data_lifecycle), P(INVALID), QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0 }, - { QI(reader_data_lifecycle), P(INVALID), QA_RD, {1,1,0}, { RXO_INAPPLICABLE }, 1 }, - { QI(durability_service), P(DURABILITYSERVICE), QA_TP | QA_WR, {1,1,7}, { RXO_INAPPLICABLE }, 6 }, - { Q0(entity_name), P(INVALID), QA_TP|QA_PUB|QA_SUB|QA_RD|QA_WR, {1,0,0}, { RXO_DONTEVENTRY }, 0 }, + { Q0(transport_priority), P(TRANSPORTPRIORITY), QA_TP | QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0, C_YES }, + { QI(history), P(HISTORY), QA_TP | QA_RD | QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0, C_NO }, + { QI(liveliness), P(LIVELINESS), QA_TP | QA_RD | QA_WR, {2,1,0}, { RXO_IF_RD_LEQ, RXO_IF_RD_GEQ }, 1, C_NO }, + { QI(resource_limits), P(RESOURCELIMITS), QA_TP | QA_RD | QA_WR, {7,0,0}, { RXO_INAPPLICABLE }, 2, C_NO }, + { QI(presentation), P(PRESENTATION), QA_PUB | QA_SUB, {2,1,1}, { RXO_IF_RD_LEQ, RXO_IF_RD_LEQ, RXO_IF_RD_LEQ }, 0, C_NO }, + { Q0(partition), P(PARTITION), QA_PUB | QA_SUB, {2,0,0}, { RXO_PARTITION }, 0, C_UNSUPP }, + { QI(ignorelocal), P(INVALID), QA_PUB | QA_SUB| QA_RD | QA_WR, {2,0,0}, { RXO_IGNORELOCAL }, 0, C_NO }, + { Q0(writer_batching), P(INVALID), QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0, C_NO }, + { Q0(writer_data_lifecycle), P(INVALID), QA_WR, {1,0,0}, { RXO_INAPPLICABLE }, 0, C_YES }, + { QI(reader_data_lifecycle), P(INVALID), QA_RD, {1,1,0}, { RXO_INAPPLICABLE }, 1, C_YES }, + { QI(durability_service), P(DURABILITYSERVICE), QA_TP | QA_WR, {1,1,7}, { RXO_INAPPLICABLE }, 6, C_NO }, + { Q0(entity_name), P(INVALID), QA_TP|QA_PUB|QA_SUB|QA_RD|QA_WR, {1,0,0}, { RXO_DONTEVENTRY }, 0, C_NO }, }; #undef P #undef Q @@ -840,6 +847,75 @@ CU_Test(ddsc_qos_set, writer_one_invalid) do_endpoint (QA_WR, QA_WR | QA_PUB, false, do_entity_one_invalid, create_writer_wrapper); } +static void check_qos (const bool is_appl, struct qostable_elem const * const te, dds_entity_t entity, int const * const v) +{ + dds_qos_t *qos = dds_create_qos (); + dds_return_t rc; + rc = dds_get_qos (entity, qos); + CU_ASSERT_FATAL (rc == 0); + te->check (is_appl ? CM_SET : CM_UNSET, qos, v); + dds_delete_qos (qos); +} + +static void do_entity_one_change (uint32_t appl_mask, const uint32_t check_mask, const bool sparse_qos, dds_entity_t base, dds_entity_t (* const create) (dds_entity_t base, const dds_qos_t *qos)) +{ + const int v0[MAX_VALUES] = { 0 }; + const int v1[MAX_VALUES] = { 1 }; // intentionally {1,0...} + (void)check_mask; + (void)sparse_qos; + // Check that changes to mutable QoS (in spec & impl) are allowed and that changes + // to the others are rejected. Check both the return value of dds_set_qos and the + // QoS after the (attempted) change. + for (size_t i = 0; i < sizeof (qostable) / sizeof (qostable[0]); i++) + { + if ((qostable[i].appl & appl_mask) == 0) + continue; + dds_qos_t *qos = dds_create_qos (); + qostable[i].set (qos, v0); + const dds_entity_t ent = create (base, qos); + CU_ASSERT_FATAL (ent > 0); + qostable[i].set (qos, v1); + dds_return_t rc = dds_set_qos (ent, qos); + dds_return_t expected = 0; + switch (qostable[i].changeable) + { + case C_YES: expected = 0; break; + case C_NO: expected = DDS_RETCODE_IMMUTABLE_POLICY; break; + case C_UNSUPP: expected = DDS_RETCODE_UNSUPPORTED; break; + } + CU_ASSERT_FATAL (rc == expected); + dds_delete_qos (qos); + check_qos (true, &qostable[i], ent, (rc == 0) ? v1 : v0); + rc = dds_delete (ent); + CU_ASSERT_FATAL (rc == 0); + } +} + +CU_Test(ddsc_qos_set, topic_one_change) +{ + do_nonendpoint (QA_TP, QA_TP, true, do_entity_one_change, create_topic_wrapper); +} + +CU_Test(ddsc_qos_set, subscriber_one_change) +{ + do_nonendpoint (QA_SUB, QA_SUB, false, do_entity_one_change, create_subscriber_wrapper); +} + +CU_Test(ddsc_qos_set, publisher_one_change) +{ + do_nonendpoint (QA_PUB, QA_PUB, false, do_entity_one_change, create_publisher_wrapper); +} + +CU_Test(ddsc_qos_set, reader_one_change) +{ + do_endpoint (QA_RD, QA_RD | QA_SUB, false, do_entity_one_change, create_reader_wrapper); +} + +CU_Test(ddsc_qos_set, writer_one_change) +{ + do_endpoint (QA_WR, QA_WR | QA_PUB, false, do_entity_one_change, create_writer_wrapper); +} + static void sync_on_discovery (const dds_entity_t dprd, const dds_entity_t dpwr) { // Use a new, unique topic for each pair: the next-easiest way to prevent trouble @@ -889,16 +965,6 @@ static void sync_on_discovery (const dds_entity_t dprd, const dds_entity_t dpwr) CU_ASSERT_FATAL (rc == 0); } -static void check_qos (const bool is_appl, struct qostable_elem const * const te, dds_entity_t entity, int const * const v) -{ - dds_qos_t *qos = dds_create_qos (); - dds_return_t rc; - rc = dds_get_qos (entity, qos); - CU_ASSERT_FATAL (rc == 0); - te->check (is_appl ? CM_SET : CM_UNSET, qos, v); - dds_delete_qos (qos); -} - static void do_ddsc_qos_set_endpoints_with_rxo (const dds_entity_t dprd, const dds_entity_t dpwr) { // 1. Check that for each QoS applicable to readers/writers that creating endpoints From 826a070cfc6e3470ce26b7e186d4265d7ddf3e24 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 9 Apr 2024 14:31:31 +0200 Subject: [PATCH 070/207] dds_qset_entity_name should free old value if set Signed-off-by: Erik Boasson --- src/core/ddsc/src/dds_qos.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/ddsc/src/dds_qos.c b/src/core/ddsc/src/dds_qos.c index 801913cd17..46a24fbda0 100644 --- a/src/core/ddsc/src/dds_qos.c +++ b/src/core/ddsc/src/dds_qos.c @@ -434,7 +434,9 @@ void dds_qset_entity_name (dds_qos_t * __restrict qos, const char * name) { if (qos == NULL || name == NULL) return; - qos->entity_name = dds_string_dup(name); + if (qos->present & DDSI_QP_ENTITY_NAME) + dds_free (qos->entity_name); + qos->entity_name = dds_string_dup (name); qos->present |= DDSI_QP_ENTITY_NAME; } From 6498bf992059d3f491f5b351da8c7f0eb15f04a7 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Wed, 10 Apr 2024 13:14:46 +0200 Subject: [PATCH 071/207] Add TOPIC_DATA to ddsi_default_qos_topic No externally visible effect for applications, but not setting is wrong and affects the C++ QoS provider implementation because it directly looks at the default QoS objects. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_plist.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/ddsi/src/ddsi_plist.c b/src/core/ddsi/src/ddsi_plist.c index f02baad38e..dd5c80f5d4 100644 --- a/src/core/ddsi/src/ddsi_plist.c +++ b/src/core/ddsi/src/ddsi_plist.c @@ -3662,7 +3662,7 @@ const dds_qos_t ddsi_default_qos_writer = { }; const dds_qos_t ddsi_default_qos_topic = { - .present = DDSI_QP_PRESENTATION | DDSI_QP_DURABILITY | DDSI_QP_DEADLINE | DDSI_QP_LATENCY_BUDGET | DDSI_QP_LIVELINESS | DDSI_QP_DESTINATION_ORDER | DDSI_QP_HISTORY | DDSI_QP_RESOURCE_LIMITS | DDSI_QP_TRANSPORT_PRIORITY | DDSI_QP_OWNERSHIP | DDSI_QP_CYCLONE_IGNORELOCAL | DDSI_QP_DURABILITY_SERVICE | DDSI_QP_RELIABILITY | DDSI_QP_LIFESPAN | DDSI_QP_DATA_REPRESENTATION, + .present = DDSI_QP_PRESENTATION | DDSI_QP_DURABILITY | DDSI_QP_DEADLINE | DDSI_QP_LATENCY_BUDGET | DDSI_QP_LIVELINESS | DDSI_QP_DESTINATION_ORDER | DDSI_QP_HISTORY | DDSI_QP_RESOURCE_LIMITS | DDSI_QP_TOPIC_DATA | DDSI_QP_TRANSPORT_PRIORITY | DDSI_QP_OWNERSHIP | DDSI_QP_CYCLONE_IGNORELOCAL | DDSI_QP_DURABILITY_SERVICE | DDSI_QP_RELIABILITY | DDSI_QP_LIFESPAN | DDSI_QP_DATA_REPRESENTATION, .aliased = DDSI_QP_DATA_REPRESENTATION, .presentation.access_scope = DDS_PRESENTATION_INSTANCE, .presentation.coherent_access = 0, @@ -3678,6 +3678,8 @@ const dds_qos_t ddsi_default_qos_topic = { .resource_limits.max_samples = DDS_LENGTH_UNLIMITED, .resource_limits.max_instances = DDS_LENGTH_UNLIMITED, .resource_limits.max_samples_per_instance = DDS_LENGTH_UNLIMITED, + .topic_data.length = 0, + .topic_data.value = NULL, .transport_priority.value = 0, .ownership.kind = DDS_OWNERSHIP_SHARED, .ignorelocal.value = DDS_IGNORELOCAL_NONE, From ac3c75003a1eeda38fa8d51368b11fcec9730b6b Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 11 Apr 2024 15:55:05 +0200 Subject: [PATCH 072/207] Add EXPORT_ALL_SYMBOLS option to build system Signed-off-by: Erik Boasson --- CMakeLists.txt | 4 ++++ fuzz/oss-fuzz-build.sh | 2 +- src/core/CMakeLists.txt | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eb7e2e0d6c..de4b500c88 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -246,6 +246,10 @@ set(MEMORYCHECK_COMMAND_OPTIONS "--track-origins=yes --leak-check=full --trace-c # library so we can actually build the tests. option(BUILD_TESTING "Build the testing tree." OFF) +# For special-purpose builds it can be useful to export all symbols from the library, +# like we do when building the tests. +option(EXPORT_ALL_SYMBOLS "Export all symbols from the library." OFF) + # Include the xtests for idlc. These tests use the idl compiler (C back-end) to # compile an idl file at (test) runtime, and use the C compiler to build a test # application for the generated types, that is executed to do the actual testing. diff --git a/fuzz/oss-fuzz-build.sh b/fuzz/oss-fuzz-build.sh index 29176988ea..1aa8942713 100644 --- a/fuzz/oss-fuzz-build.sh +++ b/fuzz/oss-fuzz-build.sh @@ -18,7 +18,7 @@ mkdir build cd build cmake \ -DBUILD_IDLC=ON \ - -DBUILD_TESTING=ON \ + -DEXPORT_ALL_SYMBOLS=ON \ -DBUILD_SHARED_LIBS=OFF \ -DBUILD_EXAMPLES=NO \ -DENABLE_SECURITY=NO \ diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index a37f837212..d4d23a49f5 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -13,7 +13,7 @@ include (GenerateExportHeader) add_library(ddsc) -if(BUILD_TESTING) +if(BUILD_TESTING OR EXPORT_ALL_SYMBOLS) set_property(TARGET ddsc PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS TRUE) else() set_property(TARGET ddsc PROPERTY C_VISIBILITY_PRESET hidden) From 31a4843667830be87a38bd8bb22268061f79b42b Mon Sep 17 00:00:00 2001 From: Robert Femmer <114982872+robertfemmer@users.noreply.github.com> Date: Fri, 12 Apr 2024 09:02:44 +0200 Subject: [PATCH 073/207] Add fuzzer for security deserializer (#1967) * fuzz: add fuzzer targeting deserializer in security plugin * fuzz_security_deser: set linker language to cxx --- fuzz/CMakeLists.txt | 1 + fuzz/fuzz_security_deser/CMakeLists.txt | 16 ++++++++++ .../fuzz_security_deser/fuzz_security_deser.c | 28 ++++++++++++++++++ .../2d324193bb3029278fbc99dcd574f74b9d465296 | Bin 0 -> 10 bytes fuzz/oss-fuzz-build.sh | 2 +- 5 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 fuzz/fuzz_security_deser/CMakeLists.txt create mode 100644 fuzz/fuzz_security_deser/fuzz_security_deser.c create mode 100644 fuzz/fuzz_security_deser/fuzz_security_deser_seed_corpus/2d324193bb3029278fbc99dcd574f74b9d465296 diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt index 1b8ac70e17..30be15ee8f 100644 --- a/fuzz/CMakeLists.txt +++ b/fuzz/CMakeLists.txt @@ -18,4 +18,5 @@ add_subdirectory(fuzz_config_init) add_subdirectory(fuzz_handle_rtps_message) add_subdirectory(fuzz_type_object) add_subdirectory(fuzz_sample_deser) +add_subdirectory(fuzz_security_deser) # add_subdirectory(fuzz_idlc) diff --git a/fuzz/fuzz_security_deser/CMakeLists.txt b/fuzz/fuzz_security_deser/CMakeLists.txt new file mode 100644 index 0000000000..ddb223b8f3 --- /dev/null +++ b/fuzz/fuzz_security_deser/CMakeLists.txt @@ -0,0 +1,16 @@ +project(fuzz_security_deser LANGUAGES C) +cmake_minimum_required(VERSION 3.5) + +if(NOT TARGET CycloneDDS::ddsc) + # Find the CycloneDDS package. + find_package(CycloneDDS REQUIRED) +endif() + +add_executable(fuzz_security_deser fuzz_security_deser.c) +target_include_directories( + fuzz_security_deser PRIVATE + "$" + "$" + "$") +set_target_properties(fuzz_security_deser PROPERTIES LINKER_LANGUAGE CXX) +target_link_libraries(fuzz_security_deser CycloneDDS::ddsc $ENV{LIB_FUZZING_ENGINE}) diff --git a/fuzz/fuzz_security_deser/fuzz_security_deser.c b/fuzz/fuzz_security_deser/fuzz_security_deser.c new file mode 100644 index 0000000000..c23370dcb2 --- /dev/null +++ b/fuzz/fuzz_security_deser/fuzz_security_deser.c @@ -0,0 +1,28 @@ +#include +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + { + DDS_Security_Deserializer dser = DDS_Security_Deserializer_new(data, size); + DDS_Security_KeyMaterial_AES_GCM_GMAC km; + memset(&km, 0, sizeof(DDS_Security_KeyMaterial_AES_GCM_GMAC)); + DDS_Security_Deserialize_KeyMaterial_AES_GCM_GMAC(dser, &km); + DDS_Security_Deserializer_free(dser); + DDS_Security_KeyMaterial_AES_GCM_GMAC_deinit(&km); + } + + { + DDS_Security_ParticipantBuiltinTopicData *pbtd = DDS_Security_ParticipantBuiltinTopicData_alloc(); + DDS_Security_SecurityException ex; + DDS_Security_Exception_clean(&ex); + DDS_Security_Deserializer dser = DDS_Security_Deserializer_new(data, size); + DDS_Security_Deserialize_ParticipantBuiltinTopicData(dser, pbtd, &ex); + DDS_Security_Deserializer_free(dser); + DDS_Security_Exception_reset(&ex); + DDS_Security_ParticipantBuiltinTopicData_free(pbtd); + } + + return 0; +} diff --git a/fuzz/fuzz_security_deser/fuzz_security_deser_seed_corpus/2d324193bb3029278fbc99dcd574f74b9d465296 b/fuzz/fuzz_security_deser/fuzz_security_deser_seed_corpus/2d324193bb3029278fbc99dcd574f74b9d465296 new file mode 100644 index 0000000000000000000000000000000000000000..980993a4c7010df42b064d1b47073d2565f7d30f GIT binary patch literal 10 OcmY#9&j12U3=9AWp#bv$ literal 0 HcmV?d00001 diff --git a/fuzz/oss-fuzz-build.sh b/fuzz/oss-fuzz-build.sh index 1aa8942713..b2d6896e13 100644 --- a/fuzz/oss-fuzz-build.sh +++ b/fuzz/oss-fuzz-build.sh @@ -21,7 +21,7 @@ cmake \ -DEXPORT_ALL_SYMBOLS=ON \ -DBUILD_SHARED_LIBS=OFF \ -DBUILD_EXAMPLES=NO \ - -DENABLE_SECURITY=NO \ + -DENABLE_SECURITY=ON \ -DENABLE_SSL=NO \ -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ -DCMAKE_INSTALL_PREFIX=/usr/local .. From 64066d8558aea9943409e12a92d8602c56d039df Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 15 Apr 2024 15:04:22 +0200 Subject: [PATCH 074/207] Fixes for deserializers in authentication plugin This fixes some memory leaks and stops earlier following a deserialization error. Signed-off-by: Erik Boasson --- .../core/src/dds_security_serialize.c | 74 ++++++++++--------- src/security/core/src/dds_security_utils.c | 5 +- 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/src/security/core/src/dds_security_serialize.c b/src/security/core/src/dds_security_serialize.c index 1a8c4faa84..5f0b640bb5 100644 --- a/src/security/core/src/dds_security_serialize.c +++ b/src/security/core/src/dds_security_serialize.c @@ -549,14 +549,14 @@ DDS_Security_Deserialize_string( if (dser->remain < sz) { return 0; } - - if (sz > 0 && (dser->cursor[sz-1] == 0)) { - *value = ddsrt_strdup((char *)dser->cursor); - dser->cursor += sz; - dser->remain -= sz; - } else { - *value = ddsrt_strdup(""); + if (sz == 0 || dser->cursor[sz-1] != 0) { + return 0; } + + ddsrt_free (*value); + *value = ddsrt_strdup((char *)dser->cursor); + dser->cursor += sz; + dser->remain -= sz; return 1; } @@ -581,22 +581,25 @@ DDS_Security_Deserialize_OctetSeq( DDS_Security_Deserializer dser, DDS_Security_OctetSeq *seq) { - if (!DDS_Security_Deserialize_uint32_t(dser, &seq->_length)) { + uint32_t length; + if (!DDS_Security_Deserialize_uint32_t(dser, &length)) { return 0; } - if (dser->remain < seq->_length) { + if (dser->remain < length) { return 0; } - if (seq->_length > 0) { + ddsrt_free (seq->_buffer); + seq->_length = seq->_maximum = length; + if (seq->_length == 0) { + seq->_buffer = NULL; + } else { seq->_buffer = ddsrt_malloc(seq->_length); memcpy(seq->_buffer, dser->cursor, seq->_length); - dser->cursor += seq->_length; - dser->remain -= seq->_length; - } else { - seq->_buffer = NULL; } + dser->cursor += seq->_length; + dser->remain -= seq->_length; return 1; } @@ -629,16 +632,17 @@ DDS_Security_Deserialize_PropertySeq( and just as good for checking that the length value isn't completely ridiculous. */ const uint32_t minpropsize = (uint32_t) (2 * sizeof (uint32_t)); int r = 1; - uint32_t i; + uint32_t length; - if (!DDS_Security_Deserialize_uint32_t(dser, &seq->_length)) { + if (!DDS_Security_Deserialize_uint32_t(dser, &length)) { return 0; - } else if (seq->_length > dser->remain / minpropsize) { - seq->_length = 0; + } else if (length > dser->remain / minpropsize) { return 0; - } else if (seq->_length > 0) { + } else if (length > 0) { + DDS_Security_PropertySeq_deinit(seq); + seq->_length = seq->_maximum = length; seq->_buffer = DDS_Security_PropertySeq_allocbuf(seq->_length); - for (i = 0; i < seq->_length && r; i++) { + for (uint32_t i = 0; i < seq->_length && r; i++) { r = DDS_Security_Deserialize_Property(dser, &seq->_buffer[i]); } } @@ -656,16 +660,17 @@ DDS_Security_Deserialize_BinaryPropertySeq( value isn't completely ridiculous. */ const uint32_t minpropsize = (uint32_t) (2 * sizeof (uint32_t)); int r = 1; - uint32_t i; + uint32_t length; - if (!DDS_Security_Deserialize_uint32_t(dser, &seq->_length)) { + if (!DDS_Security_Deserialize_uint32_t(dser, &length)) { return 0; - } else if (seq->_length > dser->remain / minpropsize) { - seq->_length = 0; + } else if (length > dser->remain / minpropsize) { return 0; - } else if (seq->_length > 0) { + } else if (length > 0) { + DDS_Security_BinaryPropertySeq_deinit(seq); + seq->_length = seq->_maximum = length; seq->_buffer = DDS_Security_BinaryPropertySeq_allocbuf(seq->_length); - for (i = 0; i < seq->_length && r; i++) { + for (uint32_t i = 0; i < seq->_length && r; i++) { r = DDS_Security_Deserialize_BinaryProperty(dser, &seq->_buffer[i]); } } @@ -710,15 +715,13 @@ DDS_Security_Deserialize_BuiltinTopicKey( DDS_Security_Deserializer dser, DDS_Security_BuiltinTopicKey_t key) { - int r = DDS_Security_Deserialize_uint32_t(dser, (uint32_t *)&key[0]) && - DDS_Security_Deserialize_uint32_t(dser, (uint32_t *)&key[1]) && - DDS_Security_Deserialize_uint32_t(dser, (uint32_t *)&key[2]); - - /* guid is 16 bytes, so skip the last 4 bytes */ - dser->cursor += 4; - dser->remain -= 4; - - return r; + /* guid is 16 bytes but BuiltinTopicKey is 3 uint32_t:s, so skip the last 4 bytes */ + uint32_t entity_id; + return + DDS_Security_Deserialize_uint32_t(dser, &key[0]) && + DDS_Security_Deserialize_uint32_t(dser, &key[1]) && + DDS_Security_Deserialize_uint32_t(dser, &key[2]) && + DDS_Security_Deserialize_uint32_t(dser, &entity_id); } static int @@ -750,6 +753,7 @@ DDS_Security_Deserialize_ParticipantBuiltinTopicData( } else if (len > dser->remain) { DDS_Security_Exception_set(ex, "Deserialization", DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Deserialize parameter failed: payload too long for buffer"); + r = 0; } else { switch (pid) { case PID_PARTICIPANT_GUID: diff --git a/src/security/core/src/dds_security_utils.c b/src/security/core/src/dds_security_utils.c index 5af37d1ec3..6c2b1f9eaa 100644 --- a/src/security/core/src/dds_security_utils.c +++ b/src/security/core/src/dds_security_utils.c @@ -39,10 +39,10 @@ DDS_Security_BinaryProperty_deinit( } ddsrt_free(p->name); - if (p->value._length > 0) { + if (p->value._buffer != NULL) { memset (p->value._buffer, 0, p->value._length); /* because key material can be stored in binary property */ + ddsrt_free(p->value._buffer); } - ddsrt_free(p->value._buffer); } void @@ -197,6 +197,7 @@ DDS_Security_BinaryPropertySeq_deinit( ddsrt_free(seq->_buffer[i].name); DDS_Security_OctetSeq_deinit(&seq->_buffer[i].value); } + ddsrt_free(seq->_buffer); } void From 2d0b3ec6a2f021b233f776d623fdfad8e07fb44c Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 15 Apr 2024 15:34:51 +0200 Subject: [PATCH 075/207] Some extra scripting for dealing with fuzzers * check.sh: uses the oss-fuzz infrastructure scripts to run over various fuzzing engines, trying to build the fuzzers and run a sanity check on them * local.sh: builds the fuzzers locally with some minor assumptions on locations Signed-off-by: Erik Boasson --- fuzz/check.sh | 26 ++++++++++++++++++ fuzz/local.sh | 48 ++++++++++++++++++++++++++++++++++ src/core/xtests/CMakeLists.txt | 2 +- 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100755 fuzz/check.sh create mode 100644 fuzz/local.sh diff --git a/fuzz/check.sh b/fuzz/check.sh new file mode 100755 index 0000000000..3e7463aeb3 --- /dev/null +++ b/fuzz/check.sh @@ -0,0 +1,26 @@ +#!/usr/bin/bash + +if [ ! -f "infra/helper.py" ] ; then + echo "this script must be executed in the oss-fuzz directory" 2>&1 + exit 33 +fi + +if [ "$1" = "build-image" ] ; then + shift + python3 infra/helper.py build_image cyclonedds +fi + +if [ ! -d "$1" -o ! -f "$1/src/core/ddsi/src/ddsi_init.c" ] ; then + echo "usage: $0 [build-image] cyclone-source-dir" 2>&1 + exit 33 +fi +srcdir="$1" + +set -x +engines="libfuzzer afl honggfuzz centipede" +for eng in $engines ; do + echo "********** ENGINE = $eng **********" + sudo rm -rf $srcdir/{build,install,build_python} + python3 infra/helper.py build_fuzzers --sanitizer address --engine $eng cyclonedds $srcdir || break + python3 infra/helper.py check_build --engine $eng cyclonedds || break +done diff --git a/fuzz/local.sh b/fuzz/local.sh new file mode 100644 index 0000000000..fcde516a59 --- /dev/null +++ b/fuzz/local.sh @@ -0,0 +1,48 @@ +#!/usr/bin/bash + +# Local build +# +# sudo apt install clang libfuzzer-14-dev (replace 14 with clang version) + +set -ex + +if [ ! -f ../src/core/ddsi/src/ddsi_receive.c -o ! -d ../fuzz ] ; then + echo "This expects to be run in a build directory that is a subdirectory of the Cyclone repo" 2>&1 + exit 1 +fi +if [ -z "$CYCLONEDDS_HOME" ] ; then + echo "Need CYCLONEDDS_HOME to be set" 2>&1 +fi +if [ -z "$CYCLONEDDS_PYTHON" -o ! -d "$CYCLONEDDS_PYTHON/tests/support_modules/fuzz_tools" ] ; then + echo "need CYCLONEDDS_PYTHON to point to the cyclone python binding sources" 2>&1 + exit 1 +fi + +export PATH="$CYCLONEDDS_HOME/bin:$PATH" +export LD_LIBRARY_PATH="$CYCLONEDDS_HOME/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" +export PATH="$CYCLONEDDS_HOME/lib:$PATH" +export PYTHONPATH="$CYCLONEDDS_PYTHON/tests/support_modules${PYTHONPATH:+:$PYTHONPATH}" + +# Use current git HEAD hash as seed +[ -z "$SEED" ] && SEED=$(git ls-remote https://github.com/eclipse-cyclonedds/cyclonedds HEAD |cut -f1) +python3 "../fuzz/fuzz_sample_deser/generate_idl.py" $SEED "../fuzz/fuzz_sample_deser" + +export CC=clang +export CXX=clang++ +export LIB_FUZZING_ENGINE=/usr/lib/llvm-14/lib/libFuzzer.a + +cmake -G Ninja \ + -DSANITIZER=address,undefined,fuzzer \ + -DEXPORT_ALL_SYMBOLS=ON \ + -DBUILD_SHARED_LIBS=OFF \ + -DBUILD_EXAMPLES=NO \ + -DENABLE_SECURITY=ON \ + -DENABLE_SSL=NO \ + -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ + -DBUILD_IDLC=NO \ + -DBUILD_DDSPERF=NO \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_PREFIX_PATH=$PWD/host_install \ + -DCMAKE_INSTALL_PREFIX=$PWD/install .. + +cmake --build . diff --git a/src/core/xtests/CMakeLists.txt b/src/core/xtests/CMakeLists.txt index 406a625782..e913404409 100644 --- a/src/core/xtests/CMakeLists.txt +++ b/src/core/xtests/CMakeLists.txt @@ -15,6 +15,6 @@ if(BUILD_TESTING AND BUILD_IDLC) add_subdirectory(initsampledeliv) endif() -if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_SYSTEM_NAME MATCHES "iOS") +if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_SYSTEM_NAME MATCHES "iOS" AND NOT DEFINED ENV{LIB_FUZZING_ENGINE}) add_subdirectory(symbol_export) endif() From 2ad37f4cc3d545149f680d6a8b0ff31e0ea84edc Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 16 Apr 2024 07:40:06 +0200 Subject: [PATCH 076/207] Fix handling of empty second copy of PropertySeq This changes the handling of PropertySeq and BinaryPropertySeq to always return the latest one in the message. Without this change a second (or later) empty sequence would be ignored, but a second (or later) non-empty sequence would be returned. The memory is initialised to an empty sequence on allocation, so it doesn't affect the behaviour for the first copy. This matters insofar as being consistent with some other deserialization functions matters. Signed-off-by: Erik Boasson --- .../core/src/dds_security_serialize.c | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/security/core/src/dds_security_serialize.c b/src/security/core/src/dds_security_serialize.c index 5f0b640bb5..1f0d9c7646 100644 --- a/src/security/core/src/dds_security_serialize.c +++ b/src/security/core/src/dds_security_serialize.c @@ -631,22 +631,20 @@ DDS_Security_Deserialize_PropertySeq( sequence is 4+1+(3 pad)+4+1 = 13 bytes. Just use 8 because it is way faster and just as good for checking that the length value isn't completely ridiculous. */ const uint32_t minpropsize = (uint32_t) (2 * sizeof (uint32_t)); - int r = 1; uint32_t length; - if (!DDS_Security_Deserialize_uint32_t(dser, &length)) { return 0; - } else if (length > dser->remain / minpropsize) { + } + if (length > dser->remain / minpropsize) { return 0; - } else if (length > 0) { - DDS_Security_PropertySeq_deinit(seq); - seq->_length = seq->_maximum = length; - seq->_buffer = DDS_Security_PropertySeq_allocbuf(seq->_length); - for (uint32_t i = 0; i < seq->_length && r; i++) { - r = DDS_Security_Deserialize_Property(dser, &seq->_buffer[i]); - } } - + DDS_Security_PropertySeq_deinit(seq); + seq->_length = seq->_maximum = length; + seq->_buffer = (seq->_length == 0) ? NULL : DDS_Security_PropertySeq_allocbuf(seq->_length); + int r = 1; + for (uint32_t i = 0; i < seq->_length && r; i++) { + r = DDS_Security_Deserialize_Property(dser, &seq->_buffer[i]); + } return r; } @@ -659,22 +657,20 @@ DDS_Security_Deserialize_BinaryPropertySeq( Just use 8 because it is way faster and just as good for checking that the length value isn't completely ridiculous. */ const uint32_t minpropsize = (uint32_t) (2 * sizeof (uint32_t)); - int r = 1; uint32_t length; - if (!DDS_Security_Deserialize_uint32_t(dser, &length)) { return 0; - } else if (length > dser->remain / minpropsize) { + } + if (length > dser->remain / minpropsize) { return 0; - } else if (length > 0) { - DDS_Security_BinaryPropertySeq_deinit(seq); - seq->_length = seq->_maximum = length; - seq->_buffer = DDS_Security_BinaryPropertySeq_allocbuf(seq->_length); - for (uint32_t i = 0; i < seq->_length && r; i++) { - r = DDS_Security_Deserialize_BinaryProperty(dser, &seq->_buffer[i]); - } } - + DDS_Security_BinaryPropertySeq_deinit(seq); + seq->_length = seq->_maximum = length; + seq->_buffer = (seq->_length == 0) ? NULL : DDS_Security_BinaryPropertySeq_allocbuf(seq->_length); + int r = 1; + for (uint32_t i = 0; i < seq->_length && r; i++) { + r = DDS_Security_Deserialize_BinaryProperty(dser, &seq->_buffer[i]); + } return r; } From b17c425a0c0f1fa0c12cb82b899094c7075277d5 Mon Sep 17 00:00:00 2001 From: T0ny Peng <4816327+t0ny-peng@users.noreply.github.com> Date: Tue, 16 Apr 2024 19:39:55 -0700 Subject: [PATCH 077/207] Initialize the ret variable to fix compiler warnings. --- src/core/ddsi/src/ddsi_raweth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ddsi/src/ddsi_raweth.c b/src/core/ddsi/src/ddsi_raweth.c index 8c28348566..faee6f7b7c 100644 --- a/src/core/ddsi/src/ddsi_raweth.c +++ b/src/core/ddsi/src/ddsi_raweth.c @@ -218,7 +218,7 @@ static ssize_t ddsi_raweth_conn_write (struct ddsi_tran_conn * conn, const ddsi_ { ddsi_raweth_conn_t uc = (ddsi_raweth_conn_t) conn; dds_return_t rc; - ssize_t ret; + ssize_t ret = -1; unsigned retry = 2; int sendflags = 0; struct msghdr msg; @@ -507,7 +507,7 @@ static ssize_t ddsi_raweth_conn_write (struct ddsi_tran_conn * conn, const ddsi_ { ddsi_raweth_conn_t uc = (ddsi_raweth_conn_t) conn; dds_return_t rc = DDS_RETCODE_OK; - ssize_t ret; + ssize_t ret = -1; struct ddsi_vlan_header vhdr; size_t hdrlen; (void) flags; From 4d5b6f325fc15e88987bcd60e335c5accfb749c2 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Wed, 24 Apr 2024 17:59:51 +0200 Subject: [PATCH 078/207] Fix leading underscore handling in IDLC IDL identifiers start with a letter, and a (single) leading underscore is allowed as an escape character to distinguish them keywords. That is, `Gloeiworm` and `_Gloeiworm` are the same identifier. This it implemented correctly. However, it follows that where an identifier is expect, a single underscore is forbidden, and so is anything with a leading double underscore. This detects those cases and raises an error. Signed-off-by: Erik Boasson --- src/idl/src/scanner.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/idl/src/scanner.c b/src/idl/src/scanner.c index 17fe810850..d0ac44a902 100644 --- a/src/idl/src/scanner.c +++ b/src/idl/src/scanner.c @@ -436,7 +436,7 @@ scan_pp_number(idl_pstate_t *pstate, const char *cur, const char **lim) } static int32_t -scan_identifier(idl_pstate_t *pstate, const char *cur, const char **lim) +scan_identifier(idl_pstate_t *pstate, const char *cur, const char **lim, bool allow_leading_underscores) { int32_t cnt = 0; @@ -452,6 +452,19 @@ scan_identifier(idl_pstate_t *pstate, const char *cur, const char **lim) cur += cnt; } while (cnt); + /* scan_identifier is only called when looking at alpha|_ */ + const char *tok = pstate->scanner.cursor; + assert(cur - tok > 0); + if (!allow_leading_underscores) { + if (cur - tok == 1 && tok[0] == '_') { + error(pstate, tok, "'_' is not a valid identifier"); + return IDL_RETCODE_SYNTAX_ERROR; + } else if (cur - tok >= 2 && tok[0] == '_' && tok[1] == '_') { + error(pstate, tok, "At most one leading underscore allowed in an identifier"); + return IDL_RETCODE_SYNTAX_ERROR; + } + } + switch (pstate->scanner.state) { case IDL_SCAN_ANNOTATION: pstate->scanner.state = IDL_SCAN_ANNOTATION_NAME; @@ -592,7 +605,7 @@ scan(idl_pstate_t *pstate, idl_lexeme_t *lex) if (chr == '.' && have_digit(pstate, next(pstate, cur))) { code = scan_pp_number(pstate, cur, &lim); } else if (have_alpha(pstate, cur) || chr == '_') { - code = scan_identifier(pstate, cur, &lim); + code = scan_identifier(pstate, cur, &lim, true); } else if (have_digit(pstate, cur)) { code = scan_pp_number(pstate, cur, &lim); } else if (have(pstate, cur, "::")) { @@ -611,7 +624,7 @@ scan(idl_pstate_t *pstate, idl_lexeme_t *lex) /* idl_stroull takes care of decimal vs. octal vs. hexadecimal */ code = scan_integer_literal(pstate, cur, &lim); } else if (have_alpha(pstate, cur) || chr == '_') { - code = scan_identifier(pstate, cur, &lim); + code = scan_identifier(pstate, cur, &lim, false); } else if (have(pstate, cur, "::") > 0) { code = scan_scope(pstate, cur, &lim); } else if ((cnt = have(pstate, cur, "<<")) > 0) { From 64f90338100fd28c902f8f5917fd5cec292aaf7a Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 16 Apr 2024 17:11:35 +0200 Subject: [PATCH 079/207] Fix size of AF_LINK address on BSD Signed-off-by: Erik Boasson --- src/ddsrt/src/sockets.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ddsrt/src/sockets.c b/src/ddsrt/src/sockets.c index c1aff6b205..7f46574873 100644 --- a/src/ddsrt/src/sockets.c +++ b/src/ddsrt/src/sockets.c @@ -76,7 +76,7 @@ ddsrt_sockaddr_get_size(const struct sockaddr *const sa) break; #elif defined(__APPLE__) || defined(__FreeBSD__) case AF_LINK: - sz = sizeof(struct sockaddr_dl); + sz = ((const struct sockaddr_dl *) sa)->sdl_len; break; #endif /* __linux */ default: From 6639902bcd35b266dd0ac4982fe086a18273f195 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 18 Apr 2024 10:46:33 +0200 Subject: [PATCH 080/207] Syntax check PSMX config string in core code The config string used to be a free-for-all, now it is restricted to what has been established as practice: key=value pairs, each terminated by a semicolon. It allows the final semicolon to be omitted. allows a backslash as an escape character in a value. It also disallows any name starting with CYCLONEDDS_, carving out a namespace for the core of cyclone to pass potentially valuable information to the plugin. In the string passed to the plugin, each key=value pair is terminated by a semicolon. Signed-off-by: Erik Boasson --- src/core/ddsc/src/dds__psmx.h | 2 + src/core/ddsc/src/dds_psmx.c | 73 +++++++++++++++++++++++++++++++++-- src/core/ddsc/tests/psmx.c | 38 ++++++++++++++++++ 3 files changed, 110 insertions(+), 3 deletions(-) diff --git a/src/core/ddsc/src/dds__psmx.h b/src/core/ddsc/src/dds__psmx.h index 27449e28a2..5834730ac8 100644 --- a/src/core/ddsc/src/dds__psmx.h +++ b/src/core/ddsc/src/dds__psmx.h @@ -51,6 +51,8 @@ typedef dds_return_t (*dds_psmx_create_fn) ( const char *config // PSMX specific configuration ); +char *dds_pubsub_message_exchange_configstr (const char *config); + dds_return_t dds_pubsub_message_exchange_init (const struct ddsi_domaingv *gv, struct dds_domain *domain); dds_return_t dds_pubsub_message_exchange_fini (struct dds_domain *domain); diff --git a/src/core/ddsc/src/dds_psmx.c b/src/core/ddsc/src/dds_psmx.c index d3634d19f4..7f613984d9 100644 --- a/src/core/ddsc/src/dds_psmx.c +++ b/src/core/ddsc/src/dds_psmx.c @@ -13,6 +13,7 @@ #include "dds/ddsrt/heap.h" #include "dds/ddsrt/dynlib.h" #include "dds/ddsrt/mh3.h" +#include "dds/ddsrt/io.h" #include "dds/ddsi/ddsi_locator.h" #include "dds/ddsi/ddsi_domaingv.h" #include "dds/ddsi/ddsi_endpoint.h" @@ -213,13 +214,69 @@ static dds_psmx_instance_id_t get_psmx_instance_id (const struct ddsi_domaingv * return ddsrt_mh3 (config_name, strlen (config_name), hashed_id); } -static dds_return_t psmx_instance_load (const struct ddsi_domaingv *gv, struct ddsi_config_psmx *config, struct dds_psmx **out, ddsrt_dynlib_t *lib_handle) +char *dds_pubsub_message_exchange_configstr (const char *config) +{ + // Check syntax: only KEY=VALUE pairs separated by ;, with backslash an escape character + // We make no assumptions on the names of the keys or their values, except that no keys + // may have CYCLONEDDS_ as a prefix, contain an escape character or an equals sign. + const char *kstart = config; // init to pacify compiler + enum { START, KEY0, KEY, VALUE_NORM, VALUE_ESCAPED } cs = START; + for (const char *c = config; *c; c++) { + switch (cs) { + case START: // start of string, signalled for acceptance check + case KEY0: // first character of key + kstart = c; + if (*c == '=') // key may not be empty + goto malformed; + cs = KEY; + // falls through + case KEY: // following characters of key + if (*c == ';' || *c == '\\') // key may not contain ; or backslash + goto malformed; + if (*c == '=') { // key may not have CYCLONEDDS_ as prefix + cs = VALUE_NORM; + if (c - kstart >= 11 && memcmp (kstart, "CYCLONEDDS_", 11) == 0) + goto malformed; + } + break; + case VALUE_NORM: // non-escaped characters in value + if (*c == ';' || *c == '\0') // ; -> next key (end of string same) + cs = KEY0; + else if (*c == '\\') // escape next character + cs = VALUE_ESCAPED; + break; + case VALUE_ESCAPED: // anything goes + cs = VALUE_NORM; // but only for this one character + break; + } + } + switch (cs) + { + case START: // empty config string is ok + case KEY0: // looking at the next key (after ';') + case VALUE_NORM: // end of value, we accept a missing ';' at the end + break; + default: + goto malformed; + } + + char *configstr = NULL; + // Config checking verifies structure of config string and absence of any CYCLONEDDS_ + // We append a semicolon if the original config string did not end on one + ddsrt_asprintf (&configstr, "%s%s", config, (cs == VALUE_NORM) ? ";" : ""); + return configstr; + +malformed: + return NULL; +} + +static dds_return_t psmx_instance_load (const struct ddsi_domaingv *gv, const struct ddsi_config_psmx *config, struct dds_psmx **out, ddsrt_dynlib_t *lib_handle) { dds_psmx_create_fn creator = NULL; const char *lib_name; ddsrt_dynlib_t handle; char load_fn[100]; - dds_return_t ret; + dds_return_t ret = DDS_RETCODE_ERROR; struct dds_psmx *psmx_instance = NULL; if (!config->library || config->library[0] == '\0') @@ -227,6 +284,13 @@ static dds_return_t psmx_instance_load (const struct ddsi_domaingv *gv, struct d else lib_name = config->library; + char *configstr; + if ((configstr = dds_pubsub_message_exchange_configstr (config->config)) == NULL) + { + GVERROR ("Configuration for PSMX instance '%s' is invalid\n", config->name); + goto err_configstr; + } + if ((ret = ddsrt_dlopen (lib_name, true, &handle)) != DDS_RETCODE_OK) { char buf[1024]; @@ -243,7 +307,7 @@ static dds_return_t psmx_instance_load (const struct ddsi_domaingv *gv, struct d goto err_dlsym; } - if ((ret = creator (&psmx_instance, get_psmx_instance_id (gv, config->name), config->config)) != DDS_RETCODE_OK) + if ((ret = creator (&psmx_instance, get_psmx_instance_id (gv, config->name), configstr)) != DDS_RETCODE_OK) { GVERROR ("Failed to initialize PSMX instance '%s'.\n", config->name); goto err_init; @@ -251,12 +315,15 @@ static dds_return_t psmx_instance_load (const struct ddsi_domaingv *gv, struct d psmx_instance->priority = config->priority.value; *out = psmx_instance; *lib_handle = handle; + ddsrt_free (configstr); return DDS_RETCODE_OK; err_init: err_dlsym: ddsrt_dlclose (handle); err_dlopen: + ddsrt_free (configstr); +err_configstr: return ret; } diff --git a/src/core/ddsc/tests/psmx.c b/src/core/ddsc/tests/psmx.c index e54cd30db5..050e537115 100644 --- a/src/core/ddsc/tests/psmx.c +++ b/src/core/ddsc/tests/psmx.c @@ -26,6 +26,7 @@ #include "ddsi__xevent.h" #include "dds__entity.h" #include "dds__serdata_default.h" +#include "dds__psmx.h" #include "config_env.h" #include "test_common.h" @@ -1571,3 +1572,40 @@ CU_Test (ddsc_psmx, writer_loan) } dds_delete (dds_get_parent (pp)); } + +CU_Test (ddsc_psmx, configstr) +{ + static const struct { const char *in; const char *out; } cases[] = { + { "", "" }, + { ";", NULL }, + { "X", NULL }, + { "=", NULL }, + { "=Y", NULL }, + { "X;Y", NULL }, + { "X=", "X=;" }, + { "X=3", "X=3;" }, + { "X=3;", "X=3;" }, + { "X=3;;", NULL }, + { "X=3;YY=456", "X=3;YY=456;" }, + { "X=3;YY=456;", "X=3;YY=456;" }, + { "X=3;YY=4\\56;", "X=3;YY=4\\56;" }, + { "X=3;;YY=4\\56;", NULL }, + { "X\\=3;", NULL }, + { "X=3;\\", NULL }, + { "X=3\\", NULL }, + { "X=3\\\\", "X=3\\\\;" }, + { "X=3\\;Y=", "X=3\\;Y=;" }, + { "CYCLONEDDS_=", NULL }, + { "CYCLONEDDS_X=", NULL }, + { "X=3;CYCLONEDDS_=", NULL }, + { "X=3;CYCLONEDDS_X=", NULL } + }; + for (size_t i = 0; i < sizeof (cases) / sizeof (cases[0]); i++) { + char *p = dds_pubsub_message_exchange_configstr (cases[i].in); + CU_ASSERT_FATAL ((p == NULL) == (cases[i].out == NULL)); + if (p) { + CU_ASSERT_FATAL (strcmp (p, cases[i].out) == 0); + ddsrt_free (p); + } + } +} From d52f5440826a4321b654e0bd647b2cc79e07e39d Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 18 Apr 2024 10:47:14 +0200 Subject: [PATCH 081/207] Use hash of network config as Iceoryx locator For Iceoryx (or PSMX more generally) we need a unique identifier for Iceoryx instance. Ideally, Iceoryx would provide that, but it doesn't ... The plug-in used to try to come up with an identifier by fiddling with service discovery, but there is a race condition in that logic that can't be solved in the absence of an upper limit to the number of processes while not having any form of synchronization or time bounds. Fortunately, Iceoryx refuses to have multiple instances of itself on a single machine, and therefore something that can uniquely identify a machine can also be used. I haven't been able to find a good way to get a machine id from the kernel. That leaves writing stuff to the filesystem (which I don't like doing), allocating and retaining some form of shared memory to store it (also fraught with complications), or using some proxy for a proper machine id. The network configuration provides a reasonable option, as the MAC addresses are supposed to be unique. Then we get into trouble again: the network configuration can change, our getifaddrs() doesn't return the MAC address on Windows, etc. The code here is therefore flawed, but presumed good enough as replacement for the previous code that definitely did not work. Signed-off-by: Erik Boasson --- src/psmx_iox/CMakeLists.txt | 10 +++- src/psmx_iox/src/machineid.cpp | 94 ++++++++++++++++++++++++++++++ src/psmx_iox/src/machineid.hpp | 22 +++++++ src/psmx_iox/src/psmx_iox_impl.cpp | 57 +++--------------- 4 files changed, 133 insertions(+), 50 deletions(-) create mode 100644 src/psmx_iox/src/machineid.cpp create mode 100644 src/psmx_iox/src/machineid.hpp diff --git a/src/psmx_iox/CMakeLists.txt b/src/psmx_iox/CMakeLists.txt index 7c79d1c9ef..4021e93f31 100644 --- a/src/psmx_iox/CMakeLists.txt +++ b/src/psmx_iox/CMakeLists.txt @@ -14,10 +14,16 @@ include(GenerateExportHeader) message(STATUS "Building Iceoryx PSMX plugin") +set(psmx_iox_sources + src/psmx_iox_impl.cpp + include/psmx_iox_impl.hpp + src/machineid.cpp + src/machineid.hpp) + if(BUILD_SHARED_LIBS) - add_library(psmx_iox SHARED "src/psmx_iox_impl.cpp" "include/psmx_iox_impl.hpp") + add_library(psmx_iox SHARED ${psmx_iox_sources}) else() - add_library(psmx_iox OBJECT "src/psmx_iox_impl.cpp" "include/psmx_iox_impl.hpp") + add_library(psmx_iox OBJECT ${psmx_iox_sources}) set_property(GLOBAL APPEND PROPERTY cdds_plugin_list psmx_iox) set_property(GLOBAL PROPERTY psmx_iox_symbols iox_create_psmx) endif() diff --git a/src/psmx_iox/src/machineid.cpp b/src/psmx_iox/src/machineid.cpp new file mode 100644 index 0000000000..923cdd3df0 --- /dev/null +++ b/src/psmx_iox/src/machineid.cpp @@ -0,0 +1,94 @@ +// Copyright(c) 2024 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#include "machineid.hpp" + +#include "dds/ddsrt/md5.h" +#include "dds/ddsrt/ifaddrs.h" +#if defined(__linux) && !LWIP_SOCKET +#include "linux/if_packet.h" +#elif defined(__APPLE__) || defined(__QNXNTO__) || defined(__FreeBSD__) +#include "net/if_dl.h" +#endif + +std::optional get_machineid () +{ + // the non-foolproof strategy here: if we have some MAC addresses, use the + // MD5 hash of the concatenation of those as the machine id. If we don't + // have any, use the MD5 hash of the concatenation of IP addresses. If we + // don't have those give up. + // + // MAC addresses ought not to change, IP addresses can change, interfaces + // can come and go (even hardware interfaces), so it is really far from + // perfect. You would hope the kernel provides a unique id somehow + // somewhere, but I'm not sure enough about, e.g. kern.uuid on macOS. + // + // The reason this exists is simply that we need "something" for Iceoryx + // support, but as MAC addresses are the best thing I can think of (and + // ideally of the interface(s) used by Cyclone, but that gets into trouble + // with the initialization order). There is the fall-back of overriding + // the locator in the config, so one is never totally dependent on this. + // + // FIXME: our getifaddrs on Windows doesn't return MAC addresses + struct ddsrt_ifaddrs *ifa_root; + if (ddsrt_getifaddrs (&ifa_root, NULL) != DDS_RETCODE_OK) + return std::nullopt; + bool have_mac = false, have_ip = false; + ddsrt_md5_state_t md5st_mac, md5st_ip; + ddsrt_md5_init (&md5st_mac); + ddsrt_md5_init (&md5st_ip); + for (const struct ddsrt_ifaddrs *ifa = ifa_root; ifa; ifa = ifa->next) + { + const struct sockaddr *sa = ifa->addr; + switch (sa->sa_family) { +#if DDSRT_HAVE_IPV6 + case AF_INET6: { + const struct sockaddr_in6 *x = (const struct sockaddr_in6 *) sa; + ddsrt_md5_append (&md5st_ip, (const ddsrt_md5_byte_t *) &x->sin6_addr, sizeof (x->sin6_addr)); + have_ip = true; + break; + } +#endif /* DDSRT_HAVE_IPV6 */ + case AF_INET: { + const struct sockaddr_in *x = (const struct sockaddr_in *) sa; + ddsrt_md5_append (&md5st_ip, (const ddsrt_md5_byte_t *) &x->sin_addr, sizeof (x->sin_addr)); + have_ip = true; + break; + } +#if defined(__linux) && !LWIP_SOCKET + case AF_PACKET: { + const struct sockaddr_ll *x = (const struct sockaddr_ll *) sa; + ddsrt_md5_append (&md5st_mac, (const ddsrt_md5_byte_t *) &x->sll_addr, sizeof (x->sll_addr)); + have_mac = true; + break; + } +#elif defined(__APPLE__) || defined(__QNXNTO__) || defined(__FreeBSD__) + case AF_LINK: { + const struct sockaddr_dl *x = (const struct sockaddr_dl *) sa; + ddsrt_md5_append (&md5st_mac, (const ddsrt_md5_byte_t *) LLADDR (x), x->sdl_alen); + have_mac = true; + break; + } +#endif /* __linux */ + } + } + ddsrt_freeifaddrs (ifa_root); + dds_psmx_node_identifier_t mid; + static_assert (sizeof (mid.x) == 16); + if (have_mac) { + ddsrt_md5_finish (&md5st_mac, static_cast(mid.x)); + return mid; + } else if (have_ip) { + ddsrt_md5_finish (&md5st_ip, static_cast(mid.x)); + return mid; + } else { + return std::nullopt; + } +} diff --git a/src/psmx_iox/src/machineid.hpp b/src/psmx_iox/src/machineid.hpp new file mode 100644 index 0000000000..afb14e8505 --- /dev/null +++ b/src/psmx_iox/src/machineid.hpp @@ -0,0 +1,22 @@ +// Copyright(c) 2024 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#ifndef MACHINEID_HPP +#define MACHINEID_HPP + +#include +#include +#include + +#include "dds/ddsc/dds_psmx.h" + +std::optional get_machineid (); + +#endif /* MACHINEID_HPP */ diff --git a/src/psmx_iox/src/psmx_iox_impl.cpp b/src/psmx_iox/src/psmx_iox_impl.cpp index a2e0886329..f0f2e152bf 100644 --- a/src/psmx_iox/src/psmx_iox_impl.cpp +++ b/src/psmx_iox/src/psmx_iox_impl.cpp @@ -28,9 +28,9 @@ #include "iceoryx_posh/popo/untyped_subscriber.hpp" #include "iceoryx_posh/popo/listener.hpp" #include "iceoryx_posh/runtime/posh_runtime.hpp" -#include "iceoryx_posh/runtime/service_discovery.hpp" #include "psmx_iox_impl.hpp" +#include "machineid.hpp" #define ERROR_PREFIX "=== [ICEORYX] " @@ -92,9 +92,8 @@ static bool is_wildcard_partition(const char *str) struct iox_psmx : public dds_psmx_t { - iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service_name, const std::optional& node_id_override, bool support_keyed_topics); + iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service_name, const dds_psmx_node_identifier_t& node_id, bool support_keyed_topics); ~iox_psmx(); - void discover_node_id(dds_psmx_node_identifier_t node_id_fallback); bool _support_keyed_topics; iox::capro::IdString_t _service_name; std::unique_ptr _listener; //the listener needs to be created after iox runtime has been initialized @@ -102,7 +101,7 @@ struct iox_psmx : public dds_psmx_t std::shared_ptr _node_id_publisher; }; -iox_psmx::iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service_name, const std::optional& node_id_override, bool support_keyed_topics) : +iox_psmx::iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service_name, const dds_psmx_node_identifier_t& node_id, bool support_keyed_topics) : dds_psmx_t { .ops = psmx_ops, .instance_name = dds_string_dup ("CycloneDDS-IOX-PSMX"), @@ -121,14 +120,7 @@ iox_psmx::iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service iox::runtime::PoshRuntime::initRuntime(iox_runtime_name); _listener = std::unique_ptr(new iox::popo::Listener()); - if (node_id_override.has_value()) - _node_id = node_id_override.value(); - else - { - dds_psmx_node_identifier_t node_id_fallback = { 0 }; - memcpy(node_id_fallback.x, &instance_hash, sizeof (instance_hash)); - discover_node_id(node_id_fallback); - } + _node_id = node_id; dds_psmx_init_generic(this); } @@ -141,39 +133,6 @@ iox_psmx::~iox_psmx() } } -void iox_psmx::discover_node_id(dds_psmx_node_identifier_t node_id_fallback) -{ - const iox::capro::IdString_t disctopic{"CycloneDDS-IOX-PSMX node_id discovery"}; - iox::runtime::ServiceDiscovery serviceDiscovery; - unsigned int node_ids_present = 0; - iox::capro::IdString_t outstr; - serviceDiscovery.findService(_service_name, - disctopic, - iox::capro::Wildcard, - [&node_ids_present, &outstr](const iox::capro::ServiceDescription& s) { - node_ids_present++; - outstr = s.getEventIDString(); - }, - iox::popo::MessagingPattern::PUB_SUB); - if (node_ids_present > 1) - { - std::cerr << ERROR_PREFIX "inconsistency during node id creation" << std::endl; - assert(false); - } - else if (node_ids_present == 1) - { - _node_id = to_node_identifier(outstr).value(); - } - else - { - char tentative_node_id_str[33]; - for (uint32_t n = 0; n < 16; n++) - snprintf(tentative_node_id_str + 2 * n, sizeof(tentative_node_id_str) - 2 * n, "%02" PRIx8, node_id_fallback.x[n]); - _node_id = node_id_fallback; - _node_id_publisher = std::shared_ptr(new iox::popo::UntypedPublisher({_service_name, disctopic, tentative_node_id_str})); - } -} - struct iox_psmx_topic : public dds_psmx_topic_t { iox_psmx_topic(iox_psmx& psmx, const char * topic_name, const char * type_name, dds_data_type_properties_t data_type_props); @@ -692,9 +651,11 @@ dds_return_t iox_create_psmx(struct dds_psmx **psmx, dds_psmx_instance_id_t inst std::optional node_id = std::nullopt; if (opt_node_id.has_value()) { node_id = to_node_identifier(opt_node_id.value()); - if (!node_id.has_value()) - return DDS_RETCODE_ERROR; + } else { + node_id = get_machineid (); } + if (!node_id.has_value()) + return DDS_RETCODE_ERROR; auto opt_keyed_topics = get_config_option_value(config, "KEYED_TOPICS", true); bool keyed_topics = false; @@ -705,6 +666,6 @@ dds_return_t iox_create_psmx(struct dds_psmx **psmx, dds_psmx_instance_id_t inst return DDS_RETCODE_ERROR; } - *psmx = new iox_psmx::iox_psmx(instance_id, service_name, node_id, keyed_topics); + *psmx = new iox_psmx::iox_psmx(instance_id, service_name, node_id.value(), keyed_topics); return *psmx ? DDS_RETCODE_OK : DDS_RETCODE_ERROR; } From 7c253ad3c4461b10dc4cac36a257b097802cd043 Mon Sep 17 00:00:00 2001 From: Patrick Masselink Date: Fri, 26 Apr 2024 14:44:40 +0200 Subject: [PATCH 082/207] Fix building for Zephyr V3.6, QNX and other platforms that don't support single-source multicast and/or dynamic library loading Signed-off-by: Patrick Masselink --- ports/zephyr/README.md | 16 +- ports/zephyr/prj.conf | 1 + src/core/ddsc/src/dds__sysdef_model.h | 1 + src/core/ddsc/tests/waitset.c | 42 ++-- src/core/ddsi/src/ddsi_endpoint.c | 2 + src/core/ddsi/src/ddsi_nwinterfaces.c | 2 + src/core/ddsi/src/ddsi_sertype.c | 18 +- src/core/ddsi/src/ddsi_udp.c | 4 + src/core/ddsi/tests/wraddrset.c | 4 + src/ddsrt/include/dds/ddsrt/dynlib.h | 12 +- src/ddsrt/include/dds/ddsrt/sockets/posix.h | 13 +- src/ddsrt/src/dynlib.c | 32 +++ .../src/ifaddrs/zephyr/ifaddrs-v3.7pre.c | 220 ++++++++++++++++++ src/ddsrt/src/sockets/posix/gethostname.c | 4 + src/ddsrt/src/sockets/posix/socket.c | 79 +------ src/ddsrt/tests/log.c | 3 +- src/ucunit/CMakeLists.txt | 2 +- 17 files changed, 325 insertions(+), 130 deletions(-) create mode 100644 src/ddsrt/src/ifaddrs/zephyr/ifaddrs-v3.7pre.c diff --git a/ports/zephyr/README.md b/ports/zephyr/README.md index 14cc50b70d..8a39c2dc4c 100644 --- a/ports/zephyr/README.md +++ b/ports/zephyr/README.md @@ -4,8 +4,8 @@ This directory contains some proof-of-concept applications that show how to build and use CycloneDDS on [Zephyr RTOS](https://www.zephyrproject.org) for a NXP X-S32Z27X-DC board. -Getting Started with Zephyr information can be found [here](https://docs.zephyrproject.org/3.4.0/develop/getting_started/index.html) -Documentation for the NXP X-S32Z27X-DC board can be found [here](https://docs.zephyrproject.org/3.4.0/boards/arm/s32z270dc2_r52/doc/index.html) +Getting Started with Zephyr information can be found [here](https://docs.zephyrproject.org/3.6.0/develop/getting_started/index.html) +Documentation for the NXP X-S32Z27X-DC board can be found [here](https://docs.zephyrproject.org/3.6.0/boards/arm/s32z270dc2_r52/doc/index.html) ## Usage The applications can be treated similarly to other Zephyr sample applications. @@ -13,13 +13,13 @@ The `CMakeLists.txt` is currently set up to build some of the CycloneDDS example :warning: While CycloneDDS can be built in-tree, it does not support multiple different builds. Therefore the CycloneDDS source directory needs to be cleaned in order to build for Zephyr and must not contain an in-tree build for eg. the host system. Alternatively, this directory with Zephyr examples can be copied outside the CycloneDDS source directory but that requires updating the `ExternalProject_Add` directive in `CMakeLists.txt` to point to the CycloneDDS source directory. -:warning: When building outside the Zephyr tree, `ZEPHYR_BASE` variable must be set. See [Application Development](https://docs.zephyrproject.org/3.4.0/develop/application/index.html) for more info. +:warning: When building outside the Zephyr tree, `ZEPHYR_BASE` variable must be set. See [Application Development](https://docs.zephyrproject.org/3.6.0/develop/application/index.html) for more info. -:warning: A static IPv4/IPv6 address is defined in `prj.conf`. When running between two Zephyr nodes it is suggested to copy `prj.conf` to eg. `prj-host1.conf` and `prj-host2.conf`, updating the address as required and building with `-DCONF=prj-host1.conf` or `-DCONF=prj-host2.conf` respectively, as described in more detail [here](https://docs.zephyrproject.org/3.4.0/samples/net/eth_native_posix/README.html). A different approach is to enable DHCP client support in Zephyr (see [example](https://docs.zephyrproject.org/3.4.0/samples/net/dhcpv4_client/README.html)). +:warning: A static IPv4/IPv6 address is defined in `prj.conf`. When running between two Zephyr nodes it is suggested to copy `prj.conf` to eg. `prj-host1.conf` and `prj-host2.conf`, updating the address as required and building with `-DCONF=prj-host1.conf` or `-DCONF=prj-host2.conf` respectively, as described in more detail [here](https://docs.zephyrproject.org/3.6.0/samples/net/eth_native_posix/README.html). A different approach is to enable DHCP client support in Zephyr (see [example](https://docs.zephyrproject.org/3.6.0/samples/net/dhcpv4_client/README.html)). The `copy_examples.sh` script can be used to (manually) update the code from CycloneDDS examples and run `idlc` to generate types. -For example, to build Roundtrip Ping for the `s32z270dc2_rtu0_r52` target: +For example, to build Roundtrip Ping for the NXP S32Z270-DC2 board: ``` $ west build -b s32z270dc2_rtu0_r52 . -- -DBUILD_ROUNDTRIP_PING=1 ``` @@ -27,11 +27,13 @@ To build for qemu_x86, with ethernet support: ``` $ west build -b qemu_x86 . -- -DOVERLAY_CONFIG=overlay-e1000.conf -DBUILD_ROUNDTRIP_PING=1 ``` +:warning: In the current Zephyr v3.7.0 (draft) branch, board naming has been refactored and you should use `s32z2xxdc2/s32z270/rtu0`. + Command-line parameters for the example can be modified in `src/rountrip_main.c` The CycloneDDS configuration in `config.xml` is automatically converted to a char array and available as environment variable to support the default behaviour of retrieving config from `CYCLONEDDS_URI`. Alternatively, [dds_create_domain_with_rawconfig](https://cyclonedds.io/docs/cyclonedds/latest/api/domain.html?#c.dds_create_domain_with_rawconfig) can be used without XML configuration data. ## Zephyr versions -At the time of writing, CycloneDDS has been tested on Zephyr [v3.3.0](https://github.com/zephyrproject-rtos/zephyr/releases/tag/v3.3.0) and [v3.4.0](https://github.com/zephyrproject-rtos/zephyr/releases/tag/v3.4.0). However, for the NXP X-S32Z27X-DC board an issue exists in `v3.4.0` that can cause CycloneDDS to crash. This is fixed on the Zephyr main branch, therefore we suggest using [@143429](https://github.com/zephyrproject-rtos/zephyr/commit/14342969150a35f3c26afa513a4725bdec310799). - +At the time of writing, CycloneDDS has been tested on Zephyr [v3.6.0](https://github.com/zephyrproject-rtos/zephyr/releases/tag/v3.6.0) +To use CycloneDDS with the current (draft) V3.7.0 release, please replace `src/ddsrt/src/ifaddrs/zephyr/ifaddrs.c` with `ifaddrs-v3.7pre.c` which is compatible with the updated (IPv4) Networking APIs in Zephyr (though this code is in flux so YMMV). diff --git a/ports/zephyr/prj.conf b/ports/zephyr/prj.conf index 58230a68d0..0b39da5d5b 100644 --- a/ports/zephyr/prj.conf +++ b/ports/zephyr/prj.conf @@ -1,6 +1,7 @@ CONFIG_NEWLIB_LIBC=y CONFIG_NEWLIB_LIBC_NANO=n CONFIG_MAIN_STACK_SIZE=131072 +CONFIG_NET_HOSTNAME_ENABLE=y CONFIG_POSIX_API=y diff --git a/src/core/ddsc/src/dds__sysdef_model.h b/src/core/ddsc/src/dds__sysdef_model.h index 8c673dfb0e..b7da3656c2 100644 --- a/src/core/ddsc/src/dds__sysdef_model.h +++ b/src/core/ddsc/src/dds__sysdef_model.h @@ -12,6 +12,7 @@ #include "dds/dds.h" #include "dds/ddsi/ddsi_xqos.h" +#include "dds/ddsrt/sockets.h" #if defined (__cplusplus) extern "C" { diff --git a/src/core/ddsc/tests/waitset.c b/src/core/ddsc/tests/waitset.c index a2d4eb4b70..7c3d1200ad 100644 --- a/src/core/ddsc/tests/waitset.c +++ b/src/core/ddsc/tests/waitset.c @@ -38,7 +38,7 @@ typedef struct thread_arg_t { static void waiting_thread_start(struct thread_arg_t *arg, dds_entity_t expected); static dds_return_t waiting_thread_expect_exit(struct thread_arg_t *arg); -static dds_entity_t participant, topic, writer, reader, waitset, publisher, subscriber, readcond; +static dds_entity_t participant, topic, writer, reader, waitset, publisher, subscriber, rdcond; static void ddsc_waitset_basic_init (void) { @@ -71,8 +71,8 @@ static void ddsc_waitset_init (void) CU_ASSERT_FATAL (reader > 0); writer = dds_create_writer (publisher, topic, NULL, NULL); CU_ASSERT_FATAL (writer > 0); - readcond = dds_create_readcondition (reader, mask); - CU_ASSERT_FATAL (readcond > 0); + rdcond = dds_create_readcondition (reader, mask); + CU_ASSERT_FATAL (rdcond > 0); } static void ddsc_waitset_fini (void) @@ -140,7 +140,7 @@ CU_Theory((dds_entity_t par), ddsc_waitset_create, invalid_params, .init=ddsc_wa } CU_TheoryDataPoints(ddsc_waitset_create, non_participants) = { - CU_DataPoints(dds_entity_t*, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &rdcond), }; CU_Theory((dds_entity_t *par), ddsc_waitset_create, non_participants, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { @@ -199,8 +199,8 @@ CU_Theory((dds_entity_t ws, dds_attach_t a), ddsc_waitset_attach, invalid_waitse } CU_TheoryDataPoints(ddsc_waitset_attach, non_waitsets) = { - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &rdcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &rdcond), CU_DataPoints(dds_attach_t, (dds_attach_t)NULL, (dds_attach_t)&reader, (dds_attach_t)3, (dds_attach_t)0, (dds_attach_t)0, (dds_attach_t)0, (dds_attach_t)0), }; CU_Theory((dds_entity_t *ws, dds_entity_t *e, dds_attach_t a), ddsc_waitset_attach, non_waitsets, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) @@ -261,8 +261,8 @@ CU_Theory ((int owner, int ok1, int ok2, int fail), ddsc_waitset_attach, scoping } CU_TheoryDataPoints(ddsc_waitset_attach_detach, valid_entities) = { - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &rdcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &rdcond), CU_DataPoints(dds_attach_t, (dds_attach_t)NULL, (dds_attach_t)&reader, (dds_attach_t)3, (dds_attach_t)3, (dds_attach_t)3, (dds_attach_t)3, (dds_attach_t)3, (dds_attach_t)3), }; CU_Theory((dds_entity_t *ws, dds_entity_t *e, dds_attach_t a), ddsc_waitset_attach_detach, valid_entities, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) @@ -318,8 +318,8 @@ CU_Theory((dds_entity_t ws), ddsc_waitset_detach, invalid_waitsets, .init=ddsc_w } CU_TheoryDataPoints(ddsc_waitset_detach, valid_entities) = { - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &rdcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &waitset, &publisher, &subscriber, &rdcond), }; CU_Theory((dds_entity_t *ws, dds_entity_t *e), ddsc_waitset_detach, valid_entities, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { @@ -338,7 +338,7 @@ CU_Theory((dds_entity_t *ws, dds_entity_t *e), ddsc_waitset_detach, valid_entiti CU_Test(ddsc_waitset_attach_detach, various, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { - const dds_entity_t es[] = { readcond, writer, reader, topic, publisher, subscriber, waitset, participant }; + const dds_entity_t es[] = { rdcond, writer, reader, topic, publisher, subscriber, waitset, participant }; dds_return_t ret; for (size_t i = 0; i < sizeof (es) / sizeof (es[0]); i++) { @@ -354,7 +354,7 @@ CU_Test(ddsc_waitset_attach_detach, various, .init=ddsc_waitset_init, .fini=ddsc CU_Test(ddsc_waitset_attach_detach, combinations, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { - const dds_entity_t entities[] = { readcond, writer, reader, topic, publisher, subscriber, waitset, participant }; + const dds_entity_t entities[] = { rdcond, writer, reader, topic, publisher, subscriber, waitset, participant }; const uint32_t count = (uint32_t) (sizeof (entities) / sizeof (entities[0])); dds_return_t ret; dds_entity_t es[MAX_ENTITIES_CNT]; @@ -447,7 +447,7 @@ CU_Test(ddsc_waitset_delete_attached, reader, .init=ddsc_waitset_init, .fini=dds { dds_entity_t es[MAX_ENTITIES_CNT]; dds_return_t ret; - ret = dds_waitset_attach (waitset, readcond, 0); + ret = dds_waitset_attach (waitset, rdcond, 0); CU_ASSERT_FATAL (ret == 0); ret = dds_waitset_attach (waitset, reader, 1); CU_ASSERT_FATAL (ret == 0); @@ -462,7 +462,7 @@ CU_Test(ddsc_waitset_delete_attached, various, .init=ddsc_waitset_init, .fini=dd { // order matters: deleting the reader will also delete readcond; deleting pub/sub will delete wr/rd // this order should be ok, but the number of alive entities will dwindle - const dds_entity_t es[] = { readcond, writer, reader, topic, publisher, subscriber }; + const dds_entity_t es[] = { rdcond, writer, reader, topic, publisher, subscriber }; dds_return_t ret; for (size_t i = 0; i < sizeof (es) / sizeof (es[0]); i++) { @@ -490,7 +490,7 @@ CU_Theory((dds_entity_t ws), ddsc_waitset_set_trigger, invalid_params, .init=dds } CU_TheoryDataPoints(ddsc_waitset_set_trigger, non_waitsets) = { - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &rdcond), }; CU_Theory((dds_entity_t *ws), ddsc_waitset_set_trigger, non_waitsets, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { @@ -517,7 +517,7 @@ CU_Theory((dds_entity_t ws), ddsc_waitset_wait, invalid_waitsets, .init=ddsc_wai } CU_TheoryDataPoints(ddsc_waitset_wait, non_waitsets) = { - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &rdcond), }; CU_Theory((dds_entity_t *ws), ddsc_waitset_wait, non_waitsets, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { @@ -558,7 +558,7 @@ CU_Theory((dds_entity_t ws), ddsc_waitset_wait_until, invalid_waitsets, .init=dd } CU_TheoryDataPoints(ddsc_waitset_wait_until, non_waitsets) = { - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &rdcond), }; CU_Theory((dds_entity_t *ws), ddsc_waitset_wait_until, non_waitsets, .init=ddsc_waitset_init, .fini=ddsc_waitset_fini) { @@ -653,7 +653,7 @@ CU_Theory((dds_entity_t ws), ddsc_waitset_get_entities, invalid_params, .init=dd } CU_TheoryDataPoints(ddsc_waitset_get_entities, non_waitsets) = { - CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &readcond), + CU_DataPoints(dds_entity_t*, &participant, &topic, &writer, &reader, &publisher, &subscriber, &rdcond), }; CU_Theory((dds_entity_t *ws), ddsc_waitset_get_entities, non_waitsets, .init=ddsc_waitset_attached_init, .fini=ddsc_waitset_attached_fini) { @@ -721,10 +721,10 @@ CU_Test(ddsc_waitset_triggering, on_reader, .init=ddsc_waitset_attached_init, .f CU_Test(ddsc_waitset_triggering, on_readcondition, .init=ddsc_waitset_attached_init, .fini=ddsc_waitset_attached_fini) { dds_return_t ret; - ret = dds_waitset_attach (waitset, readcond, readcond); + ret = dds_waitset_attach (waitset, rdcond, rdcond); CU_ASSERT_FATAL (ret == 0); - check_waitset_trigger (readcond, cw_trig_write); - ret = dds_waitset_detach (waitset, readcond); + check_waitset_trigger (rdcond, cw_trig_write); + ret = dds_waitset_detach (waitset, rdcond); CU_ASSERT_FATAL (ret == 0); } diff --git a/src/core/ddsi/src/ddsi_endpoint.c b/src/core/ddsi/src/ddsi_endpoint.c index cfd607f6c2..8d8a5968b8 100644 --- a/src/core/ddsi/src/ddsi_endpoint.c +++ b/src/core/ddsi/src/ddsi_endpoint.c @@ -213,6 +213,7 @@ void ddsi_rebuild_writer_addrset (struct ddsi_writer *wr) ELOGDISC (wr, " (burst size %"PRIu32" rexmit %"PRIu32")\n", wr->init_burst_size_limit, wr->rexmit_burst_size_limit); } +#ifdef DDS_HAS_SSM static bool nwpart_includes_ssm_enabled_interfaces (const struct ddsi_domaingv *gv, const struct ddsi_config_networkpartition_listelem *np) ddsrt_nonnull ((1)); @@ -241,6 +242,7 @@ static bool nwpart_includes_ssm_enabled_interfaces (const struct ddsi_domaingv * return false; } } +#endif static void writer_get_alive_state_locked (struct ddsi_writer *wr, struct ddsi_alive_state *st) { diff --git a/src/core/ddsi/src/ddsi_nwinterfaces.c b/src/core/ddsi/src/ddsi_nwinterfaces.c index b7bbb62fa7..5e8b8a06dd 100644 --- a/src/core/ddsi/src/ddsi_nwinterfaces.c +++ b/src/core/ddsi/src/ddsi_nwinterfaces.c @@ -573,8 +573,10 @@ int ddsi_gather_network_interfaces (struct ddsi_domaingv *gv) flagpos += snprintf (flagstr + flagpos, sizeof (flagstr) - (size_t) flagpos, "%sspdp", (flagpos > 0) ? "," : ""); if (gv->interfaces[i].allow_multicast & DDSI_AMC_ASM) flagpos += snprintf (flagstr + flagpos, sizeof (flagstr) - (size_t) flagpos, "%sasm", (flagpos > 0) ? "," : ""); +#ifdef DDS_HAS_SSM if (gv->interfaces[i].allow_multicast & DDSI_AMC_SSM) flagpos += snprintf (flagstr + flagpos, sizeof (flagstr) - (size_t) flagpos, "%sssm", (flagpos > 0) ? "," : ""); +#endif (void) flagpos; GVLOG (DDS_LC_CONFIG, "%s%s (index %"PRIu32" priority %"PRId32" mc {%s})", (i == 0) ? "" : ", ", gv->interfaces[i].name, gv->interfaces[i].if_index, gv->interfaces[i].priority, diff --git a/src/core/ddsi/src/ddsi_sertype.c b/src/core/ddsi/src/ddsi_sertype.c index 29ac6d9bb7..12b3c2009f 100644 --- a/src/core/ddsi/src/ddsi_sertype.c +++ b/src/core/ddsi/src/ddsi_sertype.c @@ -222,8 +222,8 @@ uint32_t ddsi_sertype_compute_serdata_basehash (const struct ddsi_serdata_ops *o uint16_t ddsi_sertype_get_native_enc_identifier (uint32_t enc_version, uint32_t enc_format) { -#define CONCAT_(a,b) (a ## b) -#define CONCAT(id,suffix) CONCAT_(id,suffix) +#define ENC_CONCAT_(a,b) (a ## b) +#define ENC_CONCAT(id,suffix) ENC_CONCAT_(id,suffix) #if (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN) #define SUFFIX _LE @@ -235,20 +235,20 @@ uint16_t ddsi_sertype_get_native_enc_identifier (uint32_t enc_version, uint32_t { case DDSI_RTPS_CDR_ENC_VERSION_1: if (enc_format == DDSI_RTPS_CDR_ENC_FORMAT_PL) - return CONCAT(DDSI_RTPS_PL_CDR, SUFFIX); - return CONCAT(DDSI_RTPS_CDR, SUFFIX); + return ENC_CONCAT(DDSI_RTPS_PL_CDR, SUFFIX); + return ENC_CONCAT(DDSI_RTPS_CDR, SUFFIX); case DDSI_RTPS_CDR_ENC_VERSION_2: if (enc_format == DDSI_RTPS_CDR_ENC_FORMAT_PL) - return CONCAT(DDSI_RTPS_PL_CDR2, SUFFIX); + return ENC_CONCAT(DDSI_RTPS_PL_CDR2, SUFFIX); if (enc_format == DDSI_RTPS_CDR_ENC_FORMAT_DELIMITED) - return CONCAT(DDSI_RTPS_D_CDR2, SUFFIX); - return CONCAT(DDSI_RTPS_CDR2, SUFFIX); + return ENC_CONCAT(DDSI_RTPS_D_CDR2, SUFFIX); + return ENC_CONCAT(DDSI_RTPS_CDR2, SUFFIX); default: abort (); /* unsupported */ } #undef SUFFIX -#undef CONCAT -#undef CONCAT_ +#undef ENC_CONCAT +#undef ENC_CONCAT_ } uint16_t ddsi_sertype_extensibility_enc_format (enum dds_cdr_type_extensibility type_extensibility) diff --git a/src/core/ddsi/src/ddsi_udp.c b/src/core/ddsi/src/ddsi_udp.c index 236cf08d2c..7321c211fa 100644 --- a/src/core/ddsi/src/ddsi_udp.c +++ b/src/core/ddsi/src/ddsi_udp.c @@ -718,7 +718,11 @@ static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const ddsi_lo struct ipv6_mreq ipv6mreq; memset (&ipv6mreq, 0, sizeof (ipv6mreq)); ipv6mreq.ipv6mr_multiaddr = mcip.a6.sin6_addr; +#if __ZEPHYR__ + ipv6mreq.ipv6mr_ifindex = interf ? interf->if_index : 0; +#else ipv6mreq.ipv6mr_interface = interf ? interf->if_index : 0; +#endif rc = ddsrt_setsockopt (socket, IPPROTO_IPV6, join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP, &ipv6mreq, sizeof (ipv6mreq)); } else diff --git a/src/core/ddsi/tests/wraddrset.c b/src/core/ddsi/tests/wraddrset.c index afcb5f48ad..f8f1708faa 100644 --- a/src/core/ddsi/tests/wraddrset.c +++ b/src/core/ddsi/tests/wraddrset.c @@ -220,7 +220,11 @@ static void ddsi_wraddrset_some_cases (int casenumber, int cost, bool wr_psmx, c // something else ddsi_add_xlocator_to_addrset (&gv, rd_as, &(ddsi_xlocator_t){ .conn = &fake_conn, .c = psmxloc[i] }); } +#if DDS_HAS_SSM ddsi_new_proxy_reader (&gv, &rdppguid[i][j], &rdguid, rd_as, &plist_rd, ddsrt_time_wallclock (), 1, false); +#else + ddsi_new_proxy_reader (&gv, &rdppguid[i][j], &rdguid, rd_as, &plist_rd, ddsrt_time_wallclock (), 1); +#endif assert (ddsi_entidx_lookup_proxy_reader_guid (gv.entity_index, &rdguid)); ddsi_unref_addrset (rd_as); } diff --git a/src/ddsrt/include/dds/ddsrt/dynlib.h b/src/ddsrt/include/dds/ddsrt/dynlib.h index 6d78cf6420..0bca9d04ad 100644 --- a/src/ddsrt/include/dds/ddsrt/dynlib.h +++ b/src/ddsrt/include/dds/ddsrt/dynlib.h @@ -17,8 +17,6 @@ #include "dds/ddsrt/retcode.h" #include "dds/ddsrt/attributes.h" -#if DDSRT_HAVE_DYNLIB - #if defined (__cplusplus) extern "C" { #endif @@ -64,11 +62,13 @@ ddsrt_dlopen( bool translate, ddsrt_dynlib_t *handle) ddsrt_nonnull_all; +#if DDSRT_HAVE_DYNLIB dds_return_t ddsrt_platform_dlopen( const char *name, bool translate, ddsrt_dynlib_t *handle) ddsrt_nonnull_all; +#endif /** * @brief Close the library. @@ -92,9 +92,11 @@ dds_return_t ddsrt_dlclose( ddsrt_dynlib_t handle); +#if DDSRT_HAVE_DYNLIB dds_return_t ddsrt_platform_dlclose( ddsrt_dynlib_t handle); +#endif /** * @brief Get the memory address of a symbol. @@ -121,11 +123,13 @@ ddsrt_dlsym( const char *symbol, void **address); +#if DDSRT_HAVE_DYNLIB dds_return_t ddsrt_platform_dlsym( ddsrt_dynlib_t handle, const char *symbol, void **address); +#endif /** * @brief Get the most recent library related error. @@ -154,15 +158,15 @@ ddsrt_dlerror( char *buf, size_t buflen); +#if DDSRT_HAVE_DYNLIB dds_return_t ddsrt_platform_dlerror( char *buf, size_t buflen); +#endif #if defined (__cplusplus) } #endif -#endif /* DDSRT_HAVE_DYNLIB */ - #endif /* DDSRT_DYNLIB_H */ diff --git a/src/ddsrt/include/dds/ddsrt/sockets/posix.h b/src/ddsrt/include/dds/ddsrt/sockets/posix.h index fa3cd261a6..a7e344132f 100644 --- a/src/ddsrt/include/dds/ddsrt/sockets/posix.h +++ b/src/ddsrt/include/dds/ddsrt/sockets/posix.h @@ -60,10 +60,7 @@ typedef struct ddsrt_socket_ext { # define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */ # define IN_MULTICAST(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000) -/* socket options */ -# define IP_ADD_MEMBERSHIP 35 -# define IP_DROP_MEMBERSHIP 36 -/* Ignored? */ +/* Ignored socket options */ # define IP_MULTICAST_IF 32 # define IP_MULTICAST_TTL 33 # define IP_MULTICAST_LOOP 34 @@ -86,17 +83,9 @@ struct ip_mreq { # define IN6_IS_ADDR_LINKLOCAL(a) (((a)->s6_addr[0] & 0xff) == 0xfe && ((a)->s6_addr[1] & 0xc0) == 0x80) # define IN6_IS_ADDR_MULTICAST(a) (((a)->s6_addr[0] & 0xff) == 0xff) -struct ipv6_mreq { - struct in6_addr ipv6mr_multiaddr; - unsigned int ipv6mr_interface; -}; - /* socket options */ # define IPV6_JOIN_GROUP 91 # define IPV6_LEAVE_GROUP 92 -/* ignored? */ -# define IPV6_MULTICAST_HOPS 93 -# define IPV6_UNICAST_HOPS 94 # define IPV6_MULTICAST_IF 95 # define IPV6_MULTICAST_LOOP 96 #endif diff --git a/src/ddsrt/src/dynlib.c b/src/ddsrt/src/dynlib.c index a0be151558..1c8bd9a242 100644 --- a/src/ddsrt/src/dynlib.c +++ b/src/ddsrt/src/dynlib.c @@ -106,7 +106,11 @@ dds_return_t ddsrt_dlopen (const char *name, bool translate, ddsrt_dynlib_t *han return DDS_RETCODE_OK; } } +#if DDSRT_HAVE_DYNLIB return ddsrt_platform_dlopen (name, translate, handle); +#else + return DDS_RETCODE_UNSUPPORTED; +#endif } dds_return_t ddsrt_dlclose (ddsrt_dynlib_t handle) @@ -114,7 +118,11 @@ dds_return_t ddsrt_dlclose (ddsrt_dynlib_t handle) for (size_t i = 0; static_dlopen_table[i].name; i++) if (handle == (ddsrt_dynlib_t) static_dlopen_table[i].syms) return DDS_RETCODE_OK; +#if DDSRT_HAVE_DYNLIB return ddsrt_platform_dlclose (handle); +#else + return DDS_RETCODE_UNSUPPORTED +#endif } static dds_return_t fake_dlsym (ddsrt_dynlib_t handle, const char *symbol, void **address) @@ -134,34 +142,58 @@ dds_return_t ddsrt_dlsym (ddsrt_dynlib_t handle, const char *symbol, void **addr for (size_t i = 0; static_dlopen_table[i].name; i++) if (handle == (ddsrt_dynlib_t) static_dlopen_table[i].syms) return fake_dlsym (handle, symbol, address); +#if DDSRT_HAVE_DYNLIB return ddsrt_platform_dlsym (handle, symbol, address); +#else + return DDS_RETCODE_UNSUPPORTED +#endif } dds_return_t ddsrt_dlerror (char *buf, size_t buflen) { +#if DDSRT_HAVE_DYNLIB return ddsrt_platform_dlerror (buf, buflen); +#else + return DDS_RETCODE_UNSUPPORTED +#endif } #else dds_return_t ddsrt_dlopen (const char *name, bool translate, ddsrt_dynlib_t *handle) { +#if DDSRT_HAVE_DYNLIB return ddsrt_platform_dlopen (name, translate, handle); +#else + return DDS_RETCODE_UNSUPPORTED; +#endif } dds_return_t ddsrt_dlclose (ddsrt_dynlib_t handle) { +#if DDSRT_HAVE_DYNLIB return ddsrt_platform_dlclose (handle); +#else + return DDS_RETCODE_UNSUPPORTED; +#endif } dds_return_t ddsrt_dlsym (ddsrt_dynlib_t handle, const char *symbol, void **address) { +#if DDSRT_HAVE_DYNLIB return ddsrt_platform_dlsym (handle, symbol, address); +#else + return DDS_RETCODE_UNSUPPORTED; +#endif } dds_return_t ddsrt_dlerror (char *buf, size_t buflen) { +#if DDSRT_HAVE_DYNLIB return ddsrt_platform_dlerror (buf, buflen); +#else + return DDS_RETCODE_UNSUPPORTED; +#endif } #endif diff --git a/src/ddsrt/src/ifaddrs/zephyr/ifaddrs-v3.7pre.c b/src/ddsrt/src/ifaddrs/zephyr/ifaddrs-v3.7pre.c new file mode 100644 index 0000000000..02245d9f74 --- /dev/null +++ b/src/ddsrt/src/ifaddrs/zephyr/ifaddrs-v3.7pre.c @@ -0,0 +1,220 @@ +// Copyright(c) 2006 to 2023 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#include +#include + +#include + +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/io.h" +#include "dds/ddsrt/ifaddrs.h" +#include "dds/ddsrt/retcode.h" +#include "dds/ddsrt/string.h" + +extern const int *const os_supp_afs; + +struct ifaddrs_data { + ddsrt_ifaddrs_t *first; + ddsrt_ifaddrs_t *prev; + int getv4; + int getv6; + dds_return_t rc; +}; + +static uint32_t +getflags( + struct net_if *iface) +{ + uint32_t flags = 0; + + if (net_if_is_up(iface)) { + flags |= IFF_UP; + } + if (net_if_flag_is_set(iface, NET_IF_POINTOPOINT)) { + flags |= IFF_POINTOPOINT; + } + flags |= IFF_BROADCAST; + flags |= IFF_MULTICAST; + +#if defined(CONFIG_NET_LOOPBACK) + if (net_if_l2(iface) == &NET_L2_GET_NAME(DUMMY)) { + flags |= IFF_LOOPBACK; + } +#endif + + return flags; +} + +static void netif_callback(struct net_if *iface, void *cb_data) +{ + ddsrt_ifaddrs_t *ifa; + struct ifaddrs_data *data = (struct ifaddrs_data*)cb_data; + + + if ((data->rc != DDS_RETCODE_OK) +#if defined(CONFIG_NET_L2_ETHERNET) && defined(CONFIG_NET_L2_DUMMY) + || ((net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) && (net_if_l2(iface) != &NET_L2_GET_NAME(DUMMY))) +#elif defined(CONFIG_NET_L2_ETHERNET) + || (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) +#elif defined(CONFIG_NET_L2_DUMMY) + || (net_if_l2(iface) != &NET_L2_GET_NAME(DUMMY)) +#endif + ) { + /* Skip on previous error or unsupported interface type */ + return; + } + + if (data->getv4 && iface->config.ip.ipv4) { + struct net_if_ipv4 *cfg = iface->config.ip.ipv4; + struct net_if_addr_ipv4 *addr = NULL; + int i; + for (i = 0; i < NET_IF_MAX_IPV4_ADDR && !addr; i++) { + if (cfg->unicast[i].ipv4.is_used && + cfg->unicast[i].ipv4.addr_state == NET_ADDR_PREFERRED && + cfg->unicast[i].ipv4.address.family == AF_INET) { + addr = &cfg->unicast[i]; + } + } + + ifa = ddsrt_calloc_s(1, sizeof(ddsrt_ifaddrs_t)); + if (!ifa) { + data->rc = DDS_RETCODE_OUT_OF_RESOURCES; + } else { + ifa->name = ddsrt_strdup(iface->if_dev->dev->name); + if (addr) { + ifa->addr = ddsrt_calloc_s(1, sizeof(struct sockaddr_in)); + ifa->netmask = ddsrt_calloc_s(1, sizeof(struct sockaddr_in)); + ifa->broadaddr = ddsrt_calloc_s(1, sizeof(struct sockaddr_in)); + } + if (!ifa->name || (addr && (!ifa->addr || !ifa->netmask || !ifa->broadaddr))) { + data->rc = DDS_RETCODE_OUT_OF_RESOURCES; + } else { + ifa->type = DDSRT_IFTYPE_UNKNOWN; + ifa->flags = getflags(iface); + ifa->index = net_if_get_by_iface(iface); + + if (addr) { + net_ipaddr_copy(&(net_sin(ifa->addr)->sin_addr), &(addr->ipv4.address.in_addr)); + ifa->addr->sa_family = AF_INET; + + net_ipaddr_copy(&(net_sin(ifa->netmask)->sin_addr), &(addr->netmask)); + ifa->netmask->sa_family = AF_INET; + + ((struct sockaddr_in*)ifa->broadaddr)->sin_addr.s_addr = (net_sin(ifa->addr)->sin_addr.s_addr & net_sin(ifa->netmask)->sin_addr.s_addr) | ~net_sin(ifa->netmask)->sin_addr.s_addr; + ifa->broadaddr->sa_family = AF_INET; + } + } + } + + if (data->rc == DDS_RETCODE_OK) { + if (data->prev) { + data->prev->next = ifa; + } else { + data->first = ifa; + } + data->prev = ifa; + } else { + ddsrt_freeifaddrs(ifa); + } + } + +#if DDSRT_HAVE_IPV6 + if (data->getv6 && iface->config.ip.ipv6) { + struct net_if_ipv6 *cfg = iface->config.ip.ipv6; + struct net_if_addr *addr = NULL; + int i; + for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { + if (cfg->unicast[i].is_used && + cfg->unicast[i].addr_state == NET_ADDR_PREFERRED && + cfg->unicast[i].address.family == AF_INET6 && + !net_ipv6_is_ll_addr(&cfg->unicast[i].address.in6_addr)) { + addr = &cfg->unicast[i]; + } + } + + ifa = ddsrt_calloc_s(1, sizeof(ddsrt_ifaddrs_t)); + if (!ifa) { + data->rc = DDS_RETCODE_OUT_OF_RESOURCES; + } else { + ifa->name = ddsrt_strdup(iface->if_dev->dev->name); + if (addr) { + ifa->addr = ddsrt_calloc_s(1, sizeof(struct sockaddr_in6)); + } + if (!ifa->name || (addr && (!ifa->addr))) { + data->rc = DDS_RETCODE_OUT_OF_RESOURCES; + } else { + ifa->type = DDSRT_IFTYPE_UNKNOWN; + ifa->flags = getflags(iface); + ifa->index = net_if_get_by_iface(iface); + + if (addr) { + net_ipaddr_copy(&(net_sin6(ifa->addr)->sin6_addr), &(addr->address.in6_addr)); + ifa->addr->sa_family = AF_INET6; + } + } + } + + if (data->rc == DDS_RETCODE_OK) { + if (data->prev) { + data->prev->next = ifa; + } else { + data->first = ifa; + } + data->prev = ifa; + } else { + ddsrt_freeifaddrs(ifa); + } + } +#endif + + return; +} + +dds_return_t +ddsrt_getifaddrs( + ddsrt_ifaddrs_t **ifap, + const int *afs) +{ + struct ifaddrs_data data; + + assert(ifap != NULL); + + data.first = NULL; + data.prev = NULL; + data.rc = DDS_RETCODE_OK; + data.getv4 = 0; + data.getv6 = 0; + + if (afs == NULL) { + afs = os_supp_afs; + } + + for (int i = 0; afs[i] != DDSRT_AF_TERM; i++) { + if (afs[i] == AF_INET) { + data.getv4 = 1; + } +#if DDSRT_HAVE_IPV6 + else if (afs[i] == AF_INET6) { + data.getv6 = 1; + } +#endif + } + + (void)net_if_foreach(netif_callback, &data); + + if (data.rc == DDS_RETCODE_OK) { + *ifap = data.first; + } else { + ddsrt_freeifaddrs(data.first); + } + + return data.rc; +} diff --git a/src/ddsrt/src/sockets/posix/gethostname.c b/src/ddsrt/src/sockets/posix/gethostname.c index 2a07acac08..60b0cf3dc9 100644 --- a/src/ddsrt/src/sockets/posix/gethostname.c +++ b/src/ddsrt/src/sockets/posix/gethostname.c @@ -32,6 +32,10 @@ #endif #if DDSRT_HAVE_GETHOSTNAME +#if __ZEPHYR__ && !CONFIG_NET_HOSTNAME_ENABLE +#undef HOST_NAME_MAX +#define HOST_NAME_MAX (strlen(net_hostname_get())) +#endif #ifndef HOST_NAME_MAX #define HOST_NAME_MAX 256 #endif diff --git a/src/ddsrt/src/sockets/posix/socket.c b/src/ddsrt/src/sockets/posix/socket.c index 3c291ebcc6..af467cdc12 100644 --- a/src/ddsrt/src/sockets/posix/socket.c +++ b/src/ddsrt/src/sockets/posix/socket.c @@ -331,39 +331,11 @@ ddsrt_setsockopt( /* ignored */ return DDS_RETCODE_OK; case IPV6_JOIN_GROUP: + optname = IPV6_ADD_MEMBERSHIP; + break; case IPV6_LEAVE_GROUP: - { - struct net_if *iface = NULL; - struct ipv6_mreq *mreq = (struct ipv6_mreq*)optval; - struct net_if_mcast_addr *maddr; - assert(level == IPPROTO_IPV6); - iface = net_if_get_by_index(mreq->ipv6mr_interface); - if (iface) { - maddr = net_if_ipv6_maddr_lookup(&(mreq->ipv6mr_multiaddr), &iface); - if (optname == IPV6_JOIN_GROUP) { - if (maddr) { - /* already joined */ - return DDS_RETCODE_ERROR; - } else { - maddr = net_if_ipv6_maddr_add(iface, &(mreq->ipv6mr_multiaddr)); - if (maddr) { - net_if_ipv6_maddr_join(iface, maddr); - net_if_mcast_monitor(iface, &(maddr->address), true); - return DDS_RETCODE_OK; - } - } - } else if (optname == IPV6_LEAVE_GROUP) { - if (maddr) { - if (net_if_ipv6_maddr_rm(iface, &(mreq->ipv6mr_multiaddr))) { - net_if_ipv6_maddr_leave(iface, maddr); - net_if_mcast_monitor(iface, &(maddr->address), false); - return DDS_RETCODE_OK; - } - } - } - } - return DDS_RETCODE_ERROR; - } + optname = IPV6_DROP_MEMBERSHIP; + break; #endif /* DDSRT_HAVE_IPV6 */ case IP_PKTINFO: case IP_MULTICAST_IF: @@ -371,49 +343,6 @@ ddsrt_setsockopt( case IP_MULTICAST_LOOP: /* ignored */ return DDS_RETCODE_OK; - case IP_ADD_MEMBERSHIP: - case IP_DROP_MEMBERSHIP: - { - struct net_if *iface = NULL; - struct ip_mreq *mreq = (struct ip_mreq*)optval; - struct net_if_mcast_addr *maddr; - assert(level == IPPROTO_IP); - if (net_if_ipv4_addr_lookup(&(mreq->imr_interface), &iface)) { -#if defined(CONFIG_NET_IPV4_IGMP) - int rc = -1; - if (optname == IP_ADD_MEMBERSHIP) { - rc = net_ipv4_igmp_join(iface, &(mreq->imr_multiaddr)); - } else { - rc = net_ipv4_igmp_leave(iface, &(mreq->imr_multiaddr)); - } - return (rc < 0) ? DDS_RETCODE_ERROR : DDS_RETCODE_OK; -#else - maddr = net_if_ipv4_maddr_lookup(&(mreq->imr_multiaddr), &iface); - if (optname == IP_ADD_MEMBERSHIP) { - if (maddr && maddr->is_used) { - /* already joined */ - return DDS_RETCODE_ERROR; - } else { - maddr = net_if_ipv4_maddr_add(iface, &(mreq->imr_multiaddr)); - if (maddr) { - net_if_ipv4_maddr_join(iface, maddr); - net_if_mcast_monitor(iface, &(maddr->address), true); - return DDS_RETCODE_OK; - } - } - } else if (optname == IP_DROP_MEMBERSHIP) { - if (maddr) { - if (net_if_ipv4_maddr_rm(iface, &(mreq->imr_multiaddr))) { - net_if_ipv4_maddr_leave(iface, maddr); - net_if_mcast_monitor(iface, &(maddr->address), false); - return DDS_RETCODE_OK; - } - } - } -#endif /* CONFIG_NET_IPV4_IGMP */ - } - return DDS_RETCODE_ERROR; - } } #endif /* __ZEPHYR__ */ diff --git a/src/ddsrt/tests/log.c b/src/ddsrt/tests/log.c index 946c6dd3a0..59d8b465c4 100644 --- a/src/ddsrt/tests/log.c +++ b/src/ddsrt/tests/log.c @@ -37,7 +37,8 @@ because it runs on the source rather than on the output of the C preprocessor (a reasonable decision in itself). Therefore, just skip the body of each test. */ -#if __APPLE__ && !(defined MAC_OS_X_VERSION_10_13 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_13) +#if (defined __APPLE__ && !(defined MAC_OS_X_VERSION_10_13 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_13)) || defined __QNXNTO__ + #define HAVE_FMEMOPEN 0 #else #define HAVE_FMEMOPEN 1 diff --git a/src/ucunit/CMakeLists.txt b/src/ucunit/CMakeLists.txt index 49566101ac..bfe3b18edd 100644 --- a/src/ucunit/CMakeLists.txt +++ b/src/ucunit/CMakeLists.txt @@ -38,7 +38,7 @@ add_executable(test_ucunit) target_sources(test_ucunit PRIVATE tests/test_ucunit.c) target_link_libraries(test_ucunit CycloneDDS::ucunit) -add_test(NAME ucunit COMMAND $/test_ucunit) +add_test(NAME ucunit COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $/test_ucunit) if (NOT BUILD_SHARED_LIBS) install( From 460851ace3417b63eee5b093471be3a3461220f6 Mon Sep 17 00:00:00 2001 From: Geoff Martin Date: Tue, 30 Apr 2024 16:35:34 +0100 Subject: [PATCH 083/207] Exported the ddsrt_getifaddrs and ddsrt_freeifaddrs symbols which are required by the Iceoryx PSMX plugin. --- src/core/xtests/symbol_export/symbol_export.c | 5 +++++ src/ddsrt/include/dds/ddsrt/ifaddrs.h | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/xtests/symbol_export/symbol_export.c b/src/core/xtests/symbol_export/symbol_export.c index a6ef6a4970..8eaa18730a 100644 --- a/src/core/xtests/symbol_export/symbol_export.c +++ b/src/core/xtests/symbol_export/symbol_export.c @@ -36,6 +36,7 @@ #include "dds/ddsrt/strtol.h" #include "dds/ddsrt/xmlparser.h" #include "dds/ddsrt/io.h" +#include "dds/ddsrt/ifaddrs.h" #if DDSRT_HAVE_FILESYSTEM #include "dds/ddsrt/filesystem.h" #endif @@ -1069,6 +1070,10 @@ int main (int argc, char **argv) test_ddsrt_vasprintf (ptr, " "); ddsrt_asprintf (ptr, " "); + // ddsrt/ifaddrs.h + ddsrt_getifaddrs (ptr, ptr); + ddsrt_freeifaddrs (ptr); + // dds__write.h dds_write_impl (ptr, ptr, 0, (dds_write_action) 0); dds_writecdr_impl (ptr, ptr, ptr, false); diff --git a/src/ddsrt/include/dds/ddsrt/ifaddrs.h b/src/ddsrt/include/dds/ddsrt/ifaddrs.h index e131f4c3ab..50b73468ee 100644 --- a/src/ddsrt/include/dds/ddsrt/ifaddrs.h +++ b/src/ddsrt/include/dds/ddsrt/ifaddrs.h @@ -58,7 +58,7 @@ typedef struct ddsrt_ifaddrs ddsrt_ifaddrs_t; * @param[in] afs an array of address families * @return a DDS_RETCODE (OK, ERROR, OUT_OF_RESOURCES, NOT_ALLOWED) */ -dds_return_t +DDS_EXPORT dds_return_t ddsrt_getifaddrs( ddsrt_ifaddrs_t **ifap, const int *afs); @@ -68,7 +68,7 @@ ddsrt_getifaddrs( * * @param[in] ifa the interface addresses to free */ -void +DDS_EXPORT void ddsrt_freeifaddrs( ddsrt_ifaddrs_t *ifa); From 022ba7afcd02143fe35a35612bd564a9071aeab3 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 25 Apr 2024 10:47:53 +0000 Subject: [PATCH 084/207] Fix handshake fuzzer build issue and memory leaks Signed-off-by: Erik Boasson --- fuzz/fuzz_handshake/fuzz_handshake_harness.c | 101 +++++++++++------- fuzz/local.sh | 28 ++++- fuzz/oss-fuzz-build.sh | 4 +- src/core/ddsi/src/ddsi__gc.h | 3 + src/core/ddsi/src/ddsi__radmin.h | 4 + src/core/ddsi/src/ddsi__xevent.h | 12 ++- src/core/ddsi/src/ddsi_gc.c | 37 ++++++- src/core/ddsi/src/ddsi_handshake.c | 2 - src/core/ddsi/src/ddsi_radmin.c | 47 ++++++++ src/core/ddsi/src/ddsi_vnet.c | 11 +- src/core/ddsi/src/ddsi_xevent.c | 13 +++ .../authentication/CMakeLists.txt | 6 ++ 12 files changed, 216 insertions(+), 52 deletions(-) diff --git a/fuzz/fuzz_handshake/fuzz_handshake_harness.c b/fuzz/fuzz_handshake/fuzz_handshake_harness.c index 1cdf1a659c..560c2ab30a 100644 --- a/fuzz/fuzz_handshake/fuzz_handshake_harness.c +++ b/fuzz/fuzz_handshake/fuzz_handshake_harness.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include @@ -26,7 +28,6 @@ #include #include #include -#include #include #include @@ -39,16 +40,16 @@ const char *sec_config = " finest" " " " " - " " + " " " data:," TEST_IDENTITY1_CERTIFICATE "" " data:," TEST_IDENTITY1_PRIVATE_KEY "" " data:," TEST_IDENTITY_CA1_CERTIFICATE "" " " " " - " " + " " " " " " - " " + " " " " " " " " @@ -66,6 +67,17 @@ EVP_PKEY *g_private_key; ddsrt_atomic_uint32_t g_fsm_done; ddsrt_atomic_uint32_t g_fuzz_events; +static ddsrt_dynlib_t auth_plugin_handle; + +typedef DDS_Security_ValidationResult_t (*dhpkey2oct_t)(EVP_PKEY *, int, unsigned char **, uint32_t *, DDS_Security_SecurityException *); +static dhpkey2oct_t dh_public_key_to_oct_ptr = NULL; + +typedef DDS_Security_ValidationResult_t (*gendhkeys_t)(EVP_PKEY **, int, DDS_Security_SecurityException *); +static gendhkeys_t generate_dh_keys_ptr = NULL; + +typedef DDS_Security_ValidationResult_t (*cvas_t)(bool, EVP_PKEY *, const unsigned char *, const size_t, unsigned char **, size_t *, DDS_Security_SecurityException *); +static cvas_t create_validate_asymmetrical_signature_ptr = NULL; + struct { struct ddsi_participant *pp; struct ddsi_proxy_participant *proxy_pp; @@ -90,7 +102,7 @@ bool fuzz_handshake_init() thrst = ddsi_lookup_thread_state (); assert (thrst->state == DDSI_THREAD_STATE_LAZILY_CREATED); thrst->state = DDSI_THREAD_STATE_ALIVE; - thrst->vtime.v = DDSI_VTIME_NEST_MASK; + thrst->vtime.v = 0; ddsrt_atomic_stvoidp (&thrst->gv, &gv); memset(&gv, 0, sizeof(gv)); ddsi_config_init_default(&gv.config); @@ -102,11 +114,25 @@ bool fuzz_handshake_init() //FILE *fp = fopen("/dev/stdout", "w"); //dds_log_cfg_init(&gv.logconfig, 1, DDS_LC_TRACE | DDS_LC_ERROR | DDS_LC_WARNING, NULL, fp); - + // Disable logging dds_log_cfg_init(&gv.logconfig, 1, 0, NULL, NULL); + // We use a statically linked build, all functions we need to lookup need to be + // exported from the plugin + // + // See src/security/builtin_plugins/authentication/CMakeLists.txt + if (ddsrt_dlopen("dds_security_auth", true, &auth_plugin_handle) != DDS_RETCODE_OK) + abort(); + if (ddsrt_dlsym(auth_plugin_handle, "generate_dh_keys", (void **)&generate_dh_keys_ptr) != DDS_RETCODE_OK) + abort(); + if (ddsrt_dlsym(auth_plugin_handle, "dh_public_key_to_oct", (void **)&dh_public_key_to_oct_ptr) != DDS_RETCODE_OK) + abort(); + if (ddsrt_dlsym(auth_plugin_handle, "create_validate_asymmetrical_signature", (void **)&create_validate_asymmetrical_signature_ptr) != DDS_RETCODE_OK) + abort(); + // Create participant + ddsi_thread_state_awake(ddsi_lookup_thread_state(), &gv); { ddsi_plist_t pplist; ddsi_plist_init_empty(&pplist); @@ -121,6 +147,7 @@ bool fuzz_handshake_init() harness.pp = ddsi_entidx_lookup_participant_guid(gv.entity_index, &g_ppguid); ddsi_plist_fini(&pplist); } + ddsi_thread_state_asleep(ddsi_lookup_thread_state()); return true; } @@ -206,6 +233,7 @@ void fuzz_handshake_reset(bool initiate_remote) { ddsi_add_locator_to_addrset(&gv,as, &loc); assert(!ddsi_addrset_empty_uc(as)); + ddsi_thread_state_awake(ddsi_lookup_thread_state(), &gv); if (!ddsi_new_proxy_participant(&gv, &g_proxy_ppguid, DDSI_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_ANNOUNCER| @@ -223,8 +251,9 @@ void fuzz_handshake_reset(bool initiate_remote) { } harness.proxy_pp = ddsi_entidx_lookup_proxy_participant_guid(gv.entity_index, &g_proxy_ppguid); + ddsi_thread_state_asleep(ddsi_lookup_thread_state()); ddsi_plist_fini(&pplist); - + harness.hs = ddsi_handshake_find(harness.pp, harness.proxy_pp); if (harness.hs == NULL) abort(); @@ -232,31 +261,20 @@ void fuzz_handshake_reset(bool initiate_remote) { // and the handshake fsm thread. dds_security_fsm_set_debug(harness.hs->fsm, fsm_debug_func); harness.hs->end_cb = hs_end_cb; + ddsi_handshake_release(harness.hs); } void fuzz_handshake_handle_timeout(void) { dds_security_fsm_dispatch(harness.hs->fsm, DDS_SECURITY_FSM_EVENT_TIMEOUT, false); } -typedef DDS_Security_ValidationResult_t (*dhpkey2oct_t)(EVP_PKEY *, int, unsigned char **, uint32_t *, DDS_Security_SecurityException *); -dhpkey2oct_t dh_public_key_to_oct = NULL; - -typedef DDS_Security_ValidationResult_t (*gendhkeys_t)(EVP_PKEY **, int, DDS_Security_SecurityException *); -gendhkeys_t generate_dh_keys = NULL; - static DDS_Security_ValidationResult_t create_dh_key(int algo, unsigned char **data, uint32_t *len) { EVP_PKEY *key; DDS_Security_SecurityException ex = {0}; - - if (generate_dh_keys == NULL) - generate_dh_keys = dlsym(NULL, "generate_dh_keys"); - - DDS_Security_ValidationResult_t result = generate_dh_keys(&key, algo, &ex); + DDS_Security_ValidationResult_t result = generate_dh_keys_ptr(&key, algo, &ex); if (result != DDS_SECURITY_VALIDATION_OK) goto out; - if (dh_public_key_to_oct == NULL) - dh_public_key_to_oct = dlsym(NULL, "dh_public_key_to_oct"); - result = dh_public_key_to_oct(key, algo, data, len, &ex); + result = dh_public_key_to_oct_ptr(key, algo, data, len, &ex); out: EVP_PKEY_free(key); DDS_Security_Exception_reset(&ex); @@ -272,7 +290,7 @@ void fuzz_handshake_handle_request(ddsi_dataholder_t *token) { for (uint32_t i = 0; i < token->binary_properties.n; i++) { dds_binaryproperty_t *binprop = &token->binary_properties.props[i]; - // To avoid fuzzing openssl, always use a valid certificate + // To avoid fuzzing openssl, always use a valid certificate if (strcmp(binprop->name, "c.id") == 0) { free(binprop->value.value); binprop->value.length = strlen(TEST_IDENTITY3_CERTIFICATE); @@ -280,8 +298,6 @@ void fuzz_handshake_handle_request(ddsi_dataholder_t *token) { } // Provide a valid dh public key if (strcmp(binprop->name, "dh1") == 0) { - if (dh_public_key_to_oct == NULL) - dh_public_key_to_oct = dlsym(NULL, "dh_public_key_to_oct"); unsigned char *data; uint32_t len; if (create_dh_key(1, &data, &len) == DDS_SECURITY_VALIDATION_OK) { @@ -294,9 +310,6 @@ void fuzz_handshake_handle_request(ddsi_dataholder_t *token) { ddsi_handshake_handle_message(harness.hs, harness.pp, harness.proxy_pp, &msg); } -typedef DDS_Security_ValidationResult_t (*cvas_t)(bool, EVP_PKEY *, const unsigned char *, const size_t, unsigned char **, size_t *, DDS_Security_SecurityException *); -cvas_t create_validate_asymmetrical_signature = NULL; - static void create_signature(const DDS_Security_BinaryProperty_t **bprops, uint32_t n_bprops, unsigned char **signature, size_t *signatureLen) { unsigned char *buffer; @@ -305,9 +318,7 @@ static void create_signature(const DDS_Security_BinaryProperty_t **bprops, uint3 DDS_Security_Serialize_BinaryPropertyArray(serializer, bprops, n_bprops); DDS_Security_Serializer_buffer(serializer, &buffer, &size); DDS_Security_SecurityException ex; - if (create_validate_asymmetrical_signature == NULL) - create_validate_asymmetrical_signature = dlsym(NULL, "create_validate_asymmetrical_signature"); - (void) create_validate_asymmetrical_signature(true, g_private_key, buffer, size, signature, signatureLen, &ex); + (void) create_validate_asymmetrical_signature_ptr(true, g_private_key, buffer, size, signature, signatureLen, &ex); free(buffer); DDS_Security_Serializer_free(serializer); } @@ -344,7 +355,6 @@ static void create_hash(const DDS_Security_DataHolder *dh, DDS_Security_BinaryPr bprop->value._maximum = SHA256_DIGEST_LENGTH; bprop->value._buffer = hash; DDS_Security_BinaryPropertySeq_deinit(&seq); - free(tokens); } void fuzz_handshake_handle_reply(ddsi_dataholder_t *token) { @@ -371,7 +381,7 @@ void fuzz_handshake_handle_reply(ddsi_dataholder_t *token) { // First fix up the values necessary for the hash for (uint32_t i = 0; i < token->binary_properties.n; i++) { dds_binaryproperty_t *binprop = &token->binary_properties.props[i]; - // To avoid fuzzing openssl, always use a valid certificate + // To avoid fuzzing openssl, always use a valid certificate if (strcmp(binprop->name, "c.id") == 0) { free(binprop->value.value); binprop->value.length = strlen(TEST_IDENTITY3_CERTIFICATE); @@ -385,9 +395,6 @@ void fuzz_handshake_handle_reply(ddsi_dataholder_t *token) { } // Provide a valid dh public key if ((strcmp(binprop->name, "dh2") == 0) && kagree_algo) { - if (dh_public_key_to_oct == NULL) - dh_public_key_to_oct = dlsym(NULL, "dh_public_key_to_oct"); - int algo = 1; if (strncmp((const char *)kagree_algo->value._buffer, "ECDH+prime256v1-CEUM", kagree_algo->value._length) == 0) algo = 2; unsigned char *data; @@ -414,7 +421,7 @@ void fuzz_handshake_handle_reply(ddsi_dataholder_t *token) { if (strcmp(binprop->name, "signature") == 0 && hash_c1 && c1 && c2 && dh1 && c2 && dh2 && hash_c2.value._buffer) { unsigned char *signature; size_t signatureLen; - const DDS_Security_BinaryProperty_t *bprops[] = { &hash_c2, c2, dh2, c1, dh1, hash_c1}; + const DDS_Security_BinaryProperty_t *bprops[] = { &hash_c2, c2, dh2, c1, dh1, hash_c1}; create_signature(bprops, 6, &signature, &signatureLen); free(binprop->value.value); binprop->value.length = (uint32_t) signatureLen; @@ -469,7 +476,7 @@ void fuzz_handshake_handle_final(ddsi_dataholder_t *token) { if (strcmp(binprop->name, "signature") == 0 && hash_c1 && c1 && c2 && dh1 && c2 && dh2 && hash_c2) { unsigned char *signature; size_t signatureLen; - const DDS_Security_BinaryProperty_t *bprops[] = { hash_c1, c1, dh1, c2, dh2, hash_c2 }; + const DDS_Security_BinaryProperty_t *bprops[] = { hash_c1, c1, dh1, c2, dh2, hash_c2 }; create_signature(bprops, 6, &signature, &signatureLen); free(binprop->value.value); binprop->value.length = (uint32_t) signatureLen; @@ -481,7 +488,9 @@ void fuzz_handshake_handle_final(ddsi_dataholder_t *token) { } void fuzz_handshake_handle_crypto_tokens(void) { + ddsi_thread_state_awake(ddsi_lookup_thread_state(), &gv); ddsi_handshake_crypto_tokens_received(harness.hs); + ddsi_thread_state_asleep(ddsi_lookup_thread_state()); } void fuzz_handshake_wait_for_event(uint32_t event) { @@ -493,7 +502,25 @@ void fuzz_handshake_wait_for_completion(void) { dds_security_fsm_dispatch(harness.hs->fsm, DDS_SECURITY_FSM_EVENT_DELETE, false); while(ddsrt_atomic_ld32(&g_fsm_done) == 0) {} ddsrt_wctime_t timestamp = { .v = dds_time() }; + ddsi_thread_state_awake(ddsi_lookup_thread_state(), &gv); ddsi_delete_proxy_participant_by_guid(&gv, &g_proxy_ppguid, timestamp, 1); + ddsi_thread_state_asleep(ddsi_lookup_thread_state()); harness.proxy_pp = NULL; harness.hs = NULL; + + // To actually delete all we created we need to step the what is normally + // done by 4 different threads in the background (multi-stage cleanup via + // the GC involves bubbles sent through the delivery queues; and then one + // has to "send" the messages queued by the handshake code). + bool x; + do { + x = false; + if (ddsi_gcreq_queue_step (gv.gcreq_queue)) + x = true; + if (ddsi_dqueue_step_deaf (gv.builtins_dqueue)) + x = true; + if (ddsi_dqueue_step_deaf (gv.user_dqueue)) + x = true; + ddsi_xeventq_step (gv.xevents); + } while (x); } diff --git a/fuzz/local.sh b/fuzz/local.sh index fcde516a59..177e515f75 100644 --- a/fuzz/local.sh +++ b/fuzz/local.sh @@ -4,18 +4,36 @@ # # sudo apt install clang libfuzzer-14-dev (replace 14 with clang version) -set -ex - +err= if [ ! -f ../src/core/ddsi/src/ddsi_receive.c -o ! -d ../fuzz ] ; then echo "This expects to be run in a build directory that is a subdirectory of the Cyclone repo" 2>&1 - exit 1 + err=1 fi if [ -z "$CYCLONEDDS_HOME" ] ; then echo "Need CYCLONEDDS_HOME to be set" 2>&1 + err=1 fi if [ -z "$CYCLONEDDS_PYTHON" -o ! -d "$CYCLONEDDS_PYTHON/tests/support_modules/fuzz_tools" ] ; then echo "need CYCLONEDDS_PYTHON to point to the cyclone python binding sources" 2>&1 - exit 1 + err=1 +fi +[ -n "$err" ] && exit 1 + +set -ex + +# hopefully Cyclone will never gain a "libprotobuf-mutator" or "LPM" subdirectory so that +# we can keep populate it to match oss-fuzz here and not have to deal with +# absl/utf8_range/protobuf horrors any more than this +if [ ! -d ../LPM ] ; then + [ ! -d ../libprotobuf-mutator ] && \ + git clone --depth 1 https://github.com/google/libprotobuf-mutator.git + mkdir ../LPM + (cd ../LPM && \ + cmake ../libprotobuf-mutator -GNinja \ + -DLIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=ON \ + -DLIB_PROTO_MUTATOR_TESTING=OFF \ + -DCMAKE_BUILD_TYPE=Release && \ + ninja) fi export PATH="$CYCLONEDDS_HOME/bin:$PATH" @@ -37,7 +55,7 @@ cmake -G Ninja \ -DBUILD_SHARED_LIBS=OFF \ -DBUILD_EXAMPLES=NO \ -DENABLE_SECURITY=ON \ - -DENABLE_SSL=NO \ + -DENABLE_SSL=ON \ -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ -DBUILD_IDLC=NO \ -DBUILD_DDSPERF=NO \ diff --git a/fuzz/oss-fuzz-build.sh b/fuzz/oss-fuzz-build.sh index b6e23a08c0..9ce72fd62c 100644 --- a/fuzz/oss-fuzz-build.sh +++ b/fuzz/oss-fuzz-build.sh @@ -15,7 +15,7 @@ source fuzz/fuzz_sample_deser/prepare.sh source fuzz/fuzz_handshake/prepare.sh ( -mkdir build +mkdir build || echo "build directory already exists" cd build cmake \ -DBUILD_IDLC=ON \ @@ -23,7 +23,7 @@ cmake \ -DBUILD_SHARED_LIBS=OFF \ -DBUILD_EXAMPLES=NO \ -DENABLE_SECURITY=ON \ - -DENABLE_SSL=NO \ + -DENABLE_SSL=ON \ -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ -DCMAKE_INSTALL_PREFIX=/usr/local .. cmake --build . diff --git a/src/core/ddsi/src/ddsi__gc.h b/src/core/ddsi/src/ddsi__gc.h index e4c1a59b32..0155fe297a 100644 --- a/src/core/ddsi/src/ddsi__gc.h +++ b/src/core/ddsi/src/ddsi__gc.h @@ -51,6 +51,9 @@ bool ddsi_gcreq_queue_start (struct ddsi_gcreq_queue *q); /** @component garbage_collector */ int ddsi_gcreq_requeue (struct ddsi_gcreq *gcreq, ddsi_gcreq_cb_t cb); +/** @component garbage_collector */ +bool ddsi_gcreq_queue_step (struct ddsi_gcreq_queue *q); + #if defined (__cplusplus) } #endif diff --git a/src/core/ddsi/src/ddsi__radmin.h b/src/core/ddsi/src/ddsi__radmin.h index ba12c3317b..53434d7578 100644 --- a/src/core/ddsi/src/ddsi__radmin.h +++ b/src/core/ddsi/src/ddsi__radmin.h @@ -238,6 +238,10 @@ int ddsi_dqueue_is_full (struct ddsi_dqueue *q); /** @component receive_buffers */ void ddsi_dqueue_wait_until_empty_if_full (struct ddsi_dqueue *q); +/** @brief processes everything currently enqueued, dropping all data + @component receive_buffers */ +bool ddsi_dqueue_step_deaf (struct ddsi_dqueue *q); + /** @component receive_buffers */ void ddsi_defrag_stats (struct ddsi_defrag *defrag, uint64_t *discarded_bytes); diff --git a/src/core/ddsi/src/ddsi__xevent.h b/src/core/ddsi/src/ddsi__xevent.h index f8f675377c..8aa85c7a87 100644 --- a/src/core/ddsi/src/ddsi__xevent.h +++ b/src/core/ddsi/src/ddsi__xevent.h @@ -38,12 +38,18 @@ struct ddsi_xeventq *ddsi_xeventq_new (struct ddsi_domaingv *gv, size_t max_queu /** * @component timed_events * - * ddsi_xeventq_free calls callback handlers with t = NEVER, at which point - * they are required to free whatever memory is claimed for the argument - * and call ddsi_delete_xevent. + * ddsi_xeventq_step invokes all currently pending callbacks and sends any queued + * messages. * * @param evq the event queue */ +void ddsi_xeventq_step (struct ddsi_xeventq *evq); + +/** + * @component timed_events + * @remark: calls ddsi_xeventq_drain + * @param evq the event queue + */ void ddsi_xeventq_free (struct ddsi_xeventq *evq); /** @component timed_events */ diff --git a/src/core/ddsi/src/ddsi_gc.c b/src/core/ddsi/src/ddsi_gc.c index 68d925c306..b8822f2ebf 100644 --- a/src/core/ddsi/src/ddsi_gc.c +++ b/src/core/ddsi/src/ddsi_gc.c @@ -99,6 +99,40 @@ static int threads_vtime_check (const struct ddsi_domaingv *gv, uint32_t *nivs, return *nivs == 0; } +bool ddsi_gcreq_queue_step (struct ddsi_gcreq_queue *q) +{ + struct ddsi_thread_state * const thrst = ddsi_lookup_thread_state (); + struct ddsi_gcreq *gcreq = NULL; + ddsrt_mutex_lock (&q->lock); + while ((gcreq = q->first) != NULL) + { + q->first = gcreq->next; + ddsrt_mutex_unlock (&q->lock); + if (!threads_vtime_check (q->gv, &gcreq->nvtimes, gcreq->vtimes)) + { + /* Give up immediately instead of waiting: this exists to make less-threaded + (test/fuzzing) code possible. (I don't think this case can occur in a single + threaded process, but it might if a some threads exist.) */ + break; + } + else + { + ddsi_thread_state_awake (thrst, q->gv); + gcreq->cb (gcreq); + ddsi_thread_state_asleep (thrst); + } + ddsrt_mutex_lock (&q->lock); + } + if (gcreq) + { + gcreq->next = q->first; + q->first = gcreq; + } + const bool ret = q->first != NULL; + ddsrt_mutex_unlock (&q->lock); + return ret; +} + static uint32_t gcreq_queue_thread (struct ddsi_gcreq_queue *q) { struct ddsi_thread_state * const thrst = ddsi_lookup_thread_state (); @@ -191,7 +225,6 @@ static uint32_t gcreq_queue_thread (struct ddsi_gcreq_queue *q) struct ddsi_gcreq_queue *ddsi_gcreq_queue_new (struct ddsi_domaingv *gv) { struct ddsi_gcreq_queue *q = ddsrt_malloc (sizeof (*q)); - q->first = q->last = NULL; q->terminate = 0; q->count = 0; @@ -231,7 +264,7 @@ void ddsi_gcreq_queue_free (struct ddsi_gcreq_queue *q) if (q->thrst) { /* Create a no-op not dependent on any thread */ - gcreq = ddsi_gcreq_new (q, ddsi_gcreq_free); + gcreq = ddsi_gcreq_new (q, ddsi_gcreq_free); gcreq->nvtimes = 0; ddsrt_mutex_lock (&q->lock); diff --git a/src/core/ddsi/src/ddsi_handshake.c b/src/core/ddsi/src/ddsi_handshake.c index e035dbe498..4b4ac59bbd 100644 --- a/src/core/ddsi/src/ddsi_handshake.c +++ b/src/core/ddsi/src/ddsi_handshake.c @@ -37,7 +37,6 @@ #define HSEXCEPTION(e, ...) \ ddsi_omg_log_exception(&handshake->gv->logconfig, DDS_LC_WARNING, e, __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) - #define VERBOSE_HANDSHAKE_DEBUG #if 1 @@ -1003,7 +1002,6 @@ static struct ddsi_handshake * ddsi_handshake_create(struct ddsi_participant *pp handshake = ddsrt_malloc(sizeof(struct ddsi_handshake)); memset(handshake, 0, sizeof(struct ddsi_handshake)); - ddsrt_mutex_init(&handshake->lock); handshake->auth = ddsi_omg_participant_get_authentication(pp); ddsrt_atomic_st32(&handshake->refc, 1); diff --git a/src/core/ddsi/src/ddsi_radmin.c b/src/core/ddsi/src/ddsi_radmin.c index 2ad8d8500f..15ad336830 100644 --- a/src/core/ddsi/src/ddsi_radmin.c +++ b/src/core/ddsi/src/ddsi_radmin.c @@ -2506,6 +2506,53 @@ static enum dqueue_elem_kind dqueue_elem_kind (const struct ddsi_rsample_chain_e return DQEK_BUBBLE; } +bool ddsi_dqueue_step_deaf (struct ddsi_dqueue *q) +{ + struct ddsi_thread_state * const thrst = ddsi_lookup_thread_state (); + struct ddsi_rsample_chain sc; + ddsrt_mutex_lock (&q->lock); + while ((sc = q->sc).first != NULL) + { + q->sc.first = q->sc.last = NULL; + ddsrt_mutex_unlock (&q->lock); + + ddsi_thread_state_awake (thrst, q->gv); + while (sc.first) + { + struct ddsi_rsample_chain_elem *e = sc.first; + sc.first = e->next; + ddsi_thread_state_awake_to_awake_no_nest (thrst); + switch (dqueue_elem_kind (e)) + { + case DQEK_DATA: + case DQEK_GAP: + ddsi_fragchain_unref (e->fragchain); + break; + case DQEK_BUBBLE: { + struct ddsi_dqueue_bubble *b = (struct ddsi_dqueue_bubble *) e->sampleinfo; + switch (b->kind) + { + case DDSI_DQBK_STOP: + case DDSI_DQBK_RDGUID: + break; + case DDSI_DQBK_CALLBACK: + b->u.cb.cb (b->u.cb.arg); + break; + break; + } + ddsrt_free (b); + break; + } + } + } + ddsi_thread_state_asleep (thrst); + ddsrt_mutex_lock (&q->lock); + } + const bool ret = q->sc.first != NULL; + ddsrt_mutex_unlock (&q->lock); + return ret; +} + static uint32_t dqueue_thread (struct ddsi_dqueue *q) { struct ddsi_thread_state * const thrst = ddsi_lookup_thread_state (); diff --git a/src/core/ddsi/src/ddsi_vnet.c b/src/core/ddsi/src/ddsi_vnet.c index 78a32be515..9e077c182f 100644 --- a/src/core/ddsi/src/ddsi_vnet.c +++ b/src/core/ddsi/src/ddsi_vnet.c @@ -64,6 +64,15 @@ static int ddsi_vnet_conn_locator (struct ddsi_tran_factory * vfact, struct ddsi return 0; } +static ssize_t ddsi_vnet_conn_write (struct ddsi_tran_conn * conn_cmn, const ddsi_locator_t *dst, const ddsi_tran_write_msgfrags_t *msgfrags, uint32_t flags) +{ + (void) conn_cmn; (void) dst; (void) flags; + ddsrt_iov_len_t n = 0; + for (size_t i = 0; i < msgfrags->niov; i++) + n += msgfrags->iov[i].iov_len; + return (ssize_t) n; +} + static dds_return_t ddsi_vnet_create_conn (struct ddsi_tran_conn **conn_out, struct ddsi_tran_factory * fact_cmn, uint32_t port, const struct ddsi_tran_qos *qos) { (void) port; @@ -79,7 +88,7 @@ static dds_return_t ddsi_vnet_create_conn (struct ddsi_tran_conn **conn_out, str x->m_base.m_base.m_handle_fn = ddsi_vnet_conn_handle; x->m_base.m_locator_fn = ddsi_vnet_conn_locator; x->m_base.m_read_fn = 0; - x->m_base.m_write_fn = 0; + x->m_base.m_write_fn = ddsi_vnet_conn_write; x->m_base.m_disable_multiplexing_fn = 0; DDS_CTRACE (&fact->m_base.gv->logconfig, "ddsi_vnet_create_conn intf %s kind %s\n", x->m_base.m_interf->name, fact->m_base.m_typename); diff --git a/src/core/ddsi/src/ddsi_xevent.c b/src/core/ddsi/src/ddsi_xevent.c index a4745d96e4..d4b68ebc74 100644 --- a/src/core/ddsi/src/ddsi_xevent.c +++ b/src/core/ddsi/src/ddsi_xevent.c @@ -592,6 +592,19 @@ static void handle_xevents (struct ddsi_thread_state * const thrst, struct ddsi_ ASSERT_MUTEX_HELD (&xevq->lock); } +void ddsi_xeventq_step (struct ddsi_xeventq *evq) +{ + struct ddsi_thread_state * const thrst = ddsi_lookup_thread_state (); + struct ddsi_xpack * const xp = ddsi_xpack_new (evq->gv, false); + ddsi_thread_state_awake (thrst, evq->gv); + ddsrt_mutex_lock (&evq->lock); + handle_xevents (thrst, evq, xp, ddsrt_time_monotonic ()); + ddsrt_mutex_unlock (&evq->lock); + ddsi_thread_state_asleep (thrst); + ddsi_xpack_send (xp, true); + ddsi_xpack_free (xp); +} + static uint32_t xevent_thread (struct ddsi_xeventq * xevq) { struct ddsi_thread_state * const thrst = ddsi_lookup_thread_state (); diff --git a/src/security/builtin_plugins/authentication/CMakeLists.txt b/src/security/builtin_plugins/authentication/CMakeLists.txt index a652c1ace6..ff3c868121 100644 --- a/src/security/builtin_plugins/authentication/CMakeLists.txt +++ b/src/security/builtin_plugins/authentication/CMakeLists.txt @@ -27,6 +27,12 @@ else() add_library(dds_security_auth OBJECT ${sources} ${private_headers}) set_property(GLOBAL APPEND PROPERTY cdds_plugin_list dds_security_auth) set_property(GLOBAL PROPERTY dds_security_auth_symbols init_authentication finalize_authentication) + if(DEFINED ENV{LIB_FUZZING_ENGINE}) + set_property(GLOBAL APPEND PROPERTY dds_security_auth_symbols + generate_dh_keys + dh_public_key_to_oct + create_validate_asymmetrical_signature) + endif() endif() generate_export_header( From 369dc226c5651f6f141f64b1e0b2ebd54dad747a Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 7 May 2024 23:03:29 +0200 Subject: [PATCH 085/207] Refactor delivery requests: a delivery request is now done for a reader iso for a set Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 25 +- src/durability/src/dds_durability.c | 1100 +++++++++-------- src/durability/src/durablesupport.c | 355 +++--- 3 files changed, 810 insertions(+), 670 deletions(-) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index fc42a5a26f..0750233696 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -285,10 +285,15 @@ typedef uint64_t DurableSupport_delivery_id_t; #define DurableSupport_delivery_id_t__alloc() \ ((DurableSupport_delivery_id_t*) dds_alloc (sizeof (DurableSupport_delivery_id_t))); +typedef struct DurableSupport_request_key +{ + DurableSupport_id_t rguid; +} DurableSupport_request_key; + typedef struct DurableSupport_request { + struct DurableSupport_request_key key; DurableSupport_id_t client; - DurableSupport_id_t rguid; char * partition; char * tpname; char * type_id; @@ -305,9 +310,27 @@ dds_sample_free ((d), &DurableSupport_request_desc, (o)) #define DurableSupport_RESPONSETYPE_SET 1 #define DurableSupport_RESPONSETYPE_DATA 2 +#ifndef DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED +#define DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED +typedef struct dds_sequence_DurableSupport_id_t +{ + uint32_t _maximum; + uint32_t _length; + DurableSupport_id_t *_buffer; + bool _release; +} dds_sequence_DurableSupport_id_t; + +#define dds_sequence_DurableSupport_id_t__alloc() \ +((dds_sequence_DurableSupport_id_t*) dds_alloc (sizeof (dds_sequence_DurableSupport_id_t))); + +#define dds_sequence_DurableSupport_id_t_allocbuf(l) \ +((DurableSupport_id_t *) dds_alloc ((l) * sizeof (DurableSupport_id_t))) +#endif /* DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED */ + typedef struct DurableSupport_response_set_t { DurableSupport_delivery_id_t delivery_id; + dds_sequence_DurableSupport_id_t guids; char * partition; char * tpname; char * type_id; diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 869d4f29e0..e21e7c0239 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -141,14 +141,40 @@ static int dc_blob_image (dds_sequence_octet blob, char *buf, size_t n) return -1; } -static int dc_stringify_request (char *buf, size_t n, const DurableSupport_request *request, bool valid_data) +static int dc_stringify_request_key (char *buf, size_t n, const DurableSupport_request_key *key) { size_t i = 0; int l; - char id_str[37]; char rguid_str[37]; + + if (buf == NULL) { + goto err; + } + if (key == NULL) { + buf[0] = '\0'; + return 0; + } + if ((l = snprintf(buf+i, n-i, "\"key\":{\"rguid\":\"%s\"}", dc_stringify_id(key->rguid, rguid_str))) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_request_key failed"); + return -1; +} + +static int dc_stringify_request (char *buf, size_t n, const DurableSupport_request *request, bool valid_data) +{ + size_t i = 0; + int l; int64_t sec; uint32_t msec; + char id_str[37]; if (buf == NULL) { goto err; @@ -157,33 +183,138 @@ static int dc_stringify_request (char *buf, size_t n, const DurableSupport_reque buf[0] = '\0'; return 0; } + buf[i++] = '{'; + if ((l = dc_stringify_request_key(buf+i, n-i, &request->key)) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + /* print non-key fields for valid data */ if (valid_data) { - /* also print non-key fields */ + if ((l = snprintf(buf+i, n-i, ", \"client\":\"%s\"", dc_stringify_id(request->client, id_str))) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } if (request->timeout == DDS_INFINITY) { - if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"rguid\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"timeout\":\"never\"}", dc_stringify_id(request->client, id_str), dc_stringify_id(request->rguid, rguid_str), request->partition, request->tpname, request->type_id)) < 0) { + if ((l = snprintf(buf+i, n-i, ", \"timeout\":\"never\"")) < 0) { goto err; } } else { sec = (int64_t)(request->timeout / DDS_NSECS_IN_SEC); msec = (uint32_t)((request->timeout % DDS_NSECS_IN_SEC) / DDS_NSECS_IN_MSEC); - if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"timeout\":%" PRId64 ".%03" PRIu32 "}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, request->type_id, sec, msec)) < 0) { + if ((l = snprintf(buf+i, n-i, ", \"timeout\":%" PRId64 ".%03" PRIu32, sec, msec)) < 0) { goto err; } } - } else { - /* only print key fields */ - if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, request->type_id)) < 0) { + i += (size_t)l; + if (i >= n) { + goto trunc; + } + } + if (i < n) { + buf[i++] = '}'; + } + if (i < n) { + buf[i] = '\0'; + } +trunc: + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_request failed"); + return -1; +} + +static int dc_stringify_response_set (char *buf, size_t n, const DurableSupport_response_set_t *response_set) +{ + size_t i = 0, j; + int l; + char id_str[37]; + bool first = true; + + if (buf == NULL) { + goto err; + } + if (response_set == NULL) { + buf[0] = '\0'; + return 0; + } + if ((l = snprintf(buf+i, n-i, "{\"delivery_id\":%" PRIu64 ", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"flags\":\"0x%04" PRIx32 "\", \"guids\":[", response_set->delivery_id, response_set->partition, response_set->tpname, response_set->type_id, response_set->flags)) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + for(j=0; j < response_set->guids._length; j++) { + if ((l = snprintf(buf+i, n-i, "%s\"%s\"", (first) ? "" : ",", dc_stringify_id(response_set->guids._buffer[j], id_str))) < 0) { goto err; } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + first = false; + } + if (i < n) { + buf[i++] = ']'; + } + if (i < n) { + buf[i++] = '}'; + } +trunc: + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_response_set failed"); + return -1; +} + +static int dc_stringify_response_data (char *buf, size_t n, const DurableSupport_response_data_t *response_data) +{ + size_t i = 0; + int l; + char blob_str[64]; + + if (buf == NULL) { + goto err; + } + if (response_data == NULL) { + buf[0] = '\0'; + return 0; + } + if (dc_blob_image(response_data->blob, blob_str, sizeof(blob_str)) < 0) { + goto err; + } + if ((l = snprintf(buf+i, n-i, "{\"blob\":\"%s\"", blob_str)) < 0) { + goto err; } i += (size_t)l; + if (i >= n) { + goto trunc; + } + if (i < n) { + buf[i++] = '}'; + } +trunc: if (i >= n) { /* truncated */ buf[n-1] = '\0'; } return (int)i; err: - DDS_ERROR("dc_stringify_request failed"); + DDS_ERROR("dc_stringify_response_data failed"); return -1; } @@ -192,7 +323,6 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp size_t i = 0; int l; char id_str[37]; - char blob_str[64]; if (buf == NULL) { goto err; @@ -201,7 +331,7 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp buf[0] = '\0'; return 0; } - if ((l = snprintf(buf+i, n-i, "{\"id\":\"%s\", \"type\":\"%s\", \"content\":{", dc_stringify_id(response->id, id_str), dc_responsetype_image(response->body._d))) < 0) { + if ((l = snprintf(buf+i, n-i, "{\"id\":\"%s\", \"type\":\"%s\", \"content\":", dc_stringify_id(response->id, id_str), dc_responsetype_image(response->body._d))) < 0) { goto err; } i += (size_t)l; @@ -210,16 +340,13 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp } switch (response->body._d) { case DurableSupport_RESPONSETYPE_SET : - if ((l = snprintf(buf+i, n-i, "\"delivery_id\":%" PRIu64 ",\"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"flags\":\"0x%04" PRIx32 "\"", response->body._u.set.delivery_id, response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.type_id, response->body._u.set.flags)) < 0) { + if ((l = dc_stringify_response_set(buf+i, n-i, &response->body._u.set)) < 0) { goto err; } i += (size_t)l; break; case DurableSupport_RESPONSETYPE_DATA : - if (dc_blob_image(response->body._u.data.blob, blob_str, sizeof(blob_str)) < 0) { - goto err; - } - if ((l = snprintf(buf+i, n-i, "\"blob\":\"%s\"", blob_str)) < 0) { + if ((l = dc_stringify_response_data(buf+i, n-i, &response->body._u.data)) < 0) { goto err; } i += (size_t)l; @@ -230,9 +357,6 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp if (i < n) { buf[i++] = '}'; } - if (i < n) { - buf[i++] = '}'; - } trunc: if (i >= n) { /* truncated */ @@ -240,7 +364,7 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp } return (int)i; err: - DDS_ERROR("dc_stringify_response failed, type: %" PRIu16 ", buf: %s\n", response->body._d, !buf ? "NULL" : buf); + DDS_ERROR("dc_stringify_response failed"); return -1; } @@ -269,146 +393,225 @@ static void cleanup_server (void *n) static const ddsrt_avl_ctreedef_t server_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct server_t, node), offsetof (struct server_t, id), cmp_server, 0); -struct proxy_set_reader_key_t { - dds_guid_t guid; /* guid of the reader */ +struct delivery_reader_key_t { + dds_guid_t rguid; +}; + +struct delivery_reader_t { + ddsrt_avl_node_t node; /* represents a node in the tree of delivery reader */ + struct delivery_reader_key_t key; /* key of a delivery reader */ }; -static int cmp_proxy_set_reader (const void *a, const void *b) +static int cmp_delivery_reader (const void *a, const void *b) { - struct proxy_set_reader_key_t *k1 = (struct proxy_set_reader_key_t *)a; - struct proxy_set_reader_key_t *k2 = (struct proxy_set_reader_key_t *)b; + struct delivery_reader_key_t *k1 = (struct delivery_reader_key_t *)a; + struct delivery_reader_key_t *k2 = (struct delivery_reader_key_t *)b; - return memcmp(k1->guid.v, k2->guid.v, 16); + return memcmp(k1->rguid.v, k2->rguid.v, 16); } -struct proxy_set_reader_t { - ddsrt_avl_node_t node; - struct proxy_set_reader_key_t key; - dds_entity_t reader; - struct dds_rhc *rhc; -}; - -static void cleanup_proxy_set_reader (void *n) +static void cleanup_delivery_reader (void *n) { - struct proxy_set_reader_t *proxy_set_reader = (struct proxy_set_reader_t *)n; - - ddsrt_free(proxy_set_reader); + struct delivery_reader_t *rd = (struct delivery_reader_t *)n; + ddsrt_free(rd); } -static const ddsrt_avl_ctreedef_t proxy_set_reader_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct proxy_set_reader_t, node), offsetof (struct proxy_set_reader_t, key), cmp_proxy_set_reader, 0); +static const ddsrt_avl_ctreedef_t delivery_readers_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct delivery_reader_t, node), offsetof (struct delivery_reader_t, key), cmp_delivery_reader, 0); -struct proxy_set_key_t { - char *partition; /* partition name */ - char *tpname; /* topic name */ - char *type_id; /* type id */ +struct delivery_request_key_t { + dds_guid_t guid; /* the guid of the reader that requested historical data */ }; -struct proxy_set_t { - ddsrt_avl_node_t node; /* represents a node in the tree of pending requests */ - struct proxy_set_key_t key; /* key of a proxy set */ - ddsrt_avl_ctree_t readers; /* the tree of readers and their rhc that have an interest in this proxy set */ - uint64_t seq; /* the sequence number of the outstanding request for this proxy set, 0 if no outstanding request */ +/* This represents a request for historical data from a client to a ds. + * Such delivery request will lead to the publication of a transient-local + * autodisposed request topic to a DS. A delivery requests is keyed by the + * guid of the reader guid that request the historical data. + * Delivery requests carry an expiration time. When the expiration time + * expires, the delivery request will be disposed and is not available + * any more for late joining ds's. + * + * LH: to check: is it really necessary to allow expiration of requests? + * If a request is transient-local, autodisposed then there is no need + * to expire a request. Only if you want to request data from a different + * ds we should dispose the current requests, create another request reader + * that connects to another ds, and republish the requests. */ + +struct delivery_request_t { + ddsrt_avl_node_t node; /* represents a node in the tree of delivery requests */ + ddsrt_fibheap_node_t fhnode; /* represents a node in the priority queue */ + struct delivery_request_key_t key; /* key of the delivery request; represents the reader that requested historical data */ + dds_entity_t reader; /* the reader entity that requested historical data */ + dds_time_t exp_time; /* delivery request expiration time */ }; -static int cmp_proxy_set (const void *a, const void *b) +static int dc_stringify_delivery_request_key (char *buf, size_t n, const struct delivery_request_key_t *key) { - struct proxy_set_key_t *k1 = (struct proxy_set_key_t *)a; - struct proxy_set_key_t *k2 = (struct proxy_set_key_t *)b; - int cmp; + size_t i = 0; + int l; + char guid_str[37]; - /* compare partition */ - if ((cmp = strcmp(k1->partition, k2->partition)) < 0) { - return -1; - } else if (cmp > 0) { - return 1; + if (buf == NULL) { + goto err; } - /* compare topic */ - if ((cmp = strcmp(k1->tpname, k2->tpname)) < 0) { - return -1; - } else if (cmp > 0) { - return 1; + if (key == NULL) { + buf[0] = '\0'; + return 0; } - /* compare type id */ - if ((cmp = strcmp(k1->type_id, k2->type_id)) < 0) { - return -1; - } else if (cmp > 0) { - return 1; + if ((l = snprintf(buf+i, n-i, "\"key\":{\"guid\":\"%s\"}", dc_stringify_id(key->guid.v, guid_str))) < 0) { + goto err; } - return 0; + i += (size_t)l; + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_delivery_request_key failed"); + return -1; } -static void cleanup_proxy_set (void *n) +static int dc_stringify_delivery_request (char *buf, size_t n, const struct delivery_request_t *dr) { - struct proxy_set_t *proxy_set = (struct proxy_set_t *)n; + size_t i = 0; + int l; + int64_t sec; + uint32_t msec; - ddsrt_avl_cfree(&proxy_set_reader_td, &proxy_set->readers, cleanup_proxy_set_reader); - ddsrt_free(proxy_set->key.partition); - ddsrt_free(proxy_set->key.tpname); - ddsrt_free(proxy_set->key.type_id); - ddsrt_free(proxy_set); + if (buf == NULL) { + goto err; + } + if (dr == NULL) { + buf[0] = '\0'; + return 0; + } + buf[i++] = '{'; + if ((l = dc_stringify_delivery_request_key(buf+i, n-i, &dr->key)) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + if ((l = snprintf(buf+i, n-i, ", \", reader\":%" PRId32, dr->reader)) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + if (dr->exp_time == DDS_INFINITY) { + if ((l = snprintf(buf+i, n-i, ", \"exp_time\":\"never\"")) < 0) { + goto err; + } + } else { + sec = (int64_t)(dr->exp_time / DDS_NSECS_IN_SEC); + msec = (uint32_t)((dr->exp_time % DDS_NSECS_IN_SEC) / DDS_NSECS_IN_MSEC); + if ((l = snprintf(buf+i, n-i, ", \"exp_time\":%" PRId64 ".%03" PRIu32, sec, msec)) < 0) { + goto err; + } + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + buf[i++]='}'; + if (i < n) { + buf[i] = '\0'; + } +trunc: + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_delivery_request failed"); + return -1; } -static const ddsrt_avl_ctreedef_t proxy_set_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct proxy_set_t, node), offsetof (struct proxy_set_t, key), cmp_proxy_set, 0); - -struct pending_request_key_t { - uint64_t seq; /* the sequence number of the request */ -}; - -/* This represents a request for data for a proxy set. - * Such request will lead to the publication of a transient-local - * autodisposed request topic to a DS. Requests are keyed by a monotonically - * increasing sequence number. - * Requests can expire when no answer is received within the specified - * expiration time. In this case the request will be disposed to prevent - * that a DS reacts to an already expired request. - * - * LH: to check: is it really necessary to allow expiration of requests? - * If a request is transient-local, autodisposed then there is no need - * to expire a request. Only if you want to request data from a different - * ds we should dispose the current requests, create another request reader - * that connects to another ds, and republish the requests. */ -struct pending_request_t { - ddsrt_avl_node_t node; /* represents a node in the tree of pending requests */ - ddsrt_fibheap_node_t fhnode; /* represents a node in the priority queue */ - struct pending_request_key_t key; /* sequence number of the request */ - struct proxy_set_t *proxy_set; /* the proxy set associated with the request */ - dds_time_t exp_time; /* request expiration time */ -}; - -static int cmp_pending_request (const void *a, const void *b) +static int cmp_delivery_request (const void *a, const void *b) { - struct pending_request_key_t *k1 = (struct pending_request_key_t *)a; - struct pending_request_key_t *k2 = (struct pending_request_key_t *)b; + struct delivery_request_key_t *k1 = (struct delivery_request_key_t *)a; + struct delivery_request_key_t *k2 = (struct delivery_request_key_t *)b; - return (k1->seq < k2->seq) ? -1 : ((k1->seq > k2->seq) ? 1 : 0); + return memcmp(k1->guid.v, k2->guid.v, 16); } -static void cleanup_pending_request (void *n) +static void cleanup_delivery_request (void *n) { - struct pending_request_t *pr = (struct pending_request_t *)n; - ddsrt_free(pr); + struct delivery_request_t *dr = (struct delivery_request_t *)n; + ddsrt_free(dr); } static int cmp_exp_time (const void *a, const void *b) { - struct pending_request_t *pr1 = (struct pending_request_t *)a; - struct pending_request_t *pr2 = (struct pending_request_t *)b; + struct delivery_request_t *dr1 = (struct delivery_request_t *)a; + struct delivery_request_t *dr2 = (struct delivery_request_t *)b; - return (pr1->exp_time < pr2->exp_time) ? -1 : ((pr1->exp_time > pr2->exp_time) ? 1 : 0); + return (dr1->exp_time < dr2->exp_time) ? -1 : ((dr1->exp_time > dr2->exp_time) ? 1 : 0); } -static const ddsrt_avl_ctreedef_t pending_requests_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct pending_request_t, node), offsetof (struct pending_request_t, key), cmp_pending_request, 0); +static const ddsrt_avl_ctreedef_t delivery_requests_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct delivery_request_t, node), offsetof (struct delivery_request_t, key), cmp_delivery_request, 0); -static const ddsrt_fibheap_def_t pending_requests_fd = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct pending_request_t, fhnode), cmp_exp_time); +static const ddsrt_fibheap_def_t delivery_requests_fd = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct delivery_request_t, fhnode), cmp_exp_time); struct delivery_ctx_t { ddsrt_avl_node_t node; - DurableSupport_id_t id; /* id of the ds; key of the delivery context */ + DurableSupport_id_t id; /* id of the ds that delivers the data; key of the delivery context */ uint64_t delivery_id; /* the id of the delivery by this ds; this is a monotonic increased sequence number */ - struct proxy_set_t *proxy_set; /* current proxy_set for which responses are being received, NULL if not known */ + ddsrt_avl_ctree_t readers; /* tree of reader guids for which this delivery is intended */ }; +static int dc_stringify_delivery_ctx (char *buf, size_t n, const struct delivery_ctx_t *delivery_ctx) +{ + size_t i = 0; + int l; + char id_str[37]; + struct delivery_reader_t *delivery_reader; + ddsrt_avl_citer_t it; + bool first = true; + + if (buf == NULL) { + goto err; + } + if (delivery_ctx == NULL) { + buf[0] = '\0'; + return 0; + } + if ((l = snprintf(buf+i, n-i, "{\"id\":\"%s\", \"readers\":[", dc_stringify_id(delivery_ctx->id, id_str))) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + for (delivery_reader = ddsrt_avl_citer_first (&delivery_readers_td, &delivery_ctx->readers, &it); delivery_reader; delivery_reader = ddsrt_avl_citer_next (&it)) { + if ((l = snprintf(buf+i, n-i, "%s%s", (first) ? "" : ",", dc_stringify_id(delivery_reader->key.rguid.v, id_str))) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + first = false; + } + if ((l = snprintf(buf+i, n-i, "]}")) < 0) { + goto err; + } + i += (size_t)l; +trunc: + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_delivery_ctx failed"); + return -1; +} + static int delivery_ctx_cmp (const void *a, const void *b) { return memcmp(a, b, 16); @@ -416,7 +619,8 @@ static int delivery_ctx_cmp (const void *a, const void *b) static void cleanup_delivery_ctx (void *n) { - struct delivery_ctx *delivery_ctx = (struct delivery_ctx *)n; + struct delivery_ctx_t *delivery_ctx = (struct delivery_ctx_t *)n; + ddsrt_avl_cfree(&delivery_readers_td, &delivery_ctx->readers, cleanup_delivery_reader); ddsrt_free(delivery_ctx); } @@ -464,7 +668,7 @@ struct com_t { dds_entity_t rd_participant; /* participant reader */ dds_entity_t rd_subinfo; /* DCPSSubscription reader */ dds_entity_t rc_subinfo; /* DCPSSubscription read condition */ - dds_entity_t pending_request_guard; /* trigger expiration of pending request */ + dds_entity_t delivery_request_guard; /* trigger expiration of delivery request */ dds_listener_t *status_listener; /* listener on status topic */ dds_entity_t ws; }; @@ -500,13 +704,12 @@ struct dc_t { dds_listener_t *subinfo_listener; /* listener to detect remote containers */ dds_listener_t *quorum_listener; /* listener to check if a quorum is reached */ dds_listener_t *request_listener; /* listener to check if request reader is available */ - ddsrt_avl_ctree_t pending_requests; /* tree containing pending requests */ - ddsrt_fibheap_t pending_requests_fh; /* priority queue for pending requests, prioritized by expiry time */ - ddsrt_mutex_t pending_request_mutex; /* pending request queue mutex */ - ddsrt_cond_t pending_request_cond; /* pending request condition */ + ddsrt_avl_ctree_t delivery_requests; /* tree containing delivery requests */ + ddsrt_fibheap_t delivery_requests_fh; /* priority queue for delivery requests, prioritized by expiry time */ + ddsrt_mutex_t delivery_request_mutex; /* delivery request queue mutex */ + ddsrt_cond_t delivery_request_cond; /* delivery request condition */ dds_instance_handle_t selected_request_reader_ih; /* instance handle to matched request reader, DDS_HANDLE_NIL if not available */ ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on a ds that match with my request writer */ - ddsrt_avl_ctree_t proxy_sets; /* tree containing the sets for which data has to be provided by a ds */ uint32_t nr_of_matched_dc_requests; /* indicates the number of matched dc_request readers for the dc_request writer of this client */ struct delivery_ctx_t *delivery_ctx; /* reference to current delivery context, NULL if none */ ddsrt_avl_ctree_t delivery_ctxs; /* table of delivery contexts, keyed by ds id */ @@ -1073,13 +1276,13 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc subinfo read condition [%s]\n", dds_strretcode(-com->rc_subinfo)); goto err_rc_subinfo; } - /* create pending reuqest guard condition */ - if ((com->pending_request_guard = dds_create_guardcondition(com->participant)) < 0) { - DDS_ERROR("failed to create guard condition [%s]\n", dds_strretcode(-com->pending_request_guard)); - goto err_create_pending_request_guard_condition; + /* create delivery request guard condition */ + if ((com->delivery_request_guard = dds_create_guardcondition(com->participant)) < 0) { + DDS_ERROR("failed to create delivery guard condition [%s]\n", dds_strretcode(-com->delivery_request_guard)); + goto err_create_delivery_request_guard_condition; } - if ((ret = dds_set_guardcondition(com->pending_request_guard, false)) < 0) { - DDS_ERROR("failed to initialize guard condition [%s]\n", dds_strretcode(-ret)); + if ((ret = dds_set_guardcondition(com->delivery_request_guard, false)) < 0) { + DDS_ERROR("failed to initialize delivery guard condition [%s]\n", dds_strretcode(-ret)); goto err_set_guard_condition; } /* create waitset and attach read conditions */ @@ -1087,9 +1290,9 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc waitset [%s]\n", dds_strretcode(-com->ws)); goto err_waitset; } - if ((ret = dds_waitset_attach (com->ws, com->pending_request_guard, com->pending_request_guard)) < 0) { - DDS_ERROR("failed to attach pending request guard condition to waitset [%s]\n", dds_strretcode(-ret)); - goto err_attach_pending_request_guard; + if ((ret = dds_waitset_attach (com->ws, com->delivery_request_guard, com->delivery_request_guard)) < 0) { + DDS_ERROR("failed to attach delivery request guard condition to waitset [%s]\n", dds_strretcode(-ret)); + goto err_attach_delivery_request_guard; } if ((ret = dds_waitset_attach (com->ws, com->rc_status, com->rd_status)) < 0) { DDS_ERROR("failed to attach dc status reader to waitset [%s]\n", dds_strretcode(-ret)); @@ -1123,12 +1326,12 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, err_attach_rd_response: dds_waitset_detach(com->ws, com->rc_status); err_attach_rd_status: - dds_waitset_detach(com->ws, com->pending_request_guard); -err_attach_pending_request_guard: + dds_waitset_detach(com->ws, com->delivery_request_guard); +err_attach_delivery_request_guard: dds_delete(com->ws); err_waitset: - dds_delete(com->pending_request_guard); -err_create_pending_request_guard_condition: + dds_delete(com->delivery_request_guard); +err_create_delivery_request_guard_condition: err_set_guard_condition: dds_delete(com->rc_subinfo); err_rc_subinfo: @@ -1201,7 +1404,7 @@ static void dc_com_free (struct com_t *com) #define MAX_TOPIC_NAME_SIZE 255 -static dds_return_t dc_com_request_write (struct com_t *com, const dds_guid_t rguid, const char *partition, const char *tpname, const char *type_id) +static dds_return_t dc_com_request_write (struct com_t *com, const dds_guid_t rguid) { /* note: we allow doing a request for volatile readers */ DurableSupport_request *request; @@ -1211,11 +1414,8 @@ static dds_return_t dc_com_request_write (struct com_t *com, const dds_guid_t rg size_t len; request = DurableSupport_request__alloc(); + memcpy(request->key.rguid, rguid.v, 16); memcpy(request->client, dc.cfg.id, 16); - memcpy(request->rguid, rguid.v, 16); - request->partition = ddsrt_strdup(partition); - request->tpname = ddsrt_strdup(tpname); - request->type_id = ddsrt_strdup(type_id); request->timeout = DDS_INFINITY; l = dc_stringify_request(str, sizeof(str), request, true); assert(l > 0); @@ -1304,42 +1504,6 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } -static struct proxy_set_t *dc_create_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, const char *type_id) -{ - struct proxy_set_t *proxy_set = NULL; - - assert(partition); - assert(tpname); - proxy_set = (struct proxy_set_t *)ddsrt_malloc(sizeof(struct proxy_set_t)); - proxy_set->key.partition = ddsrt_strdup(partition); - proxy_set->key.tpname = ddsrt_strdup(tpname); - proxy_set->key.type_id = ddsrt_strdup(type_id); - proxy_set->seq = 0; /* no pending request yet */ - ddsrt_avl_cinit(&proxy_set_reader_td, &proxy_set->readers); - ddsrt_avl_cinsert(&proxy_set_td, &dc->proxy_sets, proxy_set); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "proxy set '%s.%s<%s>' created\n", proxy_set->key.partition, proxy_set->key.tpname, proxy_set->key.type_id); - return proxy_set; -} - -static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, const char *type_id, bool autocreate) -{ - struct proxy_set_key_t key; - struct proxy_set_t *proxy_set; - - assert(partition); - assert(tpname); - key.partition = ddsrt_strdup(partition); - key.tpname = ddsrt_strdup(tpname); - key.type_id = ddsrt_strdup(type_id); - if (((proxy_set = ddsrt_avl_clookup (&proxy_set_td, &dc->proxy_sets, &key)) == NULL) && autocreate) { - proxy_set = dc_create_proxy_set(dc, partition, tpname, type_id); - } - ddsrt_free(key.partition); - ddsrt_free(key.tpname); - ddsrt_free(key.type_id); - return proxy_set; -} - /* lookup the delivery context for the ds identified by id * if not found and autocreate=true, then create the delivery context */ static struct delivery_ctx_t *dc_get_delivery_ctx (struct dc_t *dc, DurableSupport_id_t id, bool autocreate) @@ -1351,88 +1515,131 @@ static struct delivery_ctx_t *dc_get_delivery_ctx (struct dc_t *dc, DurableSuppo } else if (((delivery_ctx = ddsrt_avl_clookup (&delivery_ctx_td, &dc->delivery_ctxs, id)) == NULL) && autocreate) { delivery_ctx = ddsrt_malloc(sizeof(struct delivery_ctx_t)); memcpy(delivery_ctx->id,id,16); - delivery_ctx->delivery_id = 0; - delivery_ctx->proxy_set = NULL; + ddsrt_avl_cinit(&delivery_readers_td, &delivery_ctx->readers); ddsrt_avl_cinsert(&delivery_ctx_td, &dc->delivery_ctxs, delivery_ctx); } return delivery_ctx; } -/* Remove the current delivery */ -static void dc_remove_current_delivery (struct dc_t *dc) +/* Remove the delivery identified by id */ +static void dc_remove_delivery_ctx (struct dc_t *dc, DurableSupport_id_t id) { struct delivery_ctx_t *delivery_ctx; ddsrt_avl_dpath_t dpath; - if (dc->delivery_ctx) { - - if ((delivery_ctx = ddsrt_avl_clookup_dpath(&delivery_ctx_td, &dc->delivery_ctxs, dc->delivery_ctx->id, &dpath)) != NULL) { - assert(dc->delivery_ctx == delivery_ctx); - /* remove the delivery ctx from the tree */ - ddsrt_avl_cdelete_dpath(&delivery_ctx_td, &dc->delivery_ctxs, delivery_ctx, &dpath); - cleanup_delivery_ctx(delivery_ctx); + if ((delivery_ctx = ddsrt_avl_clookup_dpath(&delivery_ctx_td, &dc->delivery_ctxs, id, &dpath)) != NULL) { + ddsrt_avl_cdelete_dpath(&delivery_ctx_td, &dc->delivery_ctxs, delivery_ctx, &dpath); + if (delivery_ctx == dc->delivery_ctx) { + dc->delivery_ctx = NULL; } - /* reset the current delivery ctx */ - dc->delivery_ctx = NULL; + cleanup_delivery_ctx(delivery_ctx); } } -/* Abort the current delivery (i.e., dc->delivery_ctx) */ -static void dc_abort_current_delivery (struct dc_t *dc) +static struct delivery_reader_t *create_delivery_reader (dds_guid_t *guid) { - char id_str[37]; - - assert(dc->delivery_ctx); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "aborting delivery %" PRIu64 " from ds \"%s\"\n", - dc->delivery_ctx->delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str)); - /* todo: reschedule the proxy set */ + struct delivery_reader_t *delivery_reader; - /* remove the current delivery ctx */ - dc_remove_current_delivery(dc); + delivery_reader = ddsrt_malloc(sizeof(struct delivery_reader_t)); + memcpy(delivery_reader->key.rguid.v, guid->v, 16); + return delivery_reader; } -/* open the delivery context for the ds identified by id */ -static void dc_open_delivery (struct dc_t *dc, DurableSupport_response *response) +static struct delivery_reader_t *dc_get_reader_from_delivery_ctx (struct delivery_ctx_t *delivery_ctx, DurableSupport_id_t id, bool autocreate) { - char id_str[37]; - uint64_t delivery_id; + struct delivery_reader_t *delivery_reader; + ddsrt_avl_ipath_t path; + dds_guid_t key; - assert(response); - assert(response->body._u.set.flags & DC_FLAG_SET_BEGIN); - delivery_id = response->body._u.set.delivery_id; - /* now create the new delivery context */ - if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, true)) == NULL) { - DDS_ERROR("unable to create an delivery context for ds \"%s\" and delivery id %" PRIu64 "\n", dc_stringify_id(response->id, id_str), delivery_id); - abort(); - } - /* set the delivery_id and proxy set for this delivery context */ - dc->delivery_ctx->delivery_id = delivery_id; - if ((dc->delivery_ctx->proxy_set = dc_get_proxy_set(dc, response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.type_id, false)) == NULL) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "no proxy set for \"%s.%s<%s>\" found, ignore delivery\n", response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.type_id); - /* abort this delivery context */ - dc_abort_current_delivery(dc); - return; + memcpy(key.v, id, 16); + /* create a container for the topic */ + if (((delivery_reader = ddsrt_avl_clookup_ipath(&delivery_readers_td, &delivery_ctx->readers, &key, &path)) == NULL) && (autocreate)) { + delivery_reader = create_delivery_reader(&key); + ddsrt_avl_cinsert_ipath(&delivery_readers_td, &delivery_ctx->readers, delivery_reader, &path); } - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s<%s>\" opened\n", - delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str), dc->delivery_ctx->proxy_set->key.partition, dc->delivery_ctx->proxy_set->key.tpname, dc->delivery_ctx->proxy_set->key.type_id); + return delivery_reader; } /* close the current delivery context for the ds identified by id */ static void dc_close_delivery (struct dc_t *dc, DurableSupport_id_t id, DurableSupport_response_set_t *response_set) { char id_str[37]; + char str[1024]; - DC_UNUSED_ARG(response_set); - DC_UNUSED_ARG(id); assert(response_set); assert(response_set->flags & DC_FLAG_SET_END); - assert(memcmp(dc->delivery_ctx->id,id,16) == 0); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s\" closed\n", - dc->delivery_ctx->delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str), dc->delivery_ctx->proxy_set->key.partition, dc->delivery_ctx->proxy_set->key.tpname); - /* todo: mark the proxy set as complete */ + /* lookup the align context for this aligner */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, id, false)) == NULL) { + /* There exists a delivery context for the ds that produced the response. */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "unable to close delivery for ds \"%s\"\n", dc_stringify_id(id, id_str)); + return; + } + /* there exists a delivery context for the ds identified by id, close this delivery context */ + (void)dc_stringify_delivery_ctx(str, sizeof(str), dc->delivery_ctx); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "close delivery %s\n", str); + /* remove current delivery ctx */ + dc_remove_delivery_ctx(dc, id); +} + +/* Abort the current delivery context for the ds identified by id + * + * The current delivery is aborted when a new response set is received without the + * previous set being ended correctly. */ +static void dc_abort_delivery (struct dc_t *dc, DurableSupport_id_t id, DurableSupport_response_set_t *response_set) +{ + char id_str[37]; + char str[1024]; + DC_UNUSED_ARG(response_set); + /* lookup the align context for this aligner */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, id, false)) == NULL) { + /* There exists a delivery context for the ds that produced the response. */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "unable to abort delivery for unknown delivery from ds \"%s\"\n", dc_stringify_id(id, id_str)); + return; + } + assert(memcmp(dc->delivery_ctx->id,id,16) == 0); + (void)dc_stringify_delivery_ctx(str, sizeof(str), dc->delivery_ctx); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "abort delivery %s", str); /* remove current delivery ctx */ - dc_remove_current_delivery(dc); + dc_remove_delivery_ctx(dc, id); +} + +/* open the delivery context for the ds identified by id */ +static void dc_open_delivery (struct dc_t *dc, DurableSupport_id_t id, DurableSupport_response_set_t *response_set) +{ + char id_str[37]; + char str[1024]; + uint32_t i; + + assert(response_set); + assert(response_set->flags & DC_FLAG_SET_BEGIN); + /* lookup the align context for this aligner */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, id, false)) != NULL) { + /* There already exists a delivery context for the ds that produced the response. + * Implicitly abort it before opening a new one.*/ + dc_abort_delivery(dc, id, response_set); + } + /* Now create the new delivery context */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, id, true)) == NULL) { + DDS_ERROR("unable to create an delivery context for ds \"%s\"\n", dc_stringify_id(id, id_str)); + abort(); + } + assert(dc->delivery_ctx); + /* Collect the readers for which the response is intended in the delivery context. + * A response set usually carries a non-empty set of reader guids without duplicates. + * However, whenever a response set accidentally contains duplicate reader guids or + * no readers at all, we don't want this to cause any trouble, so we will handle + * these cases as well. + * In case a response contains duplicate reader guids, then we will administrate + * the reader only once. + * In case a response is published with an empty reader list, the readers in the + * delivery context will be empty. Any response data belonging to such set will simply + * not be delivered to any reader. */ + for (i=0; i < response_set->guids._length; i++) { + (void)dc_get_reader_from_delivery_ctx(dc->delivery_ctx, response_set->guids._buffer[i], true); + } + (void)dc_stringify_delivery_ctx(str, sizeof(str), dc->delivery_ctx); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "open delivery %s\n", str); } static void dc_process_set_response_begin(struct dc_t *dc, DurableSupport_response *response) @@ -1446,39 +1653,18 @@ static void dc_process_set_response_begin(struct dc_t *dc, DurableSupport_respon assert(memcmp(dc->delivery_ctx->id, response->id, 16) == 0); DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "current open delivery %" PRIu64 " has missed an end\n", dc->delivery_ctx->delivery_id); /* abort the currently open delivery */ - dc_abort_current_delivery(dc); + dc_abort_delivery(dc, dc->delivery_ctx->id, &response->body._u.set); } assert(dc->delivery_ctx == NULL); /* open the new delivery */ - dc_open_delivery(dc, response); + dc_open_delivery(dc, response->id, &response->body._u.set); } static void dc_process_set_response_end (struct dc_t *dc, DurableSupport_response *response) { - char id_str[37]; - - /* A response set end is received. Lookup the existing delivery context for this ds */ - if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, false)) != NULL) { - assert(memcmp(dc->delivery_ctx->id, response->id, 16) == 0); - /* verify that this response set end belongs the currently opened delivery. - * by comparing the delivery_id. If they do not match, then this response - * set end does not belong to the currently opened set. This means that - * delivery of the currently opened set has failed and needs to be aborted. */ - if (dc->delivery_ctx->delivery_id != response->body._u.set.delivery_id) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "current open delivery %" PRIu64 " does not belong to end delivery %" PRIu64 "\n", - dc->delivery_ctx->delivery_id, response->body._u.set.delivery_id); - /* abort the currently open delivery */ - dc_abort_current_delivery(dc); - } else { - /* the end belongs to the correct begin; we have received all data for the set - * and can properly close the delivery */ - dc_close_delivery(dc, response->id, &response->body._u.set); - } - } else { - /* an end was received without a begin; no need to abort */ - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "end delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s\" received, but no corresponding open delivery found\n", - response->body._u.set.delivery_id, dc_stringify_id(response->id, id_str), response->body._u.set.partition, response->body._u.set.tpname); - } + assert(response); + assert(response->body._d == DurableSupport_RESPONSETYPE_SET); + dc_close_delivery(dc, response->id, &response->body._u.set); } static void dc_process_set_response_not_found(struct dc_t *dc, DurableSupport_response *response) @@ -1506,12 +1692,6 @@ static void dc_process_set_response (struct dc_t *dc, DurableSupport_response *r } } -#if 0 -int dc_deliver_blob () -{ -} -#endif - /* todo: this function is hared between ds and client */ static enum ddsi_serdata_kind get_serdata_kind (uint8_t kind) { @@ -1543,7 +1723,6 @@ static enum ddsi_serdata_kind get_serdata_kind (uint8_t kind) static void dc_process_data_response (struct dc_t *dc, DurableSupport_response *response) { - struct proxy_set_t *proxy_set = NULL; ddsrt_avl_citer_t it; const struct ddsi_sertype *sertype; struct ddsi_serdata *serdata; @@ -1556,24 +1735,22 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * dds_guid_t wguid; dds_return_t ret = DDS_RETCODE_OK; bool autodispose = 0; - struct proxy_set_reader_t *proxy_set_rd; char id_str[37]; + struct delivery_reader_t *delivery_reader; /* TODO: * A DS also has a response reader (by virtue of the CycloneDDS instance it runs). - * Currently, a DS therefore also receives responses that it sends itself. - * Because they is no proxy set the data is not injected, but I still like - * to have that a ds never receives responses. */ + * A DS therefore also receives responses that it sends to itself. + * Preferably we should prevent that the responses are end up at DSs. + * In any case, if responses do end up a DS, then the DS should ignore it. */ if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, false)) == NULL) { /* There is no delivery context for this data, which means that this node * did not request data for this set. If we do receive data, then we * can safely ignore it. */ return; } - if ((proxy_set = dc->delivery_ctx->proxy_set) == NULL) { - /* There is no proxy set for this data, which means that this node - * did not request data for this set. If we do receive data, then we - * can safely ignore it. */ + if (ddsrt_avl_cis_empty(&dc->delivery_ctx->readers)) { + /* There are no readers to deliver the data to. */ return; } /* A response_set begin has been received. Because data delivery is reliable, @@ -1595,16 +1772,30 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * serdata_size = response_size - serdata_offset; data_out.iov_len = serdata_size; data_out.iov_base = response->body._u.data.blob._buffer + serdata_offset; - /* now deliver the data to the local readers that have an interest in the data */ - for (proxy_set_rd = ddsrt_avl_citer_first (&proxy_set_reader_td, &proxy_set->readers, &it); proxy_set_rd; proxy_set_rd = ddsrt_avl_citer_next (&it)) { - dds_entity_t reader = proxy_set_rd->reader; + /* Now deliver the data to the local readers. */ + for (delivery_reader = ddsrt_avl_citer_first (&delivery_readers_td, &dc->delivery_ctx->readers, &it); delivery_reader; delivery_reader = ddsrt_avl_citer_next (&it)) { + /* take the guid and lookup the reader entity that requested the delivery */ + /* check if the reader still exists by lookup the entity */ + struct delivery_request_t *dr; + struct delivery_request_key_t key; + dds_entity_t reader; + + memcpy(key.guid.v, delivery_reader->key.rguid.v, 16); + if ((dr = ddsrt_avl_clookup(&delivery_requests_td, &dc->delivery_requests, &key)) == NULL) { + /* Unable to find a delivery request for this reader, so + * we cannot resolve the reader entity associated with the guid. + * Evidently, we cannot inject data into the rhc of a reader + * that we cannot resolve. */ + continue; + } + reader = dr->reader; /* in order to insert the data in the rhc of the reader we first * need to resolve the type of the reader */ if ((ret = dds_get_entity_sertype (reader, &sertype)) < 0) { - /* We failed to get the sertype. If it happens I do not consider - * this my problem, it is a problem in CycloneDDS. - * For now I silently ignore the data. After all, I cannot - * deliver the data to this reader! */ + /* We failed to get the sertype of the reader., so we cannot + * This could be because the reader does not exist any more, + * but frankly I don't about the reason. All that matters is + * that we cannot inject data into the rhc of this reader. */ continue; } /* get the serdata */ @@ -1619,7 +1810,7 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * serdata->timestamp.v = wt; memcpy(&serdata->writer_guid, &wguid, 16); if ((ret = dds_reader_store_historical_serdata(reader, wguid, autodispose, serdata)) != DDS_RETCODE_OK) { - DDS_ERROR("Failed to deliver historical data to reader \"%s\" [%s]\n", dc_stringify_id(proxy_set_rd->key.guid.v, id_str), dds_strretcode(ret)); + DDS_ERROR("Failed to deliver historical data to reader \"%s\" [%s]\n", dc_stringify_id(dr->key.guid.v, id_str), dds_strretcode(ret)); goto err_store_historical_serdata; } ddsi_serdata_to_ser_unref(serdata, &data_out); @@ -1680,120 +1871,78 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } -/* add the reader tree of readers for this proxy set */ -static void dc_register_reader_to_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, dds_guid_t guid, dds_entity_t reader, struct dds_rhc *rhc) +static void dc_delete_delivery_request (struct dc_t *dc, dds_guid_t rguid) { - struct proxy_set_reader_t *proxy_set_rd; - struct proxy_set_reader_key_t key; - char id_str[37]; + struct delivery_request_t *dr; + struct delivery_request_key_t key; + ddsrt_avl_dpath_t dpath; + char dr_str[512]; - key.guid = guid; - if ((proxy_set_rd = ddsrt_avl_clookup (&proxy_set_reader_td, &proxy_set->readers, &key)) == NULL) { - proxy_set_rd = (struct proxy_set_reader_t *)ddsrt_malloc(sizeof(struct proxy_set_reader_t)); - proxy_set_rd->key.guid = guid; - proxy_set_rd->reader = reader; - proxy_set_rd->rhc = rhc; - ddsrt_avl_cinsert(&proxy_set_reader_td, &proxy_set->readers, proxy_set_rd); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "reader \"%s\" added to proxy set '%s.%s'\n", dc_stringify_id(guid.v, id_str), proxy_set->key.partition, proxy_set->key.tpname); + memcpy(key.guid.v, rguid.v, 16); + if ((dr = ddsrt_avl_clookup_dpath (&delivery_requests_td, &dc->delivery_requests, &key, &dpath)) != NULL) { + ddsrt_avl_cdelete_dpath(&delivery_requests_td, &dc->delivery_requests, dr, &dpath); + (void)dc_stringify_delivery_request(dr_str, sizeof(dr_str), dr); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delete delivery request %s\n", dr_str); + cleanup_delivery_request(dr); } - assert(proxy_set_rd->rhc == rhc); } -static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reader, struct dds_rhc *rhc) +static struct delivery_request_t *dc_insert_delivery_request (struct dc_t *dc, dds_entity_t reader, dds_guid_t rguid) { - dds_entity_t topic; + struct delivery_request_t *dr; + struct delivery_request_key_t key; + ddsrt_avl_ipath_t ipath; + char dr_str[512]; dds_return_t rc; - char tpname[MAX_TOPIC_NAME_SIZE]; - dds_qos_t *rqos; - uint32_t plen, i; - char **partitions; - struct proxy_set_t *proxy_set = NULL; - dds_guid_t rguid; - char id_str[37]; - dds_typeinfo_t *typeinfo; - ddsi_typeid_t *tid = NULL; - struct ddsi_typeid_str tidstr = { 0 }; - if ((rc = dds_get_typeinfo(reader, &typeinfo)) != DDS_RETCODE_OK) { - DDS_ERROR("Unable to retrieve typeinfo [%s]\n", dds_strretcode(-rc)); - goto err_get_typeinfo; - } - if ((tid = ddsi_typeinfo_typeid(typeinfo, DDSI_TYPEID_KIND_COMPLETE)) == NULL) { - DDS_ERROR("Unable to retrieve typeid [%s]\n", dds_strretcode(-rc)); - goto err_typeid; + memcpy(key.guid.v, rguid.v, 16); + if ((dr = ddsrt_avl_clookup_ipath (&delivery_requests_td, &dc->delivery_requests, &key, &ipath)) == NULL) { + dr = ddsrt_malloc(sizeof(struct delivery_request_t)); + memcpy(dr->key.guid.v, rguid.v, 16); + dr->reader = reader; + dr->exp_time = DDS_NEVER; + (void)dc_stringify_delivery_request(dr_str, sizeof(dr_str), dr); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "create delivery request %s\n", dr_str); + ddsrt_avl_cinsert_ipath(&delivery_requests_td, &dc->delivery_requests, dr, &ipath); + ddsrt_fibheap_insert(&delivery_requests_fd, &dc->delivery_requests_fh, dr); + if (dr == ddsrt_fibheap_min(&delivery_requests_fd, &dc->delivery_requests_fh)) { + /* delivery request added to the front, trigger guard condition */ + if ((rc = dds_set_guardcondition(dc->com->delivery_request_guard, true)) < 0) { + DDS_ERROR("failed to set delivery request guard to true [%s]", dds_strretcode(rc)); + } + } } - (void)ddsi_make_typeid_str(&tidstr, tid); - /* get reader guid */ + return dr; +} + +static void dc_send_request_for_reader (struct dc_t *dc, dds_entity_t reader, struct dds_rhc *rhc) +{ + dds_return_t rc; + dds_guid_t rguid; + + (void)rhc; if ((rc = dds_get_guid(reader, &rguid)) < DDS_RETCODE_OK) { - DDS_ERROR("Unable to retrieve the guid of the reader [%s]\n", dds_strretcode(-rc)); + DDS_ERROR("Unable to retrieve the guid of the reader [%s]", dds_strretcode(-rc)); goto err_get_guid; } - (void)dc_stringify_id(rguid.v, id_str); - /* get topic name */ - if ((topic = dds_get_topic(reader)) < 0) { - DDS_ERROR("Unable to get topic from reader [%s]\n", dds_strretcode(-topic)); - goto err_get_topic; - } - if ((rc = dds_get_name(topic, tpname, sizeof(tpname))) < 0) { - DDS_ERROR("Failed to get topic name [%s]\n", dds_strretcode(-rc)); - goto err_get_name; - } else if (rc > MAX_TOPIC_NAME_SIZE) { - DDS_ERROR("Name for topic '%s...', name too long\n", tpname); - goto err_get_name_size; - } - /* get partitions of the reader */ - if ((rqos = dds_create_qos()) == NULL) { - DDS_ERROR("Failed to allocate reader qos\n"); - goto err_alloc_rqos; - } - if ((rc = dds_get_qos(reader, rqos)) < 0) { - DDS_ERROR("Failed to get topic qos [%s]\n", dds_strretcode(rc)); - goto err_get_qos; - } - if (!dds_qget_partition(rqos, &plen, &partitions)) { - DDS_ERROR("failed to get partitions from qos\n"); - goto err_qget_partition; - } - /* for each partition create a proxy set if it does not exist yet - * and request data for the proxy set (if not done so already) */ - for (i=0; i < plen; i++) { - proxy_set = dc_get_proxy_set(dc, partitions[i], tpname, tidstr.str, true); - assert(proxy_set); - /* Add the reader and rhc to this proxy set. - * We do this BEFORE we send the request, so that we are sure - * that when we receive the response (possibly immediately after - * sending the request) the reader and rhc are present */ - dc_register_reader_to_proxy_set(dc, proxy_set, rguid, reader, rhc); - /* send a request for this proxy set */ - if ((rc = dc_com_request_write(dc->com, rguid, proxy_set->key.partition, proxy_set->key.tpname, proxy_set->key.type_id)) != DDS_RETCODE_OK) { - DDS_ERROR("Failed to publish dc_request for proxy set %s.%s\n", proxy_set->key.partition, proxy_set->key.tpname); - /* We failed to request data for this proxy set. - * We could do several things now, e.g., 1) try again until we succeed, - * 2) notify the application that no historical data could be retrieved, - * or 3) commit suicide because we cannot guarantee eventual consistency. - * For now, I choose for the latter. After all, it is expected that sending - * a request should never fails. */ - abort(); - } + /* Administrate the outstanding request. + * This is used a.o. to correlate reader guids to actual readers. */ + dc_insert_delivery_request(dc, reader, rguid); + /* Publish the quest */ + if ((rc = dc_com_request_write(dc->com, rguid)) != DDS_RETCODE_OK) { + DDS_ERROR("Failed to publish dc_request [%s]", dds_strretcode(-rc)); + /* We failed to request data for this proxy set. + * We could do several things now, e.g., 1) try again until we succeed, + * 2) notify the application that no historical data could be retrieved, + * or 3) commit suicide because we cannot guarantee eventual consistency. + * For now, I choose for the latter. After all, it is expected that sending + * a request should never fail. */ + dc_delete_delivery_request(dc, rguid); + abort(); } - dc_free_partitions(plen, partitions); - dds_delete_qos(rqos); - dds_free_typeinfo(typeinfo); - ddsrt_free(tid); return; -err_qget_partition: -err_get_qos: - dds_delete_qos(rqos); -err_alloc_rqos: -err_get_name_size: -err_get_name: -err_get_topic: err_get_guid: - ddsrt_free(tid); -err_typeid: - dds_free_typeinfo(typeinfo); -err_get_typeinfo: return; } @@ -1828,30 +1977,28 @@ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publicat return; } -/* dispose the request for the proxy set */ -static void dc_dispose_reader_request (struct dc_t *dc, struct proxy_set_t *proxy_set) +/* dispose the delivery request */ +static void dc_dispose_delivery_request (struct dc_t *dc, struct delivery_request_t *dr) { dds_return_t rc; dds_instance_handle_t ih; DurableSupport_request request; + char id_str[37]; - /* create a dummy request containing the key fields to retrieve the instance handle */ - memcpy(request.client, dc->cfg.id, 16); - request.partition = ddsrt_strdup(proxy_set->key.partition); - request.tpname = ddsrt_strdup(proxy_set->key.tpname); + DC_UNUSED_ARG(dr); + /* create a dummy request containing the reader guid that */ + memcpy(request.key.rguid, dr->key.guid.v, 16); if ((ih = dds_lookup_instance(dc->com->wr_request, &request)) == DDS_HANDLE_NIL) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dc_request for proxy set %s.%s not found, unable to dispose\n", request.partition, request.tpname); - goto err_dispose_reader_request; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "no delivery request for reader \"%s\" found, unable to dispose\n", dc_stringify_id(request.key.rguid, id_str)); + goto err_dispose_delivery_request; } if ((rc = dc_com_request_dispose(dc->com, ih)) != DDS_RETCODE_OK) { - DDS_ERROR("failed to dispose dc_request for proxy set %s.%s [%s]\n", request.partition, request.tpname, dds_strretcode(-rc)); - goto err_dispose_reader_request; + DDS_ERROR("failed to dispose delivery request for reader \"%s\" [%s]\n", dc_stringify_id(request.key.rguid, id_str), dds_strretcode(-rc)); + goto err_dispose_delivery_request; } /* LH: todo: use dc_stringify_request, but only print the keys */ - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dispose dc_request {\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\"}\n", dc->cfg.id_str, request.partition, request.tpname); -err_dispose_reader_request: - ddsrt_free(request.partition); - ddsrt_free(request.tpname); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dispose delivery request for reader \"%s\"\n", dc_stringify_id(request.key.rguid, id_str)); +err_dispose_delivery_request: return; } @@ -1913,7 +2060,7 @@ static void default_request_writer_matched_cb (dds_entity_t writer, dds_publicat if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { /* A dc_request reader on a data container has matched with the dc_request writer. * From now on it is allowed to publish requests. - * In case there are any pending requests, we can sent them now */ + * In case there are any delivery requests, we can sent them now */ dc_add_matched_request_reader(dc, ep, ih); } dds_builtintopic_free_endpoint(ep); @@ -1923,40 +2070,42 @@ static void default_request_writer_matched_cb (dds_entity_t writer, dds_publicat } } -/* handle expired pending request and determine the next timeout */ -static void dc_process_pending_request_guard (struct dc_t *dc, dds_time_t *timeout) +/* handle expired delivery request and determine the next timeout */ +static void dc_process_delivery_request_guard (struct dc_t *dc, dds_time_t *timeout) { dds_return_t ret; - struct pending_request_t *pr; + struct delivery_request_t *dr; dds_time_t now = dds_time(); + char dr_str[256]; - ddsrt_mutex_lock(&dc->pending_request_mutex); + ddsrt_mutex_lock(&dc->delivery_request_mutex); do { - pr = ddsrt_fibheap_min(&pending_requests_fd, &dc->pending_requests_fh); - if ((pr == NULL) || (now < pr->exp_time)) { - /* there is no pending request, or the first pending request is not yet expired */ + dr = ddsrt_fibheap_min(&delivery_requests_fd, &dc->delivery_requests_fh); + if ((dr == NULL) || (now < dr->exp_time)) { + /* there is no delivery request, or the first delivery request has not yet expired */ break; } - /* The head is expired. Remove the pending request from the priority queue + /* The head is expired. Remove the delivery request from the priority queue * and dispose it to prevent that a DS reacts to an expired request */ - if ((pr = ddsrt_fibheap_extract_min(&pending_requests_fd, &dc->pending_requests_fh)) != NULL) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "process pending request %" PRIu64 "\n", pr->key.seq); - dc_dispose_reader_request(dc, pr->proxy_set); - cleanup_pending_request(pr); + if ((dr = ddsrt_fibheap_extract_min(&delivery_requests_fd, &dc->delivery_requests_fh)) != NULL) { + (void)dc_stringify_delivery_request(dr_str, sizeof(dr_str), dr); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "process delivery request \"%s\"\n", dr_str); + dc_dispose_delivery_request(dc, dr); + dc_delete_delivery_request(dc, dr->key.guid); } } while (true); /* recalculate the remaining timeout */ - *timeout = (pr == NULL) ? DDS_NEVER : pr->exp_time; - if ((ret = dds_set_guardcondition(dc->com->pending_request_guard, false)) < 0) { - DDS_ERROR("failed to set pending request guard to false [%s]", dds_strretcode(ret)); + *timeout = (dr == NULL) ? DDS_NEVER : dr->exp_time; + if ((ret = dds_set_guardcondition(dc->com->delivery_request_guard, false)) < 0) { + DDS_ERROR("failed to set delivery request guard to false [%s]", dds_strretcode(ret)); } if (*timeout != DDS_NEVER) { dds_duration_t tnext = *timeout - now; int64_t sec = (int64_t)(tnext / DDS_NSECS_IN_SEC); uint32_t usec = (uint32_t)((tnext % DDS_NSECS_IN_SEC) / DDS_NSECS_IN_USEC); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "next pending request timeout at %" PRId64 ".%06" PRIu32 "s\n", sec, usec); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "next delivery request timeout at %" PRId64 ".%06" PRIu32 "s\n", sec, usec); } - ddsrt_mutex_unlock(&dc->pending_request_mutex); + ddsrt_mutex_unlock(&dc->delivery_request_mutex); } static uint32_t recv_handler (void *a) @@ -1978,13 +2127,13 @@ static uint32_t recv_handler (void *a) dc_process_status(dc->com->rd_status, dc); } else if (wsresults[j] == dc->com->rd_response) { dc_process_response(dc->com->rd_response, dc); - } else if (wsresults[j] == dc->com->pending_request_guard) { - dc_process_pending_request_guard(dc, &timeout); + } else if (wsresults[j] == dc->com->delivery_request_guard) { + dc_process_delivery_request_guard(dc, &timeout); } } } else { /* timeout */ - dc_process_pending_request_guard(dc, &timeout); + dc_process_delivery_request_guard(dc, &timeout); } } DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "stop durable client thread\n"); @@ -2038,7 +2187,7 @@ static dds_return_t activate_request_listener (struct dc_t *dc) if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { /* A dc_request reader on a DS has matched with the dc_request writer. * From now on it is allowed to publish requests. - * In case there are any pending requests, we can sent them now */ + * In case there are any delivery requests, we can sent them now */ dc_add_matched_request_reader(dc, ep, rd_ihs[i]); } dds_builtintopic_free_endpoint(ep); @@ -2081,11 +2230,10 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom ddsrt_avl_cinit(&delivery_ctx_td, &dc.delivery_ctxs); ddsrt_avl_cinit(&server_td, &dc.servers); ddsrt_avl_cinit(&matched_request_readers_td, &dc.matched_request_readers); - ddsrt_avl_cinit(&pending_requests_td, &dc.pending_requests); - ddsrt_fibheap_init(&pending_requests_fd, &dc.pending_requests_fh); - ddsrt_avl_cinit(&proxy_set_td, &dc.proxy_sets); - ddsrt_mutex_init(&dc.pending_request_mutex); - ddsrt_cond_init(&dc.pending_request_cond); + ddsrt_avl_cinit(&delivery_requests_td, &dc.delivery_requests); + ddsrt_fibheap_init(&delivery_requests_fd, &dc.delivery_requests_fh); + ddsrt_mutex_init(&dc.delivery_request_mutex); + ddsrt_cond_init(&dc.delivery_request_cond); /* create the quorum listener */ if ((dc.quorum_listener = dds_create_listener(&dc)) == NULL) { DDS_ERROR("failed to create quorum listener\n"); @@ -2117,10 +2265,9 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom err_create_request_listener: dds_delete_listener(dc.quorum_listener); err_create_quorum_listener: - ddsrt_cond_destroy(&dc.pending_request_cond); - ddsrt_mutex_destroy(&dc.pending_request_mutex); - ddsrt_avl_cfree(&proxy_set_td, &dc.proxy_sets, cleanup_proxy_set); - ddsrt_avl_cfree(&pending_requests_td, &dc.pending_requests, cleanup_pending_request); + ddsrt_cond_destroy(&dc.delivery_request_cond); + ddsrt_mutex_destroy(&dc.delivery_request_mutex); + ddsrt_avl_cfree(&delivery_requests_td, &dc.delivery_requests, cleanup_delivery_request); ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); ddsrt_free(dc.cfg.ident); @@ -2159,11 +2306,10 @@ dds_return_t dds_durability_fini (void) dds_delete_listener(dc.quorum_listener); dc_com_free(dc.com); ddsrt_avl_cfree(&delivery_ctx_td, &dc.delivery_ctxs, cleanup_delivery_ctx); - ddsrt_cond_destroy(&dc.pending_request_cond); - ddsrt_mutex_destroy(&dc.pending_request_mutex); - ddsrt_avl_cfree(&proxy_set_td, &dc.proxy_sets, cleanup_proxy_set); + ddsrt_cond_destroy(&dc.delivery_request_cond); + ddsrt_mutex_destroy(&dc.delivery_request_mutex); ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); - ddsrt_avl_cfree(&pending_requests_td, &dc.pending_requests, cleanup_pending_request); + ddsrt_avl_cfree(&delivery_requests_td, &dc.delivery_requests, cleanup_delivery_request); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); ddsrt_free(dc.cfg.ident); } @@ -2175,76 +2321,6 @@ bool dds_durability_is_terminating (void) return (ddsrt_atomic_ld32(&dc.termflag) > 0); } -dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc) -{ - dds_durability_kind_t dkind; - dds_qos_t *qos, *parqos; - dds_return_t rc = DDS_RETCODE_ERROR; - - /* check if the reader is a durable reader from a "real" user application, - * if so, send a request to obtain historical data */ - assert(reader); - qos = dds_create_qos(); - if ((rc = dds_get_qos(reader, qos)) < 0) { - DDS_ERROR("failed to get qos from reader [%s]\n", dds_strretcode(rc)); - goto err_get_qos; - } - if (!dds_qget_durability(qos, &dkind)) { - DDS_ERROR("failed to retrieve durability qos\n"); - goto err_qget_durability; - } - if ((dkind == DDS_DURABILITY_TRANSIENT) || (dkind == DDS_DURABILITY_PERSISTENT)) { - dds_entity_t par; - void *userdata; - size_t size = 0; - - /* Creation of a durable reader must only lead to the publication - * of a dc_request when the reader is a "real" application reader. - * If the reader belongs to a participant that carries user data - * containing the IDENT, then the reader is a data container. - * We don't need to generate dc_requests for data containers */ - if ((par = dds_get_participant(reader)) < 0) { - DDS_ERROR("Unable to retrieve the participant of the reader [%s]\n", dds_strretcode(rc)); - goto err_get_participant; - } - if ((parqos = dds_create_qos()) == NULL) { - DDS_ERROR("Failed to allocate qos\n"); - goto err_alloc_parqos; - } - if ((rc = dds_get_qos(par, parqos)) < 0) { - DDS_ERROR("Failed to get topic qos [%s]", dds_strretcode(rc)); - goto err_get_parqos; - } - if (!dds_qget_userdata(parqos, &userdata, &size)) { - DDS_ERROR("Unable to retrieve the participant's user data for reader\n"); - goto err_qget_userdata; - } - if ((size != strlen(dc.cfg.ident)) || (userdata == NULL) || (strcmp(userdata, dc.cfg.ident) != 0)) { - /* the user data of the participant for this durable reader does - * not contain the ident, so the endpoint is not from a remote DS. - * We can now publish a dc_request for this durable reader. The - * dc_request is published as a transient-local topic. This means - * that a late joining DS will receive the DS as long as the request - * is not yet disposed. */ - dc_create_proxy_sets_for_reader(&dc, reader, rhc); - } - dds_free(userdata); - dds_delete_qos(parqos); - } - dds_delete_qos(qos); - return rc; - -err_qget_userdata: -err_get_parqos: - dds_delete_qos(parqos); -err_alloc_parqos: -err_get_participant: -err_qget_durability: -err_get_qos: - dds_delete_qos(qos); - return rc; -} - /* Returns TRUE if the entity is an application entity, false otherwise */ static bool is_application_entity (struct dc_t *dc, dds_entity_t entity) { @@ -2293,6 +2369,44 @@ static bool is_application_entity (struct dc_t *dc, dds_entity_t entity) return true; } +dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc) +{ + dds_durability_kind_t dkind; + dds_qos_t *qos; + dds_return_t rc = DDS_RETCODE_ERROR; + + /* check if the reader is a durable reader from a "real" user application, + * if so, send a request to obtain historical data */ + assert(reader); + qos = dds_create_qos(); + if ((rc = dds_get_qos(reader, qos)) < 0) { + DDS_ERROR("failed to get qos from reader [%s]\n", dds_strretcode(rc)); + goto err_get_qos; + } + if (!dds_qget_durability(qos, &dkind)) { + DDS_ERROR("failed to retrieve durability qos\n"); + goto err_qget_durability; + } + if ((dkind == DDS_DURABILITY_TRANSIENT) || (dkind == DDS_DURABILITY_PERSISTENT)) { + if (is_application_entity(&dc, reader)) { + /* the user data of the participant for this durable reader does + * not contain the ident, so the endpoint is not from a remote DS. + * We can now publish a dc_request for this durable reader. The + * dc_request is published as a transient-local topic. This means + * that a late joining DS will receive the DS as long as the request + * is not yet disposed. */ + dc_send_request_for_reader(&dc, reader, rhc); + } + } + dds_delete_qos(qos); + return rc; + +err_qget_durability: +err_get_qos: + dds_delete_qos(qos); + return rc; +} + /* check if the writer is a durable application writer, and if so, we need to keep track of the quorum */ dds_return_t dds_durability_new_local_writer (dds_entity_t writer) { diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index 63a895fcf0..6325ac0e3f 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -703,100 +703,94 @@ static const uint32_t DurableSupport_request_ops [] = { /* request */ DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, client), 16u, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, rguid), 16u, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, partition), - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, type_id), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_EXT, offsetof (DurableSupport_request, key), (3u << 16u) + 9u /* request_key */, + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, client), 16u, DDS_OP_ADR | DDS_OP_TYPE_8BY | DDS_OP_FLAG_SGN, offsetof (DurableSupport_request, timeout), DDS_OP_RTS, - - /* key: client */ - DDS_OP_KOF | 1, 1u /* order: 0 */, - - /* key: rguid */ - DDS_OP_KOF | 1, 4u /* order: 1 */, - /* key: partition */ - DDS_OP_KOF | 1, 7u /* order: 2 */, - - /* key: tpname */ - DDS_OP_KOF | 1, 9u /* order: 3 */, + /* request_key */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_key, rguid), 16u, + DDS_OP_RTS, - /* key: type_id */ - DDS_OP_KOF | 1, 11u /* order: 4 */ + /* key: key.rguid */ + DDS_OP_KOF | 2, 1u /* order: 0 */, 1u /* order: 0 */ }; -static const dds_key_descriptor_t DurableSupport_request_keys[5] = +static const dds_key_descriptor_t DurableSupport_request_keys[1] = { - { "client", 16, 0 }, - { "rguid", 18, 1 }, - { "partition", 20, 2 }, - { "tpname", 22, 3 }, - { "type_id", 24, 4 } + { "key.rguid", 15, 0 } }; /* Type Information: - [MINIMAL ab970ab07c061f95f865be523bb0] (#deps: 2) + [MINIMAL 8b9080d97a1a0c3c5aa3da72955b] (#deps: 3) + - [MINIMAL a3976212b3d863bdaaf29cf722d7] - [MINIMAL 43f53a2be35b432cc735e9431a89] - [MINIMAL 84ce9c3d894c1483f859c00d5927] - [COMPLETE ca811b13ce9943d64d1fa75ace5f] (#deps: 2) + [COMPLETE ffa88f3ac66a3c1ea9fb2cc3dcec] (#deps: 3) + - [COMPLETE c4f510554fa6a62cae1437b6364b] - [COMPLETE aca4d5a256d39713924333e85c6d] - [COMPLETE 023df3bd21223779cd1936cef928] */ #define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ - 0xc0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0xab, 0x97, 0x0a, 0xb0, 0x7c, 0x06, 0x1f, 0x95, 0xf8, 0x65, 0xbe, \ - 0x52, 0x3b, 0xb0, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, \ - 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0xca, 0x81, 0x1b, 0x13, 0xce, 0x99, 0x43, 0xd6, 0x4d, 0x1f, 0xa7, \ - 0x5a, 0xce, 0x5f, 0x00, 0x06, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0xf0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x8b, 0x90, 0x80, 0xd9, 0x7a, 0x1a, 0x0c, 0x3c, 0x5a, 0xa3, 0xda, \ + 0x72, 0x95, 0x5b, 0x00, 0x75, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xa3, 0x97, 0x62, 0x12, 0xb3, 0xd8, 0x63, \ + 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, 0x00, 0x35, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, \ + 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xff, 0xa8, 0x8f, \ + 0x3a, 0xc6, 0x6a, 0x3c, 0x1e, 0xa9, 0xfb, 0x2c, 0xc3, 0xdc, 0xec, 0x00, 0xb2, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xc4, 0xf5, 0x10, 0x55, 0x4f, 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, 0x4b, 0x00, \ + 0x60, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ 0x39, 0x00, 0x00, 0x00\ } -#define TYPE_INFO_CDR_SZ_DurableSupport_request 196u +#define TYPE_INFO_CDR_SZ_DurableSupport_request 244u #define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ - 0x0b, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0xab, 0x97, 0x0a, 0xb0, 0x7c, 0x06, 0x1f, \ - 0x95, 0xf8, 0x65, 0xbe, 0x52, 0x3b, 0xb0, 0x00, 0xa1, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x1f, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf1, 0x8b, 0x90, 0x80, 0xd9, 0x7a, 0x1a, 0x0c, \ + 0x3c, 0x5a, 0xa3, 0xda, 0x72, 0x95, 0x5b, 0x00, 0x71, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0xa3, 0x97, 0x62, 0x12, 0xb3, \ + 0xd8, 0x63, 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, 0x3c, 0x6e, 0x0b, 0x8a, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xaf, 0xc4, 0x1d, 0xc3, 0x00, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ - 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ - 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, \ - 0x19, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ - 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ - 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ - 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, \ - 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ - 0xb5, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0xca, 0x81, 0x1b, 0x13, 0xce, 0x99, 0x43, \ - 0xd6, 0x4d, 0x1f, 0xa7, 0x5a, 0xce, 0x5f, 0x00, 0x02, 0x01, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, \ - 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x72, 0x67, 0x75, 0x69, 0x64, 0x00, 0x00, 0x00, \ - 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, \ - 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, \ - 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, \ + 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ + 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0xa3, 0x97, \ + 0x62, 0x12, 0xb3, 0xd8, 0x63, 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, 0x31, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, \ + 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xaf, 0xc4, 0x1d, \ + 0xc3, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ + 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x84, \ + 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x00, 0x00, \ + 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x05, 0x00, 0xd1, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf2, 0xff, 0xa8, 0x8f, \ + 0x3a, 0xc6, 0x6a, 0x3c, 0x1e, 0xa9, 0xfb, 0x2c, 0xc3, 0xdc, 0xec, 0x00, 0xae, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x00, 0x82, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xc4, 0xf5, 0x10, 0x55, 0x4f, \ + 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, 0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, \ 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, \ - 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ + 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xc4, \ + 0xf5, 0x10, 0x55, 0x4f, 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, 0x4b, 0x00, 0x00, 0x00, \ + 0x5c, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x1c, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, \ + 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x72, 0x67, 0x75, 0x69, 0x64, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ @@ -805,21 +799,23 @@ static const dds_key_descriptor_t DurableSupport_request_keys[5] = 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0xf2, 0xca, 0x81, 0x1b, 0x13, 0xce, 0x99, 0x43, 0xd6, 0x4d, 0x1f, 0xa7, \ - 0x5a, 0xce, 0x5f, 0xf1, 0xab, 0x97, 0x0a, 0xb0, 0x7c, 0x06, 0x1f, 0x95, 0xf8, 0x65, 0xbe, 0x52, \ - 0x3b, 0xb0, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ - 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, \ - 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0xf2, 0xff, 0xa8, 0x8f, 0x3a, 0xc6, 0x6a, 0x3c, 0x1e, 0xa9, 0xfb, 0x2c, \ + 0xc3, 0xdc, 0xec, 0xf1, 0x8b, 0x90, 0x80, 0xd9, 0x7a, 0x1a, 0x0c, 0x3c, 0x5a, 0xa3, 0xda, 0x72, \ + 0x95, 0x5b, 0xf2, 0xc4, 0xf5, 0x10, 0x55, 0x4f, 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, \ + 0x4b, 0xf1, 0xa3, 0x97, 0x62, 0x12, 0xb3, 0xd8, 0x63, 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, \ + 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, \ + 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, \ + 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_request 814u +#define TYPE_MAP_CDR_SZ_DurableSupport_request 892u const dds_topic_descriptor_t DurableSupport_request_desc = { .m_size = sizeof (DurableSupport_request), .m_align = dds_alignof (DurableSupport_request), - .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 5u, + .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 1u, .m_typename = "DurableSupport::request", .m_keys = DurableSupport_request_keys, .m_nops = 8, @@ -841,12 +837,15 @@ static const uint32_t DurableSupport_response_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_response_content, _d), 2u, (12u << 16u) + 4u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 9 /* response_set_t */, 1, offsetof (DurableSupport_response_content, _u.set), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 17 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 25 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, DDS_OP_RTS, /* response_set_t */ DDS_OP_DLC, DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_response_set_t, delivery_id), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_ARR, offsetof (DurableSupport_response_set_t, guids), sizeof (DurableSupport_id_t), (8u << 16u) + 4u, + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, 0u, 16u, + DDS_OP_RTS, DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, partition), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, tpname), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, type_id), @@ -864,135 +863,140 @@ static const uint32_t DurableSupport_response_ops [] = static const dds_key_descriptor_t DurableSupport_response_keys[1] = { - { "id", 38, 0 } + { "id", 46, 0 } }; /* Type Information: - [MINIMAL 7172db81541171f4d3215f317121] (#deps: 6) + [MINIMAL afe8255284083dabd3ddf2d54e74] (#deps: 6) - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL adf1bdbb30b9d6975e377ee51fa4] + - [MINIMAL 98ce0230d0ff9c4c40cabb2d52c3] - [MINIMAL 80455e796dd3437163cb532089da] - - [MINIMAL 19656e10c4f1e4cd8e04106c5b0f] + - [MINIMAL e78d987aa9597510bc0942813b1e] - [MINIMAL d8398b259af5a04792e296996c27] - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE eb98abe5dd8d7bfb5b2507da617d] (#deps: 6) + [COMPLETE 96afe9e7626475acdc5483ed4445] (#deps: 6) - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE 5c1f20e6410aad78dfe023066879] + - [COMPLETE 32546bec8365219448f85d5a510d] - [COMPLETE eec1bad6badde73f40ef199fedcc] - - [COMPLETE e4730a78f541604cc1a1a037ef05] + - [COMPLETE 5af9ae0c63928c6db71150e723db] - [COMPLETE 7b005a124ff7bda9c39eb4003556] - [COMPLETE 008875599776c39ce0c1fe897846] */ #define TYPE_INFO_CDR_DurableSupport_response (const unsigned char []){ \ 0x80, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x71, 0x72, 0xdb, 0x81, 0x54, 0x11, 0x71, 0xf4, 0xd3, 0x21, 0x5f, \ - 0x31, 0x71, 0x21, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0xaf, 0xe8, 0x25, 0x52, 0x84, 0x08, 0x3d, 0xab, 0xd3, 0xdd, 0xf2, \ + 0xd5, 0x4e, 0x74, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, 0xb9, 0xd6, 0x97, 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0x00, \ + 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, 0xff, 0x9c, 0x4c, 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0x00, \ 0x7c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x19, 0x65, 0x6e, 0x10, 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, 0x5b, 0x0f, 0x00, \ - 0x77, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ + 0xf1, 0xe7, 0x8d, 0x98, 0x7a, 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, 0x3b, 0x1e, 0x00, \ + 0x9b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0xeb, 0x98, 0xab, 0xe5, 0xdd, 0x8d, 0x7b, 0xfb, 0x5b, 0x25, 0x07, \ - 0xda, 0x61, 0x7d, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x96, 0xaf, 0xe9, 0xe7, 0x62, 0x64, 0x75, 0xac, 0xdc, 0x54, 0x83, \ + 0xed, 0x44, 0x45, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, 0x78, 0xdf, 0xe0, 0x23, 0x06, 0x68, 0x79, 0x00, \ + 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, 0x65, 0x21, 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0x00, \ 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, \ 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, 0x60, 0x4c, 0xc1, 0xa1, 0xa0, 0x37, 0xef, 0x05, 0x00, \ - 0xd8, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, \ + 0xf2, 0x5a, 0xf9, 0xae, 0x0c, 0x63, 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, 0xe7, 0x23, 0xdb, 0x00, \ + 0x04, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, \ 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ 0x57, 0x00, 0x00, 0x00\ } #define TYPE_INFO_CDR_SZ_DurableSupport_response 388u #define TYPE_MAP_CDR_DurableSupport_response (const unsigned char []){ \ - 0x30, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0x71, 0x72, 0xdb, 0x81, 0x54, 0x11, 0x71, \ - 0xf4, 0xd3, 0x21, 0x5f, 0x31, 0x71, 0x21, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x54, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0xaf, 0xe8, 0x25, 0x52, 0x84, 0x08, 0x3d, \ + 0xab, 0xd3, 0xdd, 0xf2, 0xd5, 0x4e, 0x74, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, \ - 0xb9, 0xd6, 0x97, 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, \ + 0xff, 0x9c, 0x4c, 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, \ - 0xb9, 0xd6, 0x97, 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, \ + 0xff, 0x9c, 0x4c, 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ 0x54, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x19, 0x65, 0x6e, 0x10, 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, 0x5b, \ - 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ + 0x01, 0x00, 0xf1, 0xe7, 0x8d, 0x98, 0x7a, 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, 0x3b, \ + 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x19, 0x65, 0x6e, 0x10, \ - 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, 0x5b, 0x0f, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0xe7, 0x8d, 0x98, 0x7a, \ + 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, 0x3b, 0x1e, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x7c, 0x4b, 0x99, \ - 0xfe, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x7e, 0x75, 0xc0, 0xed, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x94, 0x75, 0x7c, 0xae, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, \ - 0x58, 0x68, 0xd6, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ - 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, \ - 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \ - 0xee, 0x26, 0x90, 0x8b, 0x9b, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0xeb, 0x98, 0xab, \ - 0xe5, 0xdd, 0x8d, 0x7b, 0xfb, 0x5b, 0x25, 0x07, 0xda, 0x61, 0x7d, 0x00, 0x83, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, 0x78, 0xdf, \ - 0xe0, 0x23, 0x06, 0x68, 0x79, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, \ - 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, \ - 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x10, 0x02, 0x00, 0x00, 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, 0x78, 0xdf, 0xe0, 0x23, \ - 0x06, 0x68, 0x79, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ - 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, \ - 0x11, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, \ - 0xcc, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, 0x60, 0x4c, 0xc1, \ - 0xa1, 0xa0, 0x37, 0xef, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, \ - 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, \ - 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, \ - 0x60, 0x4c, 0xc1, 0xa1, 0xa0, 0x37, 0xef, 0x05, 0xd4, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ - 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0xfe, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, \ + 0x01, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, \ + 0x1a, 0x89, 0x0d, 0x36, 0x32, 0x3f, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, 0x0b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, \ + 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, \ + 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, \ + 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0xc7, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0xf2, 0x96, 0xaf, 0xe9, 0xe7, 0x62, 0x64, 0x75, 0xac, 0xdc, 0x54, 0x83, 0xed, 0x44, 0x45, 0x00, \ + 0x83, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, \ + 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, \ + 0x65, 0x21, 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ + 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, 0x65, 0x21, \ + 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, \ + 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, \ - 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x7b, \ - 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, \ + 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ + 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5a, 0xf9, 0xae, 0x0c, 0x63, \ + 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, 0xe7, 0x23, 0xdb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, \ + 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, \ + 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, \ + 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, \ + 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x5a, 0xf9, \ + 0xae, 0x0c, 0x63, 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, 0xe7, 0x23, 0xdb, 0x00, 0x01, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, \ + 0xcc, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, \ + 0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, \ + 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ + 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x67, 0x75, 0x69, 0x64, \ + 0x73, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, \ - 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, \ + 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, \ 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1005,22 +1009,22 @@ static const dds_key_descriptor_t DurableSupport_response_keys[1] = 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, \ 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, \ - 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0xeb, 0x98, 0xab, \ - 0xe5, 0xdd, 0x8d, 0x7b, 0xfb, 0x5b, 0x25, 0x07, 0xda, 0x61, 0x7d, 0xf1, 0x71, 0x72, 0xdb, 0x81, \ - 0x54, 0x11, 0x71, 0xf4, 0xd3, 0x21, 0x5f, 0x31, 0x71, 0x21, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0x96, 0xaf, 0xe9, \ + 0xe7, 0x62, 0x64, 0x75, 0xac, 0xdc, 0x54, 0x83, 0xed, 0x44, 0x45, 0xf1, 0xaf, 0xe8, 0x25, 0x52, \ + 0x84, 0x08, 0x3d, 0xab, 0xd3, 0xdd, 0xf2, 0xd5, 0x4e, 0x74, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, \ - 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, \ - 0x78, 0xdf, 0xe0, 0x23, 0x06, 0x68, 0x79, 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, 0xb9, 0xd6, 0x97, \ - 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ + 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, 0x65, 0x21, \ + 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, 0xff, 0x9c, 0x4c, \ + 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, \ - 0x53, 0x20, 0x89, 0xda, 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, 0x60, 0x4c, 0xc1, 0xa1, 0xa0, \ - 0x37, 0xef, 0x05, 0xf1, 0x19, 0x65, 0x6e, 0x10, 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, \ - 0x5b, 0x0f, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, \ + 0x53, 0x20, 0x89, 0xda, 0xf2, 0x5a, 0xf9, 0xae, 0x0c, 0x63, 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, \ + 0xe7, 0x23, 0xdb, 0xf1, 0xe7, 0x8d, 0x98, 0x7a, 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, \ + 0x3b, 0x1e, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, \ 0x56, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, \ 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0xf1, \ 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_response 1710u +#define TYPE_MAP_CDR_SZ_DurableSupport_response 1790u const dds_topic_descriptor_t DurableSupport_response_desc = { .m_size = sizeof (DurableSupport_response), @@ -1029,10 +1033,9 @@ const dds_topic_descriptor_t DurableSupport_response_desc = .m_nkeys = 1u, .m_typename = "DurableSupport::response", .m_keys = DurableSupport_response_keys, - .m_nops = 19, + .m_nops = 22, .m_ops = DurableSupport_response_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_response, .sz = TYPE_INFO_CDR_SZ_DurableSupport_response }, .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_response, .sz = TYPE_MAP_CDR_SZ_DurableSupport_response } }; - From ff640ac50877a6d2dcaebce12dae0353934be027 Mon Sep 17 00:00:00 2001 From: Splinter1984 Date: Fri, 26 Apr 2024 10:22:07 +0200 Subject: [PATCH 086/207] sysdef parser `b64` decoding support --- src/core/ddsc/src/dds__sysdef_parser.h | 2 +- src/core/ddsc/src/dds_sysdef_parser.c | 42 ++++++++++++++--- src/core/ddsc/tests/qos_provider.c | 62 +++++++++++++++++++++----- 3 files changed, 90 insertions(+), 16 deletions(-) diff --git a/src/core/ddsc/src/dds__sysdef_parser.h b/src/core/ddsc/src/dds__sysdef_parser.h index f999767e85..0c5d74e009 100644 --- a/src/core/ddsc/src/dds__sysdef_parser.h +++ b/src/core/ddsc/src/dds__sysdef_parser.h @@ -10,8 +10,8 @@ #ifndef DDS_SYSDEF_PARSER_H #define DDS_SYSDEF_PARSER_H -#include "dds/dds.h" #include "dds/ddsrt/log.h" +#include "dds/ddsrt/retcode.h" #if defined (__cplusplus) extern "C" { diff --git a/src/core/ddsc/src/dds_sysdef_parser.c b/src/core/ddsc/src/dds_sysdef_parser.c index 63c5150d87..323c664d6a 100644 --- a/src/core/ddsc/src/dds_sysdef_parser.c +++ b/src/core/ddsc/src/dds_sysdef_parser.c @@ -11,6 +11,7 @@ #include #include +#include "dds/ddsrt/bswap.h" #include "dds/ddsrt/heap.h" #include "dds/ddsrt/string.h" #include "dds/ddsrt/strtol.h" @@ -18,7 +19,6 @@ #include "dds/ddsrt/xmlparser.h" #include "dds/ddsrt/sockets.h" #include "dds/ddsi/ddsi_unused.h" -#include "dds/ddsi/ddsi_domaingv.h" #include "dds__sysdef_model.h" #include "dds__sysdef_parser.h" @@ -1601,6 +1601,38 @@ static int proc_elem_close (void *varg, UNUSED_ARG (uintptr_t eleminfo), UNUSED_ return ret; } +static const unsigned char base64_dtable[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, + 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; + +static uint32_t b64_decode (const unsigned char *text, const uint32_t sz, unsigned char **buff) +{ + unsigned char *padd = (unsigned char *) strchr((char*)text, '='); + uint32_t buff_len = (padd != NULL? (uint32_t)(padd-text): sz) * 3U/4U; + *buff = (unsigned char *) ddsrt_malloc(buff_len); + (void) memset (*buff, 0, buff_len); + + for (size_t i = 0, j = 0; i < sz && j < buff_len; i+=4, j+=3) + { + unsigned char chunk[3] = {0x00, 0x00, 0x00}; + uint32_t tmp = (uint32_t)(base64_dtable[text[i]] << 0x06U) | base64_dtable[text[i+1]]; + uint32_t safe = tmp & 0x0FU; + chunk[0] = (unsigned char)(tmp >> 0x04U); + tmp = (safe << 0x0CU) | ((uint32_t)(base64_dtable[text[i+2]] << 0x06U) | base64_dtable[text[i+3]]); + chunk[2] = (unsigned char)(tmp & 0xFFU); + chunk[1] = (unsigned char)(tmp >> 0x08U); + size_t cp_sz = (buff_len - j) < 3? buff_len - j: 3; + (void) memcpy(*buff+j, chunk, cp_sz); + } + + return buff_len; +} + #define QOS_PARAM_SET_NUMERIC_UNLIMITED(policy, param, param_field, type) \ static int set_ ## policy ## _ ## param (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_ ## policy *qp, const char *value, int line) \ { \ @@ -1656,10 +1688,10 @@ static int proc_elem_close (void *varg, UNUSED_ARG (uintptr_t eleminfo), UNUSED_ static int set_ ## policy ## _ ## param (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_ ## policy *qp, const char *value, int line) \ { \ (void) pstate; (void) line; \ - /* FIXME: base 64 decode */ \ - qp->values.param_data_field = ddsrt_memdup (value, strlen (value)); \ - qp->values.param_length_field = (uint32_t) strlen (value); \ - return SD_PARSE_RESULT_OK; \ + int ret = SD_PARSE_RESULT_OK; \ + uint32_t buff_sz = b64_decode((const unsigned char *)value, (uint32_t)strlen(value), &qp->values.param_data_field); \ + qp->values.param_length_field = buff_sz; \ + return ret; \ } static int set_DESTINATIONORDER_KIND (struct parse_sysdef_state * const pstate, struct dds_sysdef_QOS_POLICY_DESTINATIONORDER *qp, const char *value, int line) diff --git a/src/core/ddsc/tests/qos_provider.c b/src/core/ddsc/tests/qos_provider.c index edf261e699..848d6539b9 100644 --- a/src/core/ddsc/tests/qos_provider.c +++ b/src/core/ddsc/tests/qos_provider.c @@ -375,6 +375,33 @@ typedef struct sysdef_qos_conf enum duration_unit reader_data_lifecycle_disposed_unit; } sysdef_qos_conf_t; +static const unsigned char base64_etable[64] = { + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U', + 'V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p', + 'q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' +}; + +static uint32_t b64_encode (const unsigned char *text, const uint32_t sz, unsigned char **buff) +{ + uint32_t act_len = (sz * 4U/3U); + uint32_t buff_len = (act_len % 4U)? ((act_len / 4U + 1U)*4U): act_len; + *buff = (unsigned char *) ddsrt_malloc(buff_len); + (void) memset (*buff, '=', buff_len); + + for (size_t i = 0, j = 0; i < buff_len && j < sz; i+=4, j+=3) + { + unsigned char chunk[4] = {0x00, 0x00, 0x00, 0x00}; + chunk[0] = base64_etable[(text[j] >> 0x02U)]; + chunk[2] = base64_etable[((text[j+1] & 0x0FU) << 0x02U) | (text[j+2] & 0xC0U) >> 0x06U]; + chunk[1] = base64_etable[((text[j] & 0x03U) << 0x04U) | (text[j+1] >> 0x04U)]; + chunk[3] = base64_etable[text[j+2] & 0x3FU]; + size_t cp_sz = (sz - j) < 3? (sz - j) + 1: 4U; + (void) memcpy(*(buff)+i, chunk, cp_sz); + } + + return buff_len; +} + #define QOS_FORMAT " " #define CHECK_RET_OK(ret) \ if (ret < 0) goto fail; @@ -510,15 +537,20 @@ static inline dds_return_t qos_to_conf(dds_qos_t *qos, const sysdef_qos_conf_t * { if (qos->group_data.length > 0) { + unsigned char *data_buff; + size_t len = b64_encode(qos->group_data.value, qos->group_data.length, &data_buff); + char *data = ddsrt_strdup(""); - for (uint32_t i = 0; i < qos->group_data.length; i++) { + for (uint32_t i = 0; i < len; i++) { char *tmp = data; - ret = ddsrt_asprintf(&data, "%s%c", data, qos->group_data.value[i]); + ret = ddsrt_asprintf(&data, "%s%c", data, data_buff[i]); ddsrt_free(tmp); CHECK_RET_OK(ret); } + char *group_data; ret = ddsrt_asprintf(&group_data, QOS_POLICY_GOUPDATA_FMT, data); + ddsrt_free(data_buff); ddsrt_free(data); CHECK_RET_OK(ret); char *tmp = sysdef_qos; @@ -814,15 +846,20 @@ static inline dds_return_t qos_to_conf(dds_qos_t *qos, const sysdef_qos_conf_t * { if (qos->topic_data.length > 0) { + unsigned char *data_buff; + size_t len = b64_encode(qos->topic_data.value, qos->topic_data.length, &data_buff); + char *data = ddsrt_strdup(""); - for (uint32_t i = 0; i < qos->topic_data.length; i++) { + for (uint32_t i = 0; i < len; i++) { char *tmp = data; - ret = ddsrt_asprintf(&data, "%s%c", data, qos->topic_data.value[i]); + ret = ddsrt_asprintf(&data, "%s%c", data, data_buff[i]); ddsrt_free(tmp); CHECK_RET_OK(ret); } + char *topic_data; ret = ddsrt_asprintf(&topic_data, QOS_POLICY_TOPICDATA_FMT, data); + ddsrt_free(data_buff); ddsrt_free(data); CHECK_RET_OK(ret); char *tmp = sysdef_qos; @@ -849,15 +886,20 @@ static inline dds_return_t qos_to_conf(dds_qos_t *qos, const sysdef_qos_conf_t * { if (qos->user_data.length > 0) { + unsigned char *data_buff; + size_t len = b64_encode(qos->user_data.value, qos->user_data.length, &data_buff); + char *data = ddsrt_strdup(""); - for (uint32_t i = 0; i < qos->user_data.length; i++) { + for (uint32_t i = 0; i < len; i++) { char *tmp = data; - ret = ddsrt_asprintf(&data, "%s%c", data, qos->user_data.value[i]); + ret = ddsrt_asprintf(&data, "%s%c", data, data_buff[i]); ddsrt_free(tmp); CHECK_RET_OK(ret); } + char *user_data; ret = ddsrt_asprintf(&user_data, QOS_POLICY_USERDATA_FMT, data); + ddsrt_free(data_buff); ddsrt_free(data); CHECK_RET_OK(ret); char *tmp = sysdef_qos; @@ -1056,7 +1098,7 @@ CU_Theory((dds_qos_kind_t kind, sysdef_qos_conf_t dur_conf), qos_provider, get_q #define RND_CHAR4 (char[]){RND_CHAR, RND_CHAR, RND_CHAR, '\0'} #define RND_CHAR3x4 (char *[]){RND_CHAR4, RND_CHAR4, RND_CHAR4} -#define Q_DATA4(kind) .kind##_data={.value=RND_UCHAR3,.length=3}, +#define Q_DATA3(kind) .kind##_data={.value=RND_UCHAR3,.length=3}, #define Q_DURABILITY(knd) .durability={.kind=knd}, #define Q_DEADLINE(tm) .deadline={.deadline=tm}, #define Q_LATENCYBUDGET(tm) .latency_budget={.duration=tm}, @@ -1090,14 +1132,14 @@ CU_Theory((dds_qos_kind_t kind, sysdef_qos_conf_t dur_conf), qos_provider, get_q #define QOS_ALL_BASE { \ QOS_ALL_PRESENT \ - Q_DATA4(topic)Q_DURABILITY(DDS_DURABILITY_VOLATILE) \ + Q_DATA3(topic)Q_DURABILITY(DDS_DURABILITY_VOLATILE) \ Q_DEADLINE(DDS_SECS(1))Q_LATENCYBUDGET(DDS_SECS(1)) \ Q_OWNERSHIP(DDS_OWNERSHIP_EXCLUSIVE)Q_LIVELINESS(DDS_LIVELINESS_AUTOMATIC,DDS_INFINITY) \ Q_RELIABILITY(DDS_RELIABILITY_RELIABLE, DDS_SECS(1))Q_TRANSPORTPRIO(1000) \ Q_LIFESPAN(DDS_SECS(1))Q_DESTINATIONORDER(DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP) \ Q_HISTORY(DDS_HISTORY_KEEP_LAST,1)Q_RESOURCELIMITS(1,1,1) \ - Q_DATA4(user)Q_DATA3x4(partition) \ - Q_PRESENATION(DDS_PRESENTATION_TOPIC,1,1)Q_DATA4(group) \ + Q_DATA3(user)Q_DATA3x4(partition) \ + Q_PRESENATION(DDS_PRESENTATION_TOPIC,1,1)Q_DATA3(group) \ Q_TIMEBASEDFILTER(DDS_SECS(1))Q_READERLIFECYCLE(DDS_SECS(1), DDS_SECS(1)) \ Q_OWNERSHIPSTRENGTH(100)Q_WRITERLIFECYCLE(1) \ Q_DURABILITYSERVICE(DDS_SECS(1),DDS_HISTORY_KEEP_ALL,-1,1,1,1) \ From ea68c1909663044dba921592d8d40a620878d8ae Mon Sep 17 00:00:00 2001 From: Splinter1984 Date: Fri, 26 Apr 2024 12:56:09 +0200 Subject: [PATCH 087/207] qos_provider history_kind validation remove --- src/core/ddsc/src/dds_sysdef_validation.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/core/ddsc/src/dds_sysdef_validation.c b/src/core/ddsc/src/dds_sysdef_validation.c index 604cee088a..b8c058bd03 100644 --- a/src/core/ddsc/src/dds_sysdef_validation.c +++ b/src/core/ddsc/src/dds_sysdef_validation.c @@ -47,15 +47,6 @@ static int is_wildcard_partition (const char *str) static dds_return_t validate_qos (dds_qos_t *qos, const char *qos_location) { - // History - dds_history_kind_t history_kind; - int32_t history_depth; - if (dds_qget_history (qos, &history_kind, &history_depth) && (history_kind != DDS_HISTORY_KEEP_LAST || history_depth < 0)) - { - SYSDEF_ERROR ("Unsupported history kind or depth (%s)\n", qos_location); - goto failed; - } - // Partition uint32_t n_partitions; char **partitions; From 24c9938310ca44397c36a1e65613dc5971a99513 Mon Sep 17 00:00:00 2001 From: Splinter1984 Date: Fri, 3 May 2024 12:38:57 +0200 Subject: [PATCH 088/207] history qos sysdef_parser: ignore `depth` elem when kind is `ALL` --- src/core/ddsc/src/dds_sysdef_parser.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/core/ddsc/src/dds_sysdef_parser.c b/src/core/ddsc/src/dds_sysdef_parser.c index 323c664d6a..bbc029f25a 100644 --- a/src/core/ddsc/src/dds_sysdef_parser.c +++ b/src/core/ddsc/src/dds_sysdef_parser.c @@ -1435,18 +1435,26 @@ static int proc_elem_close (void *varg, UNUSED_ARG (uintptr_t eleminfo), UNUSED_ case ELEMENT_KIND_QOS_POLICY_DURABILITY: ELEM_CLOSE_QOS_POLICY(DURABILITY, "Durability"); break; - case ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE: + case ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE: { + struct dds_sysdef_QOS_POLICY_DURABILITYSERVICE *tmp_qp = (struct dds_sysdef_QOS_POLICY_DURABILITYSERVICE *) pstate->current; + if ((tmp_qp->populated & QOS_POLICY_DURABILITYSERVICE_PARAM_HISTORY_KIND) && tmp_qp->values.history.kind == DDS_HISTORY_KEEP_ALL) + tmp_qp->populated |= QOS_POLICY_DURABILITYSERVICE_PARAM_HISTORY_DEPTH; ELEM_CLOSE_QOS_POLICY(DURABILITYSERVICE, "Durability Service"); break; + } case ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_SERVICE_CLEANUP_DELAY: ELEM_CLOSE_QOS_DURATION_PROPERTY(DURABILITYSERVICE, SERVICE_CLEANUP_DELAY, service_cleanup_delay); break; case ELEMENT_KIND_QOS_POLICY_GROUPDATA: ELEM_CLOSE_QOS_POLICY(GROUPDATA, "Group Data"); break; - case ELEMENT_KIND_QOS_POLICY_HISTORY: + case ELEMENT_KIND_QOS_POLICY_HISTORY: { + struct dds_sysdef_QOS_POLICY_HISTORY *tmp_qp = (struct dds_sysdef_QOS_POLICY_HISTORY *) pstate->current; + if ((tmp_qp->populated & QOS_POLICY_HISTORY_PARAM_KIND) && tmp_qp->values.kind == DDS_HISTORY_KEEP_ALL) + tmp_qp->populated |= QOS_POLICY_HISTORY_PARAM_DEPTH; ELEM_CLOSE_QOS_POLICY(HISTORY, "History"); break; + } case ELEMENT_KIND_QOS_POLICY_LATENCYBUDGET: ELEM_CLOSE_QOS_POLICY(LATENCYBUDGET, "Latency Budget"); break; @@ -1990,9 +1998,10 @@ static int proc_elem_data (void *varg, UNUSED_ARG (uintptr_t eleminfo), const ch case ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_HISTORY_KIND: QOS_PARAM_DATA (DURABILITYSERVICE, HISTORY_KIND); break; - case ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_HISTORY_DEPTH: + case ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_HISTORY_DEPTH:{ QOS_PARAM_DATA (DURABILITYSERVICE, HISTORY_DEPTH); break; + } case ELEMENT_KIND_QOS_POLICY_DURABILITYSERVICE_RESOURCE_LIMIT_MAX_SAMPLES: QOS_PARAM_DATA (DURABILITYSERVICE, RESOURCE_LIMIT_MAX_SAMPLES); break; @@ -2011,9 +2020,10 @@ static int proc_elem_data (void *varg, UNUSED_ARG (uintptr_t eleminfo), const ch case ELEMENT_KIND_QOS_POLICY_HISTORY_KIND: QOS_PARAM_DATA (HISTORY, KIND); break; - case ELEMENT_KIND_QOS_POLICY_HISTORY_DEPTH: + case ELEMENT_KIND_QOS_POLICY_HISTORY_DEPTH: { QOS_PARAM_DATA (HISTORY, DEPTH); break; + } case ELEMENT_KIND_QOS_POLICY_LIVELINESS_KIND: QOS_PARAM_DATA (LIVELINESS, KIND); break; From 2caad2d8e71bf59e242c9c0bf4b04a877df54b1f Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 14 May 2024 11:04:47 +0200 Subject: [PATCH 089/207] Add missing ddsrt_mutex_lock in gcreq_queue_step This fixes unlocked access and unlocking a non-locked mutex when the current head of the GC queue is to be postponed. Note that the "step" function is currently only used in a fuzzer and that this case cannot occur in a single-threaded processes. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_gc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ddsi/src/ddsi_gc.c b/src/core/ddsi/src/ddsi_gc.c index b8822f2ebf..81f53a8a0b 100644 --- a/src/core/ddsi/src/ddsi_gc.c +++ b/src/core/ddsi/src/ddsi_gc.c @@ -112,7 +112,8 @@ bool ddsi_gcreq_queue_step (struct ddsi_gcreq_queue *q) { /* Give up immediately instead of waiting: this exists to make less-threaded (test/fuzzing) code possible. (I don't think this case can occur in a single - threaded process, but it might if a some threads exist.) */ + threaded process, but it might if some threads exist.) */ + ddsrt_mutex_lock (&q->lock); break; } else From 2f162442f02c6f3c59aab7d4ec34d1284a310fb3 Mon Sep 17 00:00:00 2001 From: Michel van den Hoek Date: Wed, 15 May 2024 17:33:48 +0200 Subject: [PATCH 090/207] Resolve build-time circular dependencies by making the durability client a plugin. Signed-off-by: Michel van den Hoek --- src/CMakeLists.txt | 7 +- src/core/CMakeLists.txt | 7 +- src/core/ddsc/CMakeLists.txt | 1 + src/core/ddsc/src/dds__types.h | 2 + src/core/ddsc/src/dds_domain.c | 5 + src/core/ddsc/src/dds_durability.c | 70 ++ src/core/ddsc/src/dds_participant.c | 11 +- src/core/ddsc/src/dds_reader.c | 7 +- src/core/ddsc/src/dds_write.c | 12 +- src/core/ddsc/src/dds_writer.c | 12 +- src/core/xtests/symbol_export/CMakeLists.txt | 3 +- src/durability/CMakeLists.txt | 45 +- .../include/dds/durability/dds_durability.h | 42 - .../dds/durability/dds_durability_private.h | 27 + .../dds/durability/dds_durability_public.h | 41 + .../include/dds/durability/durablesupport.h | 390 ------ src/durability/src/dds_durability.c | 51 +- src/durability/src/durablesupport.c | 1041 ----------------- src/durability/src/durablesupport.idl | 71 ++ 19 files changed, 292 insertions(+), 1553 deletions(-) create mode 100644 src/core/ddsc/src/dds_durability.c delete mode 100644 src/durability/include/dds/durability/dds_durability.h create mode 100644 src/durability/include/dds/durability/dds_durability_private.h create mode 100644 src/durability/include/dds/durability/dds_durability_public.h delete mode 100644 src/durability/include/dds/durability/durablesupport.h delete mode 100644 src/durability/src/durablesupport.c create mode 100644 src/durability/src/durablesupport.idl diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cdbe359712..8becec4768 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -110,10 +110,6 @@ if(ENABLE_ICEORYX) endif() endif() -if(ENABLE_DURABILITY) - message(STATUS "Building with Durable support") -endif() - if(BUILD_TESTING) add_subdirectory(ucunit) endif() @@ -126,7 +122,8 @@ add_subdirectory(security) if(ENABLE_ICEORYX) add_subdirectory(psmx_iox) endif() +add_subdirectory(core) if(ENABLE_DURABILITY) + message(STATUS "Building with Durable support") add_subdirectory(durability) endif() -add_subdirectory(core) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 681deac517..339097b095 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -58,10 +58,6 @@ if(ENABLE_SECURITY) $>) endif() -if(ENABLE_DURABILITY) - target_link_libraries(ddsc PRIVATE "$") -endif() - include(cdr/CMakeLists.txt) include(ddsi/CMakeLists.txt) include(ddsc/CMakeLists.txt) @@ -93,7 +89,8 @@ target_compile_definitions( $>) target_include_directories( ddsc PUBLIC - $>) + $> + $) # SOVERSION should increase on incompatible ABI change set_target_properties(ddsc PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) diff --git a/src/core/ddsc/CMakeLists.txt b/src/core/ddsc/CMakeLists.txt index dd21a6772d..9e0fb244e5 100644 --- a/src/core/ddsc/CMakeLists.txt +++ b/src/core/ddsc/CMakeLists.txt @@ -46,6 +46,7 @@ prepend(srcs_ddsc "${CMAKE_CURRENT_LIST_DIR}/src/" dds_loaned_sample.c dds_heap_loan.c dds_psmx.c + dds_durability.c ) if(ENABLE_TYPELIB) diff --git a/src/core/ddsc/src/dds__types.h b/src/core/ddsc/src/dds__types.h index 9048246181..f42d7d53a5 100644 --- a/src/core/ddsc/src/dds__types.h +++ b/src/core/ddsc/src/dds__types.h @@ -24,6 +24,7 @@ #include "dds/ddsrt/avl.h" #include "dds/ddsi/ddsi_builtin_topic_if.h" #include "dds/ddsc/dds_psmx.h" +#include "dds/durability/dds_durability_public.h" #include "dds__handles.h" #include "dds__loaned_sample.h" @@ -306,6 +307,7 @@ typedef struct dds_domain { struct dds_serdatapool *serpool; struct dds_psmx_set psmx_instances; + dds_durability_t dc; // Durability client } dds_domain; typedef struct dds_subscriber { diff --git a/src/core/ddsc/src/dds_domain.c b/src/core/ddsc/src/dds_domain.c index d2612033d7..f0a7eec123 100644 --- a/src/core/ddsc/src/dds_domain.c +++ b/src/core/ddsc/src/dds_domain.c @@ -128,6 +128,9 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i if ((ret = dds_pubsub_message_exchange_init (&domain->gv, domain)) != DDS_RETCODE_OK) goto fail_psmx_init; + if ((ret = dds_durability_load (&domain->dc, &domain->gv)) != DDS_RETCODE_OK) + goto fail_durability_init; + struct ddsi_psmx_instance_locators psmx_locators; psmx_locators.length = domain->psmx_instances.length; psmx_locators.instances = dds_alloc (domain->psmx_instances.length * sizeof (*psmx_locators.instances)); @@ -207,6 +210,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i domain->psmx_instances.instances[i]->ops.deinit(domain->psmx_instances.instances[i]); domain->psmx_instances.instances[i] = NULL; } +fail_durability_init: fail_psmx_init: fail_ddsi_config: if (domain->cfgst) @@ -337,6 +341,7 @@ static dds_return_t dds_domain_free (dds_entity *vdomain) ddsi_fini (&domain->gv); + dds_durability_unload (&domain->dc); (void) dds_pubsub_message_exchange_fini (domain); dds_serdatapool_free (domain->serpool); diff --git a/src/core/ddsc/src/dds_durability.c b/src/core/ddsc/src/dds_durability.c new file mode 100644 index 0000000000..4b1f9a877e --- /dev/null +++ b/src/core/ddsc/src/dds_durability.c @@ -0,0 +1,70 @@ +/* + * Copyright(c) 2006 to 2019 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ + +#include "dds/durability/dds_durability_public.h" +#include "dds/ddsi/ddsi_log.h" +#include + +void dds_durability_fini (dds_durability_t* dc) +{ +#ifdef DDS_HAS_DURABILITY + /* + In the cleanup phase, the durability client's participant will always be the last remaining participant on the domain. + Thus if the domain is implicit, it will trigger deletion of the domain, which in turn unloads the durability plugin. + + So if the participant were to be deleted from inside the plugin, it would result in a fatal error when + the program tries to return (as it unwinds the call stack) to the plugin function that called `dds_delete()` on the participant. + + Therefore, in order to safely delete the participant of the durability client, + its handle needs to be smuggled out so it can be deleted by a function that isn't part of the plugin itself. + */ + assert(dc->_dds_durability_fini); + dds_entity_t pp = dc->_dds_durability_fini(); + if ( pp != 0 ) { + dds_delete(pp); + } +#endif +} + +dds_return_t dds_durability_load (dds_durability_t* dc, const struct ddsi_domaingv* gv) +{ + memset(dc, 0x0, sizeof(dds_durability_t)); +#ifdef DDS_HAS_DURABILITY + dds_return_t (*creator)(dds_durability_t* dc); + ddsrt_dynlib_t handle = NULL; + dds_return_t ret; + if ((ret = ddsrt_dlopen("durability", true, &handle)) != DDS_RETCODE_OK) { + char buf[256]; + ddsrt_dlerror(buf, sizeof(buf)); + GVERROR("dlopen: %s\n", buf); + return ret; + } + if ((ret = ddsrt_dlsym(handle, "dds_durability_creator", (void**)&creator)) != DDS_RETCODE_OK) { + char buf[256]; + ddsrt_dlerror(buf, sizeof(buf)); + GVERROR("dlsym: %s\n", buf); + (void)ddsrt_dlclose(handle); + return ret; + } + creator(dc); + dc->lib_handle = handle; +#endif + return DDS_RETCODE_OK; +} + +void dds_durability_unload (dds_durability_t* dc) +{ +#ifdef DDS_HAS_DURABILITY + assert(dc->lib_handle); + (void)ddsrt_dlclose(dc->lib_handle); +#endif +} diff --git a/src/core/ddsc/src/dds_participant.c b/src/core/ddsc/src/dds_participant.c index e5aabf8b91..7c3675a6af 100644 --- a/src/core/ddsc/src/dds_participant.c +++ b/src/core/ddsc/src/dds_participant.c @@ -27,10 +27,6 @@ #include "dds__builtin.h" #include "dds__qos.h" -#ifdef DDS_HAS_DURABILITY -#include "dds/durability/dds_durability.h" -#endif - DECL_ENTITY_LOCK_UNLOCK (dds_participant) #define DDS_PARTICIPANT_STATUS_MASK (0u) @@ -62,9 +58,7 @@ static dds_return_t dds_participant_delete (dds_entity *e) DDS_CERROR (&e->m_domain->gv.logconfig, "dds_participant_delete: internal error %"PRId32"\n", ret); ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); -#ifdef DDS_HAS_DURABILITY - (void)dds_durability_fini(); -#endif + dds_durability_fini(&e->m_domain->dc); /* todo It seems incorrect that dds_participant_delete() * always returns DDS_RETCODE_OK, even if an error has @@ -179,8 +173,9 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ dds_entity_unpin_and_drop_ref (&dds_global.m_entity); #ifdef DDS_HAS_DURABILITY + assert(dom->dc.dds_durability_init); if (ret > 0) { - (void)dds_durability_init (domain, &dom->gv); + (void)dom->dc.dds_durability_init (domain, &dom->gv); } #endif diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index 61e88f8484..713af1f292 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -51,10 +51,6 @@ #include "dds/ddsi/ddsi_tkmap.h" #endif -#ifdef DDS_HAS_DURABILITY -#include "dds/durability/dds_durability.h" -#endif - DECL_ENTITY_LOCK_UNLOCK (dds_reader) #define DDS_READER_STATUS_MASK \ @@ -779,8 +775,9 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe dds_subscriber_unlock (sub); #ifdef DDS_HAS_DURABILITY + assert(rd->m_entity.m_domain->dc.dds_durability_new_local_reader); if (dkind >= DDS_DURABILITY_TRANSIENT) { - dds_durability_new_local_reader(reader, rhc); + rd->m_entity.m_domain->dc.dds_durability_new_local_reader(reader, rhc); } #endif diff --git a/src/core/ddsc/src/dds_write.c b/src/core/ddsc/src/dds_write.c index a9761aaf1f..6de46f5a51 100644 --- a/src/core/ddsc/src/dds_write.c +++ b/src/core/ddsc/src/dds_write.c @@ -31,10 +31,6 @@ #include "dds__loaned_sample.h" #include "dds__psmx.h" -#ifdef DDS_HAS_DURABILITY -#include "dds/durability/dds_durability.h" -#endif - struct ddsi_serdata_plain { struct ddsi_serdata p; }; struct ddsi_serdata_any { struct ddsi_serdata a; }; @@ -47,6 +43,11 @@ dds_return_t dds_write (dds_entity_t writer, const void *data) return DDS_RETCODE_BAD_PARAMETER; #ifdef DDS_HAS_DURABILITY + if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) + return ret; + dds_durability_t* dc = &wr->m_entity.m_domain->dc; + dds_writer_unlock (wr); + /* determine if the quorum of durable services for the writer is fulfilled. * * LH: This implementation may be suboptimal, because determining whether the @@ -54,7 +55,8 @@ dds_return_t dds_write (dds_entity_t writer, const void *data) * within the same writer lock. So after the quorum has been established, * and before the data is published, the quorum could have been dropped again. * Chances for this to happen are slim, but still ... */ - if ((ret = dds_durability_wait_for_quorum(writer)) != DDS_RETCODE_OK) { + assert(dc->dds_durability_wait_for_quorum); + if ((ret = dc->dds_durability_wait_for_quorum(writer)) != DDS_RETCODE_OK) { return ret; } #endif diff --git a/src/core/ddsc/src/dds_writer.c b/src/core/ddsc/src/dds_writer.c index 18f4a63e80..f64d5c75f9 100644 --- a/src/core/ddsc/src/dds_writer.c +++ b/src/core/ddsc/src/dds_writer.c @@ -38,10 +38,6 @@ #include "dds__statistics.h" #include "dds__psmx.h" -#ifdef DDS_HAS_DURABILITY -#include "dds/durability/dds_durability.h" -#endif - DECL_ENTITY_LOCK_UNLOCK (dds_writer) #define DDS_WRITER_STATUS_MASK \ @@ -426,13 +422,14 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit if ((rc = dds_endpoint_add_psmx_endpoint (&wr->m_endpoint, wqos, &tp->m_ktopic->psmx_topics, DDS_PSMX_ENDPOINT_TYPE_WRITER)) != DDS_RETCODE_OK) goto err_pipe_open; -#if DDS_HAS_DURABILITY +#ifdef DDS_HAS_DURABILITY /* quorum applies only to durable writers. * By default quorum reached for volatile and transient-local writers * For durable writer the quorum is initially reached when quorum threshold == 0 * (but we'll likely prohibit this case as an invalid configuration because * it may lead to eventual inconsistencies). */ - uint32_t quorum = dds_durability_get_quorum(); + assert(wr->m_entity.m_domain->dc.dds_durability_get_quorum); + uint32_t quorum = wr->m_entity.m_domain->dc.dds_durability_get_quorum(); wr->quorum_reached = true; if (wqos->durability.kind >= DDS_DURABILITY_TRANSIENT) { wr->quorum_reached = (quorum == 0); @@ -460,7 +457,8 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit dds_publisher_unlock (pub); #ifdef DDS_HAS_DURABILITY - dds_durability_new_local_writer(writer); + assert(wr->m_entity.m_domain->dc.dds_durability_new_local_writer); + wr->m_entity.m_domain->dc.dds_durability_new_local_writer(writer); #endif // start async thread if not already started and the latency budget is non zero diff --git a/src/core/xtests/symbol_export/CMakeLists.txt b/src/core/xtests/symbol_export/CMakeLists.txt index 5d9aa40c4a..fe5b576e6a 100644 --- a/src/core/xtests/symbol_export/CMakeLists.txt +++ b/src/core/xtests/symbol_export/CMakeLists.txt @@ -18,7 +18,8 @@ target_include_directories(symbol_export_test PRIVATE "$" "$" "$" - "$") + "$" + "$") if (ENABLE_SECURITY) target_link_libraries(symbol_export_test PRIVATE security_api) diff --git a/src/durability/CMakeLists.txt b/src/durability/CMakeLists.txt index 434c38867a..e2bb45caca 100644 --- a/src/durability/CMakeLists.txt +++ b/src/durability/CMakeLists.txt @@ -7,32 +7,25 @@ # http://www.eclipse.org/org/documents/edl-v10.php. # # SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause -# -set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}") -set(binary_dir "${CMAKE_CURRENT_BINARY_DIR}") - -add_library(durability INTERFACE) - -target_include_directories( - durability INTERFACE - "$" - "$" - "$") - -set(headers - "${source_dir}/include/dds/durability/dds_durability.h" - "${source_dir}/include/dds/durability/durablesupport.h") -set(sources - "${source_dir}/src/dds_durability.c" - "${source_dir}/src/durablesupport.c") - -target_sources(durability INTERFACE ${headers} ${sources}) +idlc_generate(TARGET dcidl FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/durablesupport.idl") +add_library(durability SHARED "${CMAKE_CURRENT_SOURCE_DIR}/src/dds_durability.c") +set_property(TARGET durability PROPERTY C_VISIBILITY_PRESET hidden) +target_include_directories(durability PRIVATE + "$" + "$" + "$" + "$" + "$" + "$" + "$" + "$" +) +target_link_libraries(durability PRIVATE dcidl) install( - DIRECTORY - "${source_dir}/include/" - "${binary_dir}/include/" - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" - COMPONENT dev - FILES_MATCHING PATTERN "*.h") \ No newline at end of file + TARGETS durability + EXPORT "${PROJECT_NAME}" + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h deleted file mode 100644 index 83e9033478..0000000000 --- a/src/durability/include/dds/durability/dds_durability.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright(c) 2006 to 2020 ZettaScale Technology and others -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License -// v. 1.0 which is available at -// http://www.eclipse.org/org/documents/edl-v10.php. -// -// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause - -#ifndef DDS_DURABILITY_H -#define DDS_DURABILITY_H - -#include "dds/ddsi/ddsi_domaingv.h" -#include "dds/ddsrt/retcode.h" -#include "ddsc/dds.h" -#include "dds__types.h" -#include "dds/ddsc/dds_rhc.h" - -#if defined (__cplusplus) -extern "C" { -#endif - -/* Integration functions for durability plugins */ -typedef int (*plugin_init)(const char *argument, void **context, struct ddsi_domaingv *gv); -typedef int (*plugin_finalize)(void *context); - -dds_return_t dds_durability_init (const dds_domainid_t domain, struct ddsi_domaingv *gv); -dds_return_t dds_durability_fini (void); -uint32_t dds_durability_get_quorum (void); -dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc); -dds_return_t dds_durability_new_local_writer (dds_entity_t writer); -dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer); - -bool dds_durability_is_terminating (void); - - -#if defined (__cplusplus) -} -#endif - -#endif /* DDS_DURABILITY_H */ diff --git a/src/durability/include/dds/durability/dds_durability_private.h b/src/durability/include/dds/durability/dds_durability_private.h new file mode 100644 index 0000000000..fbe5b4ba37 --- /dev/null +++ b/src/durability/include/dds/durability/dds_durability_private.h @@ -0,0 +1,27 @@ +// Copyright(c) 2006 to 2020 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#ifndef DDS_DURABILITY_PRIVATE_H +#define DDS_DURABILITY_PRIVATE_H + +#include "dds/export.h" +#include "dds/durability/dds_durability_public.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +DDS_EXPORT void dds_durability_creator(dds_durability_t* ds); + +#if defined (__cplusplus) +} +#endif + +#endif /* DDS_DURABILITY_PRIVATE_H */ diff --git a/src/durability/include/dds/durability/dds_durability_public.h b/src/durability/include/dds/durability/dds_durability_public.h new file mode 100644 index 0000000000..e990cba38b --- /dev/null +++ b/src/durability/include/dds/durability/dds_durability_public.h @@ -0,0 +1,41 @@ +// Copyright(c) 2006 to 2020 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#ifndef DDS_DURABILITY_PUBLIC_H +#define DDS_DURABILITY_PUBLIC_H + +#include "dds/ddsrt/dynlib.h" +#include "dds/ddsi/ddsi_domaingv.h" +#include "ddsc/dds.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +typedef struct dds_durability{ + ddsrt_dynlib_t lib_handle; + dds_return_t (*dds_durability_init) (const dds_domainid_t domain, struct ddsi_domaingv *gv); + dds_entity_t (*_dds_durability_fini) (void); + uint32_t (*dds_durability_get_quorum) (void); + dds_return_t (*dds_durability_new_local_reader) (dds_entity_t reader, struct dds_rhc *rhc); + dds_return_t (*dds_durability_new_local_writer) (dds_entity_t writer); + dds_return_t (*dds_durability_wait_for_quorum) (dds_entity_t writer); + bool (*dds_durability_is_terminating) (void); +}dds_durability_t; + +void dds_durability_fini (dds_durability_t* dc); +dds_return_t dds_durability_load (dds_durability_t* dc, const struct ddsi_domaingv* gv); +void dds_durability_unload (dds_durability_t* dc); + +#if defined (__cplusplus) +} +#endif + +#endif /* DDS_DURABILITY_PUBLIC_H */ diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h deleted file mode 100644 index 0750233696..0000000000 --- a/src/durability/include/dds/durability/durablesupport.h +++ /dev/null @@ -1,390 +0,0 @@ -/**************************************************************** - - IMPORTANT: - - The file contains the definitions for the client durability related topics. - This file is partially copied from the output generated by durabledupport.idl - because we cannot generate code from an idl file due to cyclic dependencies - in idlc_generate(). - -*****************************************************************/ -#ifndef DURABLE_SUPPORT_H -#define DURABLE_SUPPORT_H - -#include "dds/ddsc/dds_public_impl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef uint8_t DurableSupport_id_t[16]; - -#define DurableSupport_id_t__alloc() \ -((DurableSupport_id_t*) dds_alloc (sizeof (DurableSupport_id_t))); - -typedef uint64_t DurableSupport_session_id_t; - -#define DurableSupport_session_id_t__alloc() \ -((DurableSupport_session_id_t*) dds_alloc (sizeof (DurableSupport_session_id_t))); - -typedef uint16_t DurableSupport_session_kind_t; - -#define DurableSupport_session_kind_t__alloc() \ -((DurableSupport_session_kind_t*) dds_alloc (sizeof (DurableSupport_session_kind_t))); - -typedef uint16_t DurableSupport_beadtype_t; - -#define DurableSupport_beadtype_t__alloc() \ -((DurableSupport_beadtype_t*) dds_alloc (sizeof (DurableSupport_beadtype_t))); - -typedef struct DurableSupport_status -{ - DurableSupport_id_t id; - char * hostname; - char * name; -} DurableSupport_status; - -extern const dds_topic_descriptor_t DurableSupport_status_desc; - -#define DurableSupport_status__alloc() \ -((DurableSupport_status*) dds_alloc (sizeof (DurableSupport_status))); - -#define DurableSupport_status_free(d,o) \ -dds_sample_free ((d), &DurableSupport_status_desc, (o)) - -typedef struct DurableSupport_range -{ - uint64_t lb; - uint64_t ub; -} DurableSupport_range; - -#ifndef DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED -#define DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED -typedef struct dds_sequence_DurableSupport_range -{ - uint32_t _maximum; - uint32_t _length; - struct DurableSupport_range *_buffer; - bool _release; -} dds_sequence_DurableSupport_range; - -#define dds_sequence_DurableSupport_range__alloc() \ -((dds_sequence_DurableSupport_range*) dds_alloc (sizeof (dds_sequence_DurableSupport_range))); - -#define dds_sequence_DurableSupport_range_allocbuf(l) \ -((struct DurableSupport_range *) dds_alloc ((l) * sizeof (struct DurableSupport_range))) -#endif /* DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED */ - -typedef struct DurableSupport_writer -{ - DurableSupport_id_t id; - uint32_t flags; - dds_sequence_DurableSupport_range ranges; -} DurableSupport_writer; - -#ifndef DDS_SEQUENCE_DURABLESUPPORT_WRITER_DEFINED -#define DDS_SEQUENCE_DURABLESUPPORT_WRITER_DEFINED -typedef struct dds_sequence_DurableSupport_writer -{ - uint32_t _maximum; - uint32_t _length; - struct DurableSupport_writer *_buffer; - bool _release; -} dds_sequence_DurableSupport_writer; - -#define dds_sequence_DurableSupport_writer__alloc() \ -((dds_sequence_DurableSupport_writer*) dds_alloc (sizeof (dds_sequence_DurableSupport_writer))); - -#define dds_sequence_DurableSupport_writer_allocbuf(l) \ -((struct DurableSupport_writer *) dds_alloc ((l) * sizeof (struct DurableSupport_writer))) -#endif /* DDS_SEQUENCE_DURABLESUPPORT_WRITER_DEFINED */ - -typedef struct DurableSupport_set -{ - char * partition; - char * tpname; - char * type_id; - uint32_t flags; - dds_sequence_DurableSupport_writer writers; -} DurableSupport_set; - -#ifndef DDS_SEQUENCE_DURABLESUPPORT_SET_DEFINED -#define DDS_SEQUENCE_DURABLESUPPORT_SET_DEFINED -typedef struct dds_sequence_DurableSupport_set -{ - uint32_t _maximum; - uint32_t _length; - struct DurableSupport_set *_buffer; - bool _release; -} dds_sequence_DurableSupport_set; - -#define dds_sequence_DurableSupport_set__alloc() \ -((dds_sequence_DurableSupport_set*) dds_alloc (sizeof (dds_sequence_DurableSupport_set))); - -#define dds_sequence_DurableSupport_set_allocbuf(l) \ -((struct DurableSupport_set *) dds_alloc ((l) * sizeof (struct DurableSupport_set))) -#endif /* DDS_SEQUENCE_DURABLESUPPORT_SET_DEFINED */ - -typedef struct DurableSupport_state -{ - DurableSupport_id_t id; - char * name; - dds_sequence_DurableSupport_set sets; -} DurableSupport_state; - -extern const dds_topic_descriptor_t DurableSupport_state_desc; - -#define DurableSupport_state__alloc() \ -((DurableSupport_state*) dds_alloc (sizeof (DurableSupport_state))); - -#define DurableSupport_state_free(d,o) \ -dds_sample_free ((d), &DurableSupport_state_desc, (o)) - -#define DurableSupport_BEADTYPE_SESSION 1 -#define DurableSupport_BEADTYPE_SET 2 -#define DurableSupport_BEADTYPE_WRITER 3 -#define DurableSupport_BEADTYPE_DATA 4 -#define DurableSupport_SESSION_KIND_START 1 -#define DurableSupport_SESSION_KIND_END 2 -#define DurableSupport_SESSION_KIND_ABORT 3 -typedef struct DurableSupport_session_t -{ - DurableSupport_session_kind_t kind; - DurableSupport_session_id_t session_id; -} DurableSupport_session_t; - -#ifndef DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED -#define DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED -typedef struct dds_sequence_DurableSupport_id_t -{ - uint32_t _maximum; - uint32_t _length; - DurableSupport_id_t *_buffer; - bool _release; -} dds_sequence_DurableSupport_id_t; - -#define dds_sequence_DurableSupport_id_t__alloc() \ -((dds_sequence_DurableSupport_id_t*) dds_alloc (sizeof (dds_sequence_DurableSupport_id_t))); - -#define dds_sequence_DurableSupport_id_t_allocbuf(l) \ -((DurableSupport_id_t *) dds_alloc ((l) * sizeof (DurableSupport_id_t))) -#endif /* DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED */ - -typedef struct DurableSupport_set_t -{ - char * partition; - char * tpname; - char * type_id; - uint32_t flags; - dds_sequence_DurableSupport_id_t addressees; -} DurableSupport_set_t; - -typedef struct DurableSupport_writer_properties_t -{ - bool autodispose; -} DurableSupport_writer_properties_t; - -#ifndef DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED -#define DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED -typedef struct dds_sequence_DurableSupport_range -{ - uint32_t _maximum; - uint32_t _length; - struct DurableSupport_range *_buffer; - bool _release; -} dds_sequence_DurableSupport_range; - -#define dds_sequence_DurableSupport_range__alloc() \ -((dds_sequence_DurableSupport_range*) dds_alloc (sizeof (dds_sequence_DurableSupport_range))); - -#define dds_sequence_DurableSupport_range_allocbuf(l) \ -((struct DurableSupport_range *) dds_alloc ((l) * sizeof (struct DurableSupport_range))) -#endif /* DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED */ - -typedef struct DurableSupport_writer_t -{ - DurableSupport_id_t id; - struct DurableSupport_writer_properties_t properties; - uint32_t flags; - dds_sequence_DurableSupport_range ranges; -} DurableSupport_writer_t; - -#ifndef DDS_SEQUENCE_OCTET_DEFINED -#define DDS_SEQUENCE_OCTET_DEFINED -typedef struct dds_sequence_octet -{ - uint32_t _maximum; - uint32_t _length; - uint8_t *_buffer; - bool _release; -} dds_sequence_octet; - -#define dds_sequence_octet__alloc() \ -((dds_sequence_octet*) dds_alloc (sizeof (dds_sequence_octet))); - -#define dds_sequence_octet_allocbuf(l) \ -((uint8_t *) dds_alloc ((l) * sizeof (uint8_t))) -#endif /* DDS_SEQUENCE_OCTET_DEFINED */ - -typedef struct DurableSupport_data_t -{ - dds_sequence_octet blob; -} DurableSupport_data_t; - -typedef struct DurableSupport_content -{ - DurableSupport_beadtype_t _d; - union - { - struct DurableSupport_session_t session; - struct DurableSupport_set_t set; - struct DurableSupport_writer_t writer; - struct DurableSupport_data_t data; - } _u; -} DurableSupport_content; - -typedef struct DurableSupport_bead -{ - DurableSupport_id_t id; - struct DurableSupport_content body; -} DurableSupport_bead; - -extern const dds_topic_descriptor_t DurableSupport_bead_desc; - -#define DurableSupport_bead__alloc() \ -((DurableSupport_bead*) dds_alloc (sizeof (DurableSupport_bead))); - -#define DurableSupport_bead_free(d,o) \ -dds_sample_free ((d), &DurableSupport_bead_desc, (o)) - -typedef struct DurableSupport_control -{ - DurableSupport_id_t id; -} DurableSupport_control; - -extern const dds_topic_descriptor_t DurableSupport_control_desc; - -#define DurableSupport_control__alloc() \ -((DurableSupport_control*) dds_alloc (sizeof (DurableSupport_control))); - -#define DurableSupport_control_free(d,o) \ -dds_sample_free ((d), &DurableSupport_control_desc, (o)) - -typedef int64_t DurableSupport_duration_t; - -#define DurableSupport_duration_t__alloc() \ -((DurableSupport_duration_t*) dds_alloc (sizeof (DurableSupport_duration_t))); - -typedef uint16_t DurableSupport_responsetype_t; - -#define DurableSupport_responsetype_t__alloc() \ -((DurableSupport_responsetype_t*) dds_alloc (sizeof (DurableSupport_responsetype_t))); - -typedef uint64_t DurableSupport_delivery_id_t; - -#define DurableSupport_delivery_id_t__alloc() \ -((DurableSupport_delivery_id_t*) dds_alloc (sizeof (DurableSupport_delivery_id_t))); - -typedef struct DurableSupport_request_key -{ - DurableSupport_id_t rguid; -} DurableSupport_request_key; - -typedef struct DurableSupport_request -{ - struct DurableSupport_request_key key; - DurableSupport_id_t client; - char * partition; - char * tpname; - char * type_id; - DurableSupport_duration_t timeout; -} DurableSupport_request; - -extern const dds_topic_descriptor_t DurableSupport_request_desc; - -#define DurableSupport_request__alloc() \ -((DurableSupport_request*) dds_alloc (sizeof (DurableSupport_request))); - -#define DurableSupport_request_free(d,o) \ -dds_sample_free ((d), &DurableSupport_request_desc, (o)) - -#define DurableSupport_RESPONSETYPE_SET 1 -#define DurableSupport_RESPONSETYPE_DATA 2 -#ifndef DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED -#define DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED -typedef struct dds_sequence_DurableSupport_id_t -{ - uint32_t _maximum; - uint32_t _length; - DurableSupport_id_t *_buffer; - bool _release; -} dds_sequence_DurableSupport_id_t; - -#define dds_sequence_DurableSupport_id_t__alloc() \ -((dds_sequence_DurableSupport_id_t*) dds_alloc (sizeof (dds_sequence_DurableSupport_id_t))); - -#define dds_sequence_DurableSupport_id_t_allocbuf(l) \ -((DurableSupport_id_t *) dds_alloc ((l) * sizeof (DurableSupport_id_t))) -#endif /* DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED */ - -typedef struct DurableSupport_response_set_t -{ - DurableSupport_delivery_id_t delivery_id; - dds_sequence_DurableSupport_id_t guids; - char * partition; - char * tpname; - char * type_id; - uint32_t flags; -} DurableSupport_response_set_t; - -#ifndef DDS_SEQUENCE_OCTET_DEFINED -#define DDS_SEQUENCE_OCTET_DEFINED -typedef struct dds_sequence_octet -{ - uint32_t _maximum; - uint32_t _length; - uint8_t *_buffer; - bool _release; -} dds_sequence_octet; - -#define dds_sequence_octet__alloc() \ -((dds_sequence_octet*) dds_alloc (sizeof (dds_sequence_octet))); - -#define dds_sequence_octet_allocbuf(l) \ -((uint8_t *) dds_alloc ((l) * sizeof (uint8_t))) -#endif /* DDS_SEQUENCE_OCTET_DEFINED */ - -typedef struct DurableSupport_response_data_t -{ - dds_sequence_octet blob; -} DurableSupport_response_data_t; - -typedef struct DurableSupport_response_content -{ - DurableSupport_responsetype_t _d; - union - { - struct DurableSupport_response_set_t set; - struct DurableSupport_response_data_t data; - } _u; -} DurableSupport_response_content; - -typedef struct DurableSupport_response -{ - DurableSupport_id_t id; - struct DurableSupport_response_content body; -} DurableSupport_response; - -extern const dds_topic_descriptor_t DurableSupport_response_desc; - -#define DurableSupport_response__alloc() \ -((DurableSupport_response*) dds_alloc (sizeof (DurableSupport_response))); - -#define DurableSupport_response_free(d,o) \ -dds_sample_free ((d), &DurableSupport_response_desc, (o)) - -#ifdef __cplusplus -} -#endif - -#endif /* DURABLE_SUPPORT_H */ diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index e21e7c0239..e6eaa4feec 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -9,21 +9,21 @@ * * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ +#include "durablesupport.h" +#include "dds/durability/dds_durability_private.h" #include "dds/ddsi/ddsi_domaingv.h" -#include "dds/durability/dds_durability.h" -#include "dds/durability/durablesupport.h" #include "dds/ddsrt/atomics.h" #include "dds/ddsrt/string.h" #include "dds/ddsrt/heap.h" #include "dds/ddsrt/threads.h" #include "dds/ddsrt/log.h" #include "ddsc/dds.h" -#include -#include "dds__writer.h" +#include "../src/dds__writer.h" #include "dds/ddsi/ddsi_endpoint.h" #include "dds/ddsrt/avl.h" #include "dds/ddsi/ddsi_serdata.h" #include "dds/ddsi/ddsi_typelib.h" +#include #define DEFAULT_QOURUM 1 #define DEFAULT_IDENT "durable_support" @@ -1392,11 +1392,15 @@ err_response_subscriber : return NULL; } -static void dc_com_free (struct com_t *com) +static void dc_com_free (struct com_t *com, dds_entity_t* pp_out) { assert(com); DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "destroying dc infrastructure\n"); - dds_delete(com->participant); + if ( pp_out == NULL ){ + dds_delete(com->participant); + } else { + *pp_out = com->participant; + } ddsrt_free(com); dc.com = NULL; return; @@ -2204,7 +2208,7 @@ static dds_return_t activate_request_listener (struct dc_t *dc) return DDS_RETCODE_ERROR; } -dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_domaingv *gv) +static dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_domaingv *gv) { dds_return_t rc; @@ -2259,7 +2263,7 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom return DDS_RETCODE_OK; err_recv_thread: - dc_com_free(dc.com); + dc_com_free(dc.com, NULL); err_com_new: dds_delete_listener(dc.request_listener); err_create_request_listener: @@ -2277,9 +2281,9 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom } /* make sure that dc terminates when the last participant is destroyed */ -dds_return_t dds_durability_fini (void) +static dds_entity_t _dds_durability_fini (void) { - dds_return_t rc = DDS_RETCODE_OK; + dds_entity_t pp_out = 0; uint32_t refcount; /* The durable client is deinitialized when the last participant is about @@ -2289,12 +2293,13 @@ dds_return_t dds_durability_fini (void) refcount = ddsrt_atomic_dec32_nv(&dc.refcount); if (refcount != 2) { /* skip */ - return DDS_RETCODE_OK; + return pp_out; } if (dc.com) { /* indicate the the durable client is terminating */ ddsrt_atomic_st32 (&dc.termflag, 1); /* force the dc thread to terminate */ + dds_return_t rc; if ((rc = dds_waitset_set_trigger(dc.com->ws, true)) < 0) { DDS_ERROR("failed to trigger dc recv thread [%s]", dds_strretcode(rc)); } @@ -2304,7 +2309,7 @@ dds_return_t dds_durability_fini (void) } dds_delete_listener(dc.request_listener); dds_delete_listener(dc.quorum_listener); - dc_com_free(dc.com); + dc_com_free(dc.com, &pp_out); // Participant must be deleted outside the plugin. ddsrt_avl_cfree(&delivery_ctx_td, &dc.delivery_ctxs, cleanup_delivery_ctx); ddsrt_cond_destroy(&dc.delivery_request_cond); ddsrt_mutex_destroy(&dc.delivery_request_mutex); @@ -2313,10 +2318,10 @@ dds_return_t dds_durability_fini (void) ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); ddsrt_free(dc.cfg.ident); } - return DDS_RETCODE_OK; + return pp_out; } -bool dds_durability_is_terminating (void) +static bool dds_durability_is_terminating (void) { return (ddsrt_atomic_ld32(&dc.termflag) > 0); } @@ -2369,7 +2374,7 @@ static bool is_application_entity (struct dc_t *dc, dds_entity_t entity) return true; } -dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc) +static dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc) { dds_durability_kind_t dkind; dds_qos_t *qos; @@ -2408,7 +2413,7 @@ dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rh } /* check if the writer is a durable application writer, and if so, we need to keep track of the quorum */ -dds_return_t dds_durability_new_local_writer (dds_entity_t writer) +static dds_return_t dds_durability_new_local_writer (dds_entity_t writer) { dds_durability_kind_t dkind; dds_qos_t *wqos; @@ -2508,7 +2513,7 @@ static dds_return_t dds_durability_get_quorum_reached (dds_entity_t writer, bool * DDS_RETCODE_OK if quorum is reached * DDS_PRECONDITION_NOT_MET otherwise */ -dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) +static dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) { dds_return_t ret = DDS_RETCODE_ERROR; ddsrt_mtime_t tnow = ddsrt_time_monotonic (); @@ -2548,8 +2553,18 @@ dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) } /* get the configured quorum */ -uint32_t dds_durability_get_quorum (void) +static uint32_t dds_durability_get_quorum (void) { return dc.cfg.quorum; } +void dds_durability_creator(dds_durability_t* ds) +{ + ds->dds_durability_init = dds_durability_init; + ds->_dds_durability_fini = _dds_durability_fini; + ds->dds_durability_get_quorum = dds_durability_get_quorum; + ds->dds_durability_new_local_reader = dds_durability_new_local_reader; + ds->dds_durability_new_local_writer = dds_durability_new_local_writer; + ds->dds_durability_wait_for_quorum = dds_durability_wait_for_quorum; + ds->dds_durability_is_terminating = dds_durability_is_terminating; +} diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c deleted file mode 100644 index 6325ac0e3f..0000000000 --- a/src/durability/src/durablesupport.c +++ /dev/null @@ -1,1041 +0,0 @@ -/**************************************************************** - - Generated by Eclipse Cyclone DDS IDL to C Translator - File name: /home/lex/Repositories/TheFixer/durable_support/build/src/durablesupport.c - Source: /home/lex/Repositories/TheFixer/durable_support/src/durablesupport.idl - Cyclone DDS: V0.11.0 - -*****************************************************************/ -#include "../include/dds/durability/durablesupport.h" - -static const uint32_t DurableSupport_status_ops [] = -{ - /* status */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_status, id), 16u, - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_status, hostname), - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_status, name), - DDS_OP_RTS, - - /* key: id */ - DDS_OP_KOF | 1, 1u /* order: 0 */ -}; - -static const dds_key_descriptor_t DurableSupport_status_keys[1] = -{ - { "id", 9, 0 } -}; - -/* Type Information: - [MINIMAL 1609a972dd9ffc746226aaae0ce7] (#deps: 1) - - [MINIMAL 43f53a2be35b432cc735e9431a89] - [COMPLETE 3ae8d3b6272f54c8257bf018eda8] (#deps: 1) - - [COMPLETE aca4d5a256d39713924333e85c6d] -*/ -#define TYPE_INFO_CDR_DurableSupport_status (const unsigned char []){ \ - 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x16, 0x09, 0xa9, 0x72, 0xdd, 0x9f, 0xfc, 0x74, 0x62, 0x26, 0xaa, \ - 0xae, 0x0c, 0xe7, 0x00, 0x58, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x3a, 0xe8, 0xd3, \ - 0xb6, 0x27, 0x2f, 0x54, 0xc8, 0x25, 0x7b, 0xf0, 0x18, 0xed, 0xa8, 0x00, 0x8f, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x40, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_status 148u -#define TYPE_MAP_CDR_DurableSupport_status (const unsigned char []){ \ - 0x9a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0x16, 0x09, 0xa9, 0x72, 0xdd, 0x9f, 0xfc, \ - 0x74, 0x62, 0x26, 0xaa, 0xae, 0x0c, 0xe7, 0x00, 0x54, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x08, 0x97, 0xac, 0xf4, \ - 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0xb0, 0x68, 0x93, 0x1c, \ - 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ - 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ - 0xf4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf2, 0x3a, 0xe8, 0xd3, 0xb6, 0x27, 0x2f, 0x54, \ - 0xc8, 0x25, 0x7b, 0xf0, 0x18, 0xed, 0xa8, 0x00, 0x8b, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x74, 0x61, 0x74, \ - 0x75, 0x73, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x09, 0x00, 0x00, 0x00, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, \ - 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ - 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0xf2, 0x3a, 0xe8, 0xd3, 0xb6, 0x27, 0x2f, 0x54, 0xc8, 0x25, 0x7b, 0xf0, 0x18, 0xed, 0xa8, 0xf1, \ - 0x16, 0x09, 0xa9, 0x72, 0xdd, 0x9f, 0xfc, 0x74, 0x62, 0x26, 0xaa, 0xae, 0x0c, 0xe7, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_status 476u -const dds_topic_descriptor_t DurableSupport_status_desc = -{ - .m_size = sizeof (DurableSupport_status), - .m_align = dds_alignof (DurableSupport_status), - .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 1u, - .m_typename = "DurableSupport::status", - .m_keys = DurableSupport_status_keys, - .m_nops = 5, - .m_ops = DurableSupport_status_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_status, .sz = TYPE_INFO_CDR_SZ_DurableSupport_status }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_status, .sz = TYPE_MAP_CDR_SZ_DurableSupport_status } -}; - -static const uint32_t DurableSupport_state_ops [] = -{ - /* state */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_state, id), 16u, - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_state, name), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_state, sets), sizeof (DurableSupport_set), (4u << 16u) + 5u /* set */, - DDS_OP_RTS, - - /* set */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, partition), - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, tpname), - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, type_id), - DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_set, flags), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_set, writers), sizeof (DurableSupport_writer), (4u << 16u) + 5u /* writer */, - DDS_OP_RTS, - - /* writer */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_writer, id), 16u, - DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_writer, flags), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_writer, ranges), sizeof (DurableSupport_range), (4u << 16u) + 5u /* range */, - DDS_OP_RTS, - - /* range */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, lb), - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, ub), - DDS_OP_RTS, - - /* key: id */ - DDS_OP_KOF | 1, 1u /* order: 0 */ -}; - -static const dds_key_descriptor_t DurableSupport_state_keys[1] = -{ - { "id", 42, 0 } -}; - -/* Type Information: - [MINIMAL 9546da84e880713f59c93561b8d8] (#deps: 4) - - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 0edda7680861b44f54f71e189994] - - [MINIMAL 7b73d4df4f265b2da8c52f3c3a8e] - - [MINIMAL ef038b7b19448c9ce27fa1c268cd] - [COMPLETE 174aa20548235aee4aff5111d8a2] (#deps: 4) - - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE 0b9ecead7e5e9db531d5a4ef26b1] - - [COMPLETE 3be64a4fbc92a7b2f612cbd52a3a] - - [COMPLETE d8d43c2295c185a21b9591a7126c] -*/ -#define TYPE_INFO_CDR_DurableSupport_state (const unsigned char []){ \ - 0x20, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x95, 0x46, 0xda, 0x84, 0xe8, 0x80, 0x71, 0x3f, 0x59, 0xc9, 0x35, \ - 0x61, 0xb8, 0xd8, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, 0x94, 0x00, \ - 0x7a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, \ - 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, \ - 0x37, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x4a, 0xa2, 0x05, 0x48, 0x23, 0x5a, 0xee, 0x4a, 0xff, 0x51, \ - 0x11, 0xd8, 0xa2, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ - 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x0b, 0x9e, 0xce, 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0x00, \ - 0xca, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, \ - 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, \ - 0x61, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_state 292u -#define TYPE_MAP_CDR_DurableSupport_state (const unsigned char []){ \ - 0xff, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf1, 0x95, 0x46, 0xda, 0x84, 0xe8, 0x80, 0x71, \ - 0x3f, 0x59, 0xc9, 0x35, 0x61, 0xb8, 0xd8, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0xb0, 0x68, 0x93, 0x1c, \ - 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ - 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, 0x94, 0x17, 0x8d, \ - 0x51, 0x02, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, \ - 0x89, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x10, 0x02, 0xf1, 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, \ - 0x94, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x0c, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, 0x0b, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, \ - 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0xbf, 0x63, 0x9b, 0x5f, 0xf1, 0x7b, \ - 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0x00, 0x00, 0x00, \ - 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x56, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, \ - 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, \ - 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x8d, 0x81, 0x02, 0xfb, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, \ - 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x26, \ - 0x40, 0x3e, 0xc6, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x1c, \ - 0x78, 0xb4, 0x86, 0x00, 0x01, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x4a, 0xa2, \ - 0x05, 0x48, 0x23, 0x5a, 0xee, 0x4a, 0xff, 0x51, 0x11, 0xd8, 0xa2, 0x00, 0x9b, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x02, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x73, 0x74, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x70, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, \ - 0x27, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, \ - 0x0b, 0x9e, 0xce, 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, \ - 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x0b, 0x9e, 0xce, \ - 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0x00, 0xc6, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x73, 0x65, 0x74, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, \ - 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, \ - 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, \ - 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x77, 0x72, 0x69, 0x74, \ - 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, 0xf6, \ - 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, \ - 0x65, 0x72, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, \ - 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, \ - 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x5d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x61, 0x6e, 0x67, \ - 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6c, 0x62, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x4a, 0xa2, 0x05, 0x48, 0x23, 0x5a, 0xee, 0x4a, 0xff, 0x51, \ - 0x11, 0xd8, 0xa2, 0xf1, 0x95, 0x46, 0xda, 0x84, 0xe8, 0x80, 0x71, 0x3f, 0x59, 0xc9, 0x35, 0x61, \ - 0xb8, 0xd8, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ - 0xf2, 0x0b, 0x9e, 0xce, 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0xf1, \ - 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, 0x94, 0xf2, 0x3b, \ - 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0xf1, 0x7b, 0x73, \ - 0xd4, 0xdf, 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0xf2, 0xd8, 0xd4, 0x3c, \ - 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, 0xef, 0x03, 0x8b, 0x7b, \ - 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_state 1450u -const dds_topic_descriptor_t DurableSupport_state_desc = -{ - .m_size = sizeof (DurableSupport_state), - .m_align = dds_alignof (DurableSupport_state), - .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 1u, - .m_typename = "DurableSupport::state", - .m_keys = DurableSupport_state_keys, - .m_nops = 21, - .m_ops = DurableSupport_state_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_state, .sz = TYPE_INFO_CDR_SZ_DurableSupport_state }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_state, .sz = TYPE_MAP_CDR_SZ_DurableSupport_state } -}; - -static const uint32_t DurableSupport_bead_ops [] = -{ - /* bead */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_bead, id), 16u, - DDS_OP_ADR | DDS_OP_TYPE_EXT, offsetof (DurableSupport_bead, body), (3u << 16u) + 4u /* content */, - DDS_OP_RTS, - - /* content */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_content, _d), 4u, (20u << 16u) + 4u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 17 /* session_t */, 1, offsetof (DurableSupport_content, _u.session), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 19 /* set_t */, 2, offsetof (DurableSupport_content, _u.set), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 33 /* writer_t */, 3, offsetof (DurableSupport_content, _u.writer), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 53 /* data_t */, 4, offsetof (DurableSupport_content, _u.data), 0u, - DDS_OP_RTS, - - /* session_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_2BY, offsetof (DurableSupport_session_t, kind), - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_session_t, session_id), - DDS_OP_RTS, - - /* set_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, partition), - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, tpname), - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, type_id), - DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_set_t, flags), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_ARR, offsetof (DurableSupport_set_t, addressees), sizeof (DurableSupport_id_t), (8u << 16u) + 4u, - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, 0u, 16u, - DDS_OP_RTS, - DDS_OP_RTS, - - /* writer_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_writer_t, id), 16u, - DDS_OP_ADR | DDS_OP_TYPE_EXT, offsetof (DurableSupport_writer_t, properties), (3u << 16u) + 10u /* writer_properties_t */, - DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_writer_t, flags), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_writer_t, ranges), sizeof (DurableSupport_range), (4u << 16u) + 9u /* range */, - DDS_OP_RTS, - - /* writer_properties_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_BLN, offsetof (DurableSupport_writer_properties_t, autodispose), - DDS_OP_RTS, - - /* range */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, lb), - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, ub), - DDS_OP_RTS, - - /* data_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_data_t, blob), - DDS_OP_RTS, - - /* key: id */ - DDS_OP_KOF | 1, 1u /* order: 0 */ -}; - -static const dds_key_descriptor_t DurableSupport_bead_keys[1] = -{ - { "id", 82, 0 } -}; - -/* Type Information: - [MINIMAL 333a527587be11928ad9cbfa1803] (#deps: 10) - - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL e4bc4a05081322db5581a91d817f] - - [MINIMAL 80455e796dd3437163cb532089da] - - [MINIMAL 7fe2256248fb0dc7c6a9b6c616fb] - - [MINIMAL d8398b259af5a04792e296996c27] - - [MINIMAL 5068289639b114fecda3f2c2ebd6] - - [MINIMAL 889fb89d6714387ca74c9aa42719] - - [MINIMAL 7d1dfbcf78261b30f20d1dadb067] - - [MINIMAL ef038b7b19448c9ce27fa1c268cd] - - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE a10b59cc2ac5234a0ab0c89deed6] (#deps: 11) - - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE ad3badfa4313f0bde4a077931856] - - [COMPLETE 105e7fa73d9700c1960716873c88] - - [COMPLETE 5de973c540260a829429a905efcd] - - [COMPLETE 838f13c80cfd7a0061fb91f88e49] - - [COMPLETE 9c5d42ec81585355d169823828eb] - - [COMPLETE e2beee99b860e5aa4c372c3b5655] - - [COMPLETE e6c4e5bb805c08c1d9e923e071ea] - - [COMPLETE 7a239210b1658deca81e1474b300] - - [COMPLETE d8d43c2295c185a21b9591a7126c] - - [COMPLETE a092964f6f76e3d643846ba36f9b] -*/ -#define TYPE_INFO_CDR_DurableSupport_bead (const unsigned char []){ \ - 0x58, 0x02, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x18, 0x01, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x33, 0x3a, 0x52, 0x75, 0x87, 0xbe, 0x11, 0x92, 0x8a, 0xd9, 0xcb, \ - 0xfa, 0x18, 0x03, 0x00, 0x55, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, \ - 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xe4, 0xbc, 0x4a, 0x05, 0x08, 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0x00, \ - 0xcc, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ - 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0x00, \ - 0x55, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ - 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, 0xb1, 0x14, 0xfe, 0xcd, 0xa3, 0xf2, 0xc2, 0xeb, 0xd6, 0x00, \ - 0x7a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, \ - 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, 0x19, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, 0x1d, 0xad, 0xb0, 0x67, 0x00, \ - 0x27, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, \ - 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x37, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ - 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x30, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa1, 0x0b, 0x59, 0xcc, 0x2a, 0xc5, 0x23, 0x4a, 0x0a, 0xb0, 0xc8, \ - 0x9d, 0xee, 0xd6, 0x00, 0x83, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, \ - 0x0b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ - 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, 0x13, 0xf0, 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0x00, \ - 0x13, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, \ - 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, 0x39, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, \ - 0x8d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, \ - 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, \ - 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, 0xe5, \ - 0xaa, 0x4c, 0x37, 0x2c, 0x3b, 0x56, 0x55, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0x00, \ - 0xd5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, \ - 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, \ - 0x61, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, \ - 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x00, 0x4f, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_bead 604u -#define TYPE_MAP_CDR_DurableSupport_bead (const unsigned char []){ \ - 0x28, 0x04, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xf1, 0x33, 0x3a, 0x52, 0x75, 0x87, 0xbe, 0x11, \ - 0x92, 0x8a, 0xd9, 0xcb, 0xfa, 0x18, 0x03, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xe4, 0xbc, 0x4a, 0x05, 0x08, \ - 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ - 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0xe4, 0xbc, 0x4a, 0x05, 0x08, \ - 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, \ - 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ - 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ - 0xa4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, \ - 0xfb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0xd6, 0xf4, 0x0c, \ - 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, \ - 0xb1, 0x14, 0xfe, 0xcd, 0xa3, 0xf2, 0xc2, 0xeb, 0xd6, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xa8, 0x2f, 0xee, 0xe3, \ - 0x24, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ - 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ - 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x7f, 0xe2, 0x25, 0x62, \ - 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x80, \ - 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xd9, 0x39, 0xaa, \ - 0xf7, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ - 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x7f, 0xc8, 0xef, \ - 0x54, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, \ - 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x06, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ - 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, 0xb1, 0x14, 0xfe, \ - 0xcd, 0xa3, 0xf2, 0xc2, 0xeb, 0xd6, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ - 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ - 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, \ - 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ - 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x73, 0xed, \ - 0xc9, 0x6c, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, \ - 0x19, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, \ - 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, \ - 0x0d, 0x1d, 0xad, 0xb0, 0x67, 0x74, 0x69, 0x3d, 0x2f, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, \ - 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x8d, 0x81, 0x02, 0xfb, 0xf1, 0x7d, \ - 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, 0x1d, 0xad, 0xb0, 0x67, 0x00, 0x00, 0x00, \ - 0x23, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x01, 0x1c, 0x63, 0x57, 0x19, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, \ - 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x26, 0x40, 0x3e, 0xc6, 0x00, \ - 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x1c, 0x78, 0xb4, 0x86, 0xf1, \ - 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, \ - 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0x8b, 0x06, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0xf2, 0xa1, 0x0b, 0x59, 0xcc, 0x2a, 0xc5, 0x23, 0x4a, 0x0a, 0xb0, 0xc8, \ - 0x9d, 0xee, 0xd6, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x62, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, \ - 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, \ - 0x13, 0xf0, 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ - 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, 0x13, 0xf0, \ - 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0x00, 0x0f, 0x01, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, \ - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x63, 0x6f, 0x6e, 0x74, \ - 0x65, 0x6e, 0x74, 0x00, 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, \ - 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5d, \ - 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, \ - 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, 0xe5, 0xaa, 0x4c, 0x37, 0x2c, 0x3b, 0x56, \ - 0x55, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, \ - 0xea, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, \ - 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, \ - 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x62, 0x65, 0x61, 0x64, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, \ - 0xa9, 0x05, 0xef, 0xcd, 0x89, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x22, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, \ - 0x74, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, \ - 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6b, 0x69, 0x6e, 0x64, \ - 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x9c, \ - 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, 0x00, 0x00, \ - 0x0b, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x00, 0x00, \ - 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, \ - 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, \ - 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x9c, 0x5d, \ - 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x39, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, \ - 0xe5, 0xaa, 0x4c, 0x37, 0x2c, 0x3b, 0x56, 0x55, 0xcd, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x74, 0x5f, \ - 0x74, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, \ - 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ - 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x72, \ - 0x65, 0x73, 0x73, 0x65, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, \ - 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0xd1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, \ - 0x65, 0x72, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, \ - 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, \ - 0x65, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ - 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, \ - 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, \ - 0x07, 0x00, 0x00, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x7a, 0x23, \ - 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, 0x00, 0x5a, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, \ - 0x73, 0x5f, 0x74, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x61, 0x75, 0x74, 0x6f, \ - 0x64, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, \ - 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x6c, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0xf2, 0xa0, 0x92, \ - 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x4b, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \ - 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x01, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0xf2, 0xa1, 0x0b, 0x59, 0xcc, 0x2a, 0xc5, 0x23, 0x4a, 0x0a, 0xb0, 0xc8, \ - 0x9d, 0xee, 0xd6, 0xf1, 0x33, 0x3a, 0x52, 0x75, 0x87, 0xbe, 0x11, 0x92, 0x8a, 0xd9, 0xcb, 0xfa, \ - 0x18, 0x03, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ - 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, 0x13, 0xf0, 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0xf1, \ - 0xe4, 0xbc, 0x4a, 0x05, 0x08, 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0xf2, 0x10, \ - 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0xf1, 0x80, 0x45, \ - 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x5d, 0xe9, 0x73, \ - 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0xf1, 0x7f, 0xe2, 0x25, 0x62, \ - 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, \ - 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, \ - 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, \ - 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, \ - 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, 0xe5, 0xaa, 0x4c, \ - 0x37, 0x2c, 0x3b, 0x56, 0x55, 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, 0xb1, 0x14, 0xfe, 0xcd, 0xa3, \ - 0xf2, 0xc2, 0xeb, 0xd6, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, \ - 0xe0, 0x71, 0xea, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, \ - 0x27, 0x19, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, \ - 0x00, 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, 0x1d, 0xad, 0xb0, 0x67, \ - 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, \ - 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0xf2, 0xa0, \ - 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0xf1, 0xa5, 0x80, \ - 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_bead 3116u -const dds_topic_descriptor_t DurableSupport_bead_desc = -{ - .m_size = sizeof (DurableSupport_bead), - .m_align = dds_alignof (DurableSupport_bead), - .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 1u, - .m_typename = "DurableSupport::bead", - .m_keys = DurableSupport_bead_keys, - .m_nops = 40, - .m_ops = DurableSupport_bead_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_bead, .sz = TYPE_INFO_CDR_SZ_DurableSupport_bead }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_bead, .sz = TYPE_MAP_CDR_SZ_DurableSupport_bead } -}; - -static const uint32_t DurableSupport_control_ops [] = -{ - /* control */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_control, id), 16u, - DDS_OP_RTS, - - /* key: id */ - DDS_OP_KOF | 1, 1u /* order: 0 */ -}; - -static const dds_key_descriptor_t DurableSupport_control_keys[1] = -{ - { "id", 5, 0 } -}; - -/* Type Information: - [MINIMAL cb0d133f4534082d16d026f85046] (#deps: 1) - - [MINIMAL 43f53a2be35b432cc735e9431a89] - [COMPLETE 59d57c820de779413f0c29ca47e1] (#deps: 1) - - [COMPLETE aca4d5a256d39713924333e85c6d] -*/ -#define TYPE_INFO_CDR_DurableSupport_control (const unsigned char []){ \ - 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0xcb, 0x0d, 0x13, 0x3f, 0x45, 0x34, 0x08, 0x2d, 0x16, 0xd0, 0x26, \ - 0xf8, 0x50, 0x46, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x59, 0xd5, 0x7c, \ - 0x82, 0x0d, 0xe7, 0x79, 0x41, 0x3f, 0x0c, 0x29, 0xca, 0x47, 0xe1, 0x00, 0x59, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x40, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_control 148u -#define TYPE_MAP_CDR_DurableSupport_control (const unsigned char []){ \ - 0x76, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0xcb, 0x0d, 0x13, 0x3f, 0x45, 0x34, 0x08, \ - 0x2d, 0x16, 0xd0, 0x26, 0xf8, 0x50, 0x46, 0x00, 0x31, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ - 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0xf2, 0x59, 0xd5, 0x7c, 0x82, 0x0d, 0xe7, 0x79, 0x41, 0x3f, 0x0c, 0x29, \ - 0xca, 0x47, 0xe1, 0x00, 0x55, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x00, \ - 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, \ - 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x3c, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0xf2, 0x59, 0xd5, 0x7c, 0x82, 0x0d, 0xe7, 0x79, 0x41, 0x3f, 0x0c, 0x29, \ - 0xca, 0x47, 0xe1, 0xf1, 0xcb, 0x0d, 0x13, 0x3f, 0x45, 0x34, 0x08, 0x2d, 0x16, 0xd0, 0x26, 0xf8, \ - 0x50, 0x46, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_control 384u -const dds_topic_descriptor_t DurableSupport_control_desc = -{ - .m_size = sizeof (DurableSupport_control), - .m_align = dds_alignof (DurableSupport_control), - .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 1u, - .m_typename = "DurableSupport::control", - .m_keys = DurableSupport_control_keys, - .m_nops = 3, - .m_ops = DurableSupport_control_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_control, .sz = TYPE_INFO_CDR_SZ_DurableSupport_control }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_control, .sz = TYPE_MAP_CDR_SZ_DurableSupport_control } -}; - -static const uint32_t DurableSupport_request_ops [] = -{ - /* request */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_EXT, offsetof (DurableSupport_request, key), (3u << 16u) + 9u /* request_key */, - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, client), 16u, - DDS_OP_ADR | DDS_OP_TYPE_8BY | DDS_OP_FLAG_SGN, offsetof (DurableSupport_request, timeout), - DDS_OP_RTS, - - /* request_key */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_key, rguid), 16u, - DDS_OP_RTS, - - /* key: key.rguid */ - DDS_OP_KOF | 2, 1u /* order: 0 */, 1u /* order: 0 */ -}; - -static const dds_key_descriptor_t DurableSupport_request_keys[1] = -{ - { "key.rguid", 15, 0 } -}; - -/* Type Information: - [MINIMAL 8b9080d97a1a0c3c5aa3da72955b] (#deps: 3) - - [MINIMAL a3976212b3d863bdaaf29cf722d7] - - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 84ce9c3d894c1483f859c00d5927] - [COMPLETE ffa88f3ac66a3c1ea9fb2cc3dcec] (#deps: 3) - - [COMPLETE c4f510554fa6a62cae1437b6364b] - - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE 023df3bd21223779cd1936cef928] -*/ -#define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ - 0xf0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x8b, 0x90, 0x80, 0xd9, 0x7a, 0x1a, 0x0c, 0x3c, 0x5a, 0xa3, 0xda, \ - 0x72, 0x95, 0x5b, 0x00, 0x75, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xa3, 0x97, 0x62, 0x12, 0xb3, 0xd8, 0x63, \ - 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, 0x00, 0x35, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, \ - 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xff, 0xa8, 0x8f, \ - 0x3a, 0xc6, 0x6a, 0x3c, 0x1e, 0xa9, 0xfb, 0x2c, 0xc3, 0xdc, 0xec, 0x00, 0xb2, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xc4, 0xf5, 0x10, 0x55, 0x4f, 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, 0x4b, 0x00, \ - 0x60, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ - 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ - 0x39, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_request 244u -#define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ - 0x1f, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf1, 0x8b, 0x90, 0x80, 0xd9, 0x7a, 0x1a, 0x0c, \ - 0x3c, 0x5a, 0xa3, 0xda, 0x72, 0x95, 0x5b, 0x00, 0x71, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0xa3, 0x97, 0x62, 0x12, 0xb3, \ - 0xd8, 0x63, 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, 0x3c, 0x6e, 0x0b, 0x8a, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ - 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0xa3, 0x97, \ - 0x62, 0x12, 0xb3, 0xd8, 0x63, 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, 0x31, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, \ - 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xaf, 0xc4, 0x1d, \ - 0xc3, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ - 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x84, \ - 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x00, 0x00, \ - 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x05, 0x00, 0xd1, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf2, 0xff, 0xa8, 0x8f, \ - 0x3a, 0xc6, 0x6a, 0x3c, 0x1e, 0xa9, 0xfb, 0x2c, 0xc3, 0xdc, 0xec, 0x00, 0xae, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x00, 0x82, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xc4, 0xf5, 0x10, 0x55, 0x4f, \ - 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, 0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, \ - 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, \ - 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xc4, \ - 0xf5, 0x10, 0x55, 0x4f, 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, 0x4b, 0x00, 0x00, 0x00, \ - 0x5c, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x1c, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, \ - 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x72, 0x67, 0x75, 0x69, 0x64, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ - 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ - 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0xf2, 0xff, 0xa8, 0x8f, 0x3a, 0xc6, 0x6a, 0x3c, 0x1e, 0xa9, 0xfb, 0x2c, \ - 0xc3, 0xdc, 0xec, 0xf1, 0x8b, 0x90, 0x80, 0xd9, 0x7a, 0x1a, 0x0c, 0x3c, 0x5a, 0xa3, 0xda, 0x72, \ - 0x95, 0x5b, 0xf2, 0xc4, 0xf5, 0x10, 0x55, 0x4f, 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, \ - 0x4b, 0xf1, 0xa3, 0x97, 0x62, 0x12, 0xb3, 0xd8, 0x63, 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, \ - 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, \ - 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, \ - 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_request 892u -const dds_topic_descriptor_t DurableSupport_request_desc = -{ - .m_size = sizeof (DurableSupport_request), - .m_align = dds_alignof (DurableSupport_request), - .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 1u, - .m_typename = "DurableSupport::request", - .m_keys = DurableSupport_request_keys, - .m_nops = 8, - .m_ops = DurableSupport_request_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request } -}; - -static const uint32_t DurableSupport_response_ops [] = -{ - /* response */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_response, id), 16u, - DDS_OP_ADR | DDS_OP_TYPE_EXT, offsetof (DurableSupport_response, body), (3u << 16u) + 4u /* response_content */, - DDS_OP_RTS, - - /* response_content */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_response_content, _d), 2u, (12u << 16u) + 4u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 9 /* response_set_t */, 1, offsetof (DurableSupport_response_content, _u.set), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 25 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, - DDS_OP_RTS, - - /* response_set_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_response_set_t, delivery_id), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_ARR, offsetof (DurableSupport_response_set_t, guids), sizeof (DurableSupport_id_t), (8u << 16u) + 4u, - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, 0u, 16u, - DDS_OP_RTS, - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, partition), - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, tpname), - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, type_id), - DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_response_set_t, flags), - DDS_OP_RTS, - - /* response_data_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_response_data_t, blob), - DDS_OP_RTS, - - /* key: id */ - DDS_OP_KOF | 1, 1u /* order: 0 */ -}; - -static const dds_key_descriptor_t DurableSupport_response_keys[1] = -{ - { "id", 46, 0 } -}; - -/* Type Information: - [MINIMAL afe8255284083dabd3ddf2d54e74] (#deps: 6) - - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 98ce0230d0ff9c4c40cabb2d52c3] - - [MINIMAL 80455e796dd3437163cb532089da] - - [MINIMAL e78d987aa9597510bc0942813b1e] - - [MINIMAL d8398b259af5a04792e296996c27] - - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE 96afe9e7626475acdc5483ed4445] (#deps: 6) - - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE 32546bec8365219448f85d5a510d] - - [COMPLETE eec1bad6badde73f40ef199fedcc] - - [COMPLETE 5af9ae0c63928c6db71150e723db] - - [COMPLETE 7b005a124ff7bda9c39eb4003556] - - [COMPLETE 008875599776c39ce0c1fe897846] -*/ -#define TYPE_INFO_CDR_DurableSupport_response (const unsigned char []){ \ - 0x80, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0xaf, 0xe8, 0x25, 0x52, 0x84, 0x08, 0x3d, 0xab, 0xd3, 0xdd, 0xf2, \ - 0xd5, 0x4e, 0x74, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, 0xff, 0x9c, 0x4c, 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0x00, \ - 0x7c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ - 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xe7, 0x8d, 0x98, 0x7a, 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, 0x3b, 0x1e, 0x00, \ - 0x9b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ - 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ - 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x96, 0xaf, 0xe9, 0xe7, 0x62, 0x64, 0x75, 0xac, 0xdc, 0x54, 0x83, \ - 0xed, 0x44, 0x45, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ - 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, 0x65, 0x21, 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0x00, \ - 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, \ - 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x5a, 0xf9, 0xae, 0x0c, 0x63, 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, 0xe7, 0x23, 0xdb, 0x00, \ - 0x04, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, \ - 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ - 0x57, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_response 388u -#define TYPE_MAP_CDR_DurableSupport_response (const unsigned char []){ \ - 0x54, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0xaf, 0xe8, 0x25, 0x52, 0x84, 0x08, 0x3d, \ - 0xab, 0xd3, 0xdd, 0xf2, 0xd5, 0x4e, 0x74, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, \ - 0xff, 0x9c, 0x4c, 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ - 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, \ - 0xff, 0x9c, 0x4c, 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ - 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ - 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ - 0x54, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0xe7, 0x8d, 0x98, 0x7a, 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, 0x3b, \ - 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ - 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ - 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ - 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0xe7, 0x8d, 0x98, 0x7a, \ - 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, 0x3b, 0x1e, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ - 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x7c, 0x4b, 0x99, \ - 0xfe, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, \ - 0x01, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, \ - 0x1a, 0x89, 0x0d, 0x36, 0x32, 0x3f, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, 0x0b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, \ - 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, \ - 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, \ - 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0xc7, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0xf2, 0x96, 0xaf, 0xe9, 0xe7, 0x62, 0x64, 0x75, 0xac, 0xdc, 0x54, 0x83, 0xed, 0x44, 0x45, 0x00, \ - 0x83, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, \ - 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, \ - 0x65, 0x21, 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ - 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, 0x65, 0x21, \ - 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, \ - 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, \ - 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, \ - 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ - 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5a, 0xf9, 0xae, 0x0c, 0x63, \ - 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, 0xe7, 0x23, 0xdb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, \ - 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, \ - 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, \ - 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, \ - 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x5a, 0xf9, \ - 0xae, 0x0c, 0x63, 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, 0xe7, 0x23, 0xdb, 0x00, 0x01, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, \ - 0xcc, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, \ - 0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, \ - 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ - 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x67, 0x75, 0x69, 0x64, \ - 0x73, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, \ - 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ - 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, \ - 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x5f, \ - 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xf2, 0x00, 0x88, \ - 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x53, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, \ - 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0x96, 0xaf, 0xe9, \ - 0xe7, 0x62, 0x64, 0x75, 0xac, 0xdc, 0x54, 0x83, 0xed, 0x44, 0x45, 0xf1, 0xaf, 0xe8, 0x25, 0x52, \ - 0x84, 0x08, 0x3d, 0xab, 0xd3, 0xdd, 0xf2, 0xd5, 0x4e, 0x74, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, \ - 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, 0x65, 0x21, \ - 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, 0xff, 0x9c, 0x4c, \ - 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ - 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, \ - 0x53, 0x20, 0x89, 0xda, 0xf2, 0x5a, 0xf9, 0xae, 0x0c, 0x63, 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, \ - 0xe7, 0x23, 0xdb, 0xf1, 0xe7, 0x8d, 0x98, 0x7a, 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, \ - 0x3b, 0x1e, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, \ - 0x56, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, \ - 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0xf1, \ - 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_response 1790u -const dds_topic_descriptor_t DurableSupport_response_desc = -{ - .m_size = sizeof (DurableSupport_response), - .m_align = dds_alignof (DurableSupport_response), - .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 1u, - .m_typename = "DurableSupport::response", - .m_keys = DurableSupport_response_keys, - .m_nops = 22, - .m_ops = DurableSupport_response_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_response, .sz = TYPE_INFO_CDR_SZ_DurableSupport_response }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_response, .sz = TYPE_MAP_CDR_SZ_DurableSupport_response } -}; diff --git a/src/durability/src/durablesupport.idl b/src/durability/src/durablesupport.idl new file mode 100644 index 0000000000..0e4d949512 --- /dev/null +++ b/src/durability/src/durablesupport.idl @@ -0,0 +1,71 @@ +module DurableSupport { + /******************** + * Generic + ********************/ + + /* generic typedef to identify ds services and writers; GUID compatible */ + typedef octet id_t[16]; + + @appendable + struct status { + @key id_t id; /* system wide unique service identifier */ + string hostname; /* name of the host where this ds is deployed */ + string name; /* human readable and user defined identification */ + }; + + /******************** + * Durable client + ********************/ + + /* duration */ + typedef long long duration_t; + + /* Type discriminator for responses */ + typedef unsigned short responsetype_t; + + /* delivery id to identify the delivery session */ + typedef unsigned long long delivery_id_t; + + @appendable @nested + struct request_key { + id_t rguid; /* the guid of the reader */ + }; + + @appendable + struct request { + @key request_key key; /* the key of the request topic */ + id_t client; /* the client expressing interest in historical data for this reader */ + duration_t timeout; /* optional maximum duration the client issuing the request expects to start receiving an answer. */ + }; + + /* List of supported response types */ + const responsetype_t RESPONSETYPE_SET = 1; + const responsetype_t RESPONSETYPE_DATA = 2; + + @appendable @nested + struct response_set_t { + delivery_id_t delivery_id; /* identification of the delivery; increases monotonically per set */ + sequence guids; /* the reader guids for which this set is intended */ + string partition; /* partition of this set */ + string tpname; /* topic name of this set */ + string type_id; /* type identification of this set */ + unsigned long flags; /* flags for this set */ + }; + + @appendable @nested + struct response_data_t { + sequence blob; + }; + + @appendable @nested + union response_content switch (responsetype_t) { + case RESPONSETYPE_SET : response_set_t set; + case RESPONSETYPE_DATA: response_data_t data; + }; + + @appendable + struct response { + @key id_t id; /* identification of the ds that produces this response */ + response_content body; + }; +}; From f292e0afb9728a1a51028258a50be8a1e0ffae03 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Wed, 15 May 2024 11:00:52 +0200 Subject: [PATCH 091/207] cdrstream test: do not overallocate extern string Flagged by the gcc 14.1 analyzer Signed-off-by: Erik Boasson --- src/core/ddsc/tests/cdrstream.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ddsc/tests/cdrstream.c b/src/core/ddsc/tests/cdrstream.c index d34f403064..652821d6d3 100644 --- a/src/core/ddsc/tests/cdrstream.c +++ b/src/core/ddsc/tests/cdrstream.c @@ -426,7 +426,7 @@ static void * sample_init_ext (void) TestIdl_MsgExt *msg = ddsrt_malloc (sizeof (*msg)); msg->f1 = ddsrt_strdup (RND_STR32); - msg->f2 = ddsrt_malloc (sizeof (*msg->f2) + 1); + msg->f2 = ddsrt_malloc (sizeof (*msg->f2)); ddsrt_strlcpy (*msg->f2, RND_STR32, sizeof (*msg->f2)); msg->f3 = ddsrt_malloc (sizeof (*msg->f3)); @@ -558,7 +558,7 @@ static void * sample_init_opt (void) } if (RND_INT32 % 2) { - msg->f4 = ddsrt_malloc (sizeof (*msg->f4) + 1); + msg->f4 = ddsrt_malloc (sizeof (*msg->f4)); ddsrt_strlcpy (*msg->f4, RND_STR32, sizeof (*msg->f4)); } if (RND_INT32 % 2) From d6bdcc12f57c463d1322599d3a82e8c8841fc61c Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Wed, 15 May 2024 11:01:31 +0200 Subject: [PATCH 092/207] ddsrt_init suppress gcc 14.1 infinite loop warning Signed-off-by: Erik Boasson --- src/ddsrt/src/cdtors.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ddsrt/src/cdtors.c b/src/ddsrt/src/cdtors.c index 8cbf279463..2ad66ce0c1 100644 --- a/src/ddsrt/src/cdtors.c +++ b/src/ddsrt/src/cdtors.c @@ -13,6 +13,7 @@ #include "dds/ddsrt/sync.h" #include "dds/ddsrt/time.h" #include "dds/ddsrt/random.h" +#include "dds/ddsrt/misc.h" #if _WIN32 /* Sockets API initialization is only necessary on Microsoft Windows. The @@ -31,6 +32,9 @@ static ddsrt_cond_t init_cond; void ddsrt_init (void) { +#if defined __GNUC__ && __GNUC__ >= 14 + DDSRT_WARNING_GNUC_OFF(analyzer-infinite-loop) +#endif uint32_t v; v = ddsrt_atomic_inc32_nv(&init_status); retry: @@ -59,6 +63,9 @@ void ddsrt_init (void) } goto retry; } +#if defined __GNUC__ && __GNUC__ >= 14 + DDSRT_WARNING_GNUC_ON(analyzer-infinite-loop) +#endif } void ddsrt_fini (void) From 9861c7938839c92846b125e869ec44e64ed1685d Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Wed, 15 May 2024 11:02:49 +0200 Subject: [PATCH 093/207] Help gcc 14.1 avoid false pos infinite recursion Signed-off-by: Erik Boasson --- .../builtin_plugins/access_control/src/access_control_utils.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/security/builtin_plugins/access_control/src/access_control_utils.c b/src/security/builtin_plugins/access_control/src/access_control_utils.c index 5dca356d40..8af6240c64 100644 --- a/src/security/builtin_plugins/access_control/src/access_control_utils.c +++ b/src/security/builtin_plugins/access_control/src/access_control_utils.c @@ -430,6 +430,10 @@ bool ac_fnmatch(const char* pat, const char* str) return true; while (*str != '\0') { + // Recursive call only after consuming some pattern and therefore not infinite + // Moreover, preceding loop guarantees that the recursive call doesn't start with '*' + // The assert makes a false positive warning from the gcc 14.1 analyzer go away + assert(*pat != '*'); ret = ac_fnmatch(pat, str); if (ret) return true; From ff67f4d7a55042107aa0dba855d2615df13f9da8 Mon Sep 17 00:00:00 2001 From: Patrick Masselink Date: Fri, 17 May 2024 17:48:41 +0200 Subject: [PATCH 094/207] Fix Zephyr ipv4 multicast support Signed-off-by: Patrick Masselink --- src/core/ddsi/src/ddsi_udp.c | 14 ++++++++++++-- src/ddsrt/include/dds/ddsrt/sockets/posix.h | 5 ----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/core/ddsi/src/ddsi_udp.c b/src/core/ddsi/src/ddsi_udp.c index 7321c211fa..5ad3b4b86d 100644 --- a/src/core/ddsi/src/ddsi_udp.c +++ b/src/core/ddsi/src/ddsi_udp.c @@ -726,14 +726,24 @@ static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const ddsi_lo rc = ddsrt_setsockopt (socket, IPPROTO_IPV6, join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP, &ipv6mreq, sizeof (ipv6mreq)); } else -#endif +#endif /* DDSRT_HAVE_IPV6 */ { +#if __ZEPHYR__ + struct ip_mreqn mreq; + mreq.imr_ifindex = 0; + if (interf) { + memcpy (&mreq.imr_address, interf->loc.address + 12, sizeof (mreq.imr_address)); + else + mreq.imr_address.s_addr = htonl (INADDR_ANY); +#else struct ip_mreq mreq; - mreq.imr_multiaddr = mcip.a4.sin_addr; if (interf) memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface)); else mreq.imr_interface.s_addr = htonl (INADDR_ANY); +#endif + + mreq.imr_multiaddr = mcip.a4.sin_addr; rc = ddsrt_setsockopt (socket, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreq, sizeof (mreq)); } return (rc == DDS_RETCODE_OK) ? 0 : -1; diff --git a/src/ddsrt/include/dds/ddsrt/sockets/posix.h b/src/ddsrt/include/dds/ddsrt/sockets/posix.h index a7e344132f..d8d49dc419 100644 --- a/src/ddsrt/include/dds/ddsrt/sockets/posix.h +++ b/src/ddsrt/include/dds/ddsrt/sockets/posix.h @@ -65,11 +65,6 @@ typedef struct ddsrt_socket_ext { # define IP_MULTICAST_TTL 33 # define IP_MULTICAST_LOOP 34 -struct ip_mreq { - struct in_addr imr_multiaddr; - struct in_addr imr_interface; -}; - /* for ddsrt_getifaddrs */ # define IFF_UP 0x1 # define IFF_BROADCAST 0x2 From bcec9542a0085bb1614a89df0c969f579fe4302e Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Wed, 15 May 2024 16:55:26 +0200 Subject: [PATCH 095/207] Improve create_participant/domain documentation Signed-off-by: Erik Boasson --- src/core/ddsc/include/dds/dds.h | 89 ++++++++++++++++----------------- 1 file changed, 42 insertions(+), 47 deletions(-) diff --git a/src/core/ddsc/include/dds/dds.h b/src/core/ddsc/include/dds/dds.h index b196553aae..96db93bbc6 100644 --- a/src/core/ddsc/include/dds/dds.h +++ b/src/core/ddsc/include/dds/dds.h @@ -976,13 +976,27 @@ dds_set_listener(dds_entity_t entity, const dds_listener_t * listener); * @ingroup domain_participant * @component participant * - * If domain is set (not DDS_DOMAIN_DEFAULT) then it must match if the domain has also - * been configured or an error status will be returned. - * Currently only a single domain can be configured by providing configuration file. - * If no configuration file exists, the default domain is configured as 0. - * - * - * @param[in] domain The domain in which to create the participant (can be DDS_DOMAIN_DEFAULT). DDS_DOMAIN_DEFAULT is for using the domain in the configuration. + * This function creates a new participant in the specified domain id, implicitly creating + * a domain entity if one doesn't exist for the specified domain id. The domain entity + * can exist as a consequence of the existence of another participant in it, or because it + * was explicitly created using @ref dds_create_domain or @ref + * dds_create_domain_with_rawconfig. If the domain entity has not been created yet, a new + * domain entity is created using a configuration taken from the CYCLONEDDS_URI + * environment variable. + * + * The domain id may be specified as DDS_DOMAIN_DEFAULT, in which case the behaviour + * depends on whether some domain entity already exists or not. If there is at least one, + * the one with the lowest id will be used. If there are none, one is created with the + * domain id taken from the first domain id specified in the configuration file (i.e., + * with a Domain element with the id attribute not "any"), and if no domain id is + * specified in the configuration file, domain id 0 is used. + * + * The domain configuration is constructed by amending the default configuration with the + * Domain configuration (fragments) for which the domain id is specifed as "any" and those + * for which the domain id matches the specified domain id (not DDS_DOMAIN_DEFAULT) in the + * order in which they are encountered in the configuration. + * + * @param[in] domain The domain in which to create the participant. * @param[in] qos The QoS to set on the new participant (can be NULL). * @param[in] listener Any listener functions associated with the new participant (can be NULL). @@ -1018,43 +1032,22 @@ dds_create_participant( * @ingroup domain * @component domain * - * To explicitly create a domain based on a configuration passed as a string. - * - * It will not be created if a domain with the given domain id already exists. - * This could have been created implicitly by a dds_create_participant(). + * To explicitly create a domain based on a configuration passed as a string. A domain + * created in this manner must be explicitly deleted by calling @ref dds_delete on the + * domain (or on DDS_CYCLONEDDS_HANDLE). * - * Please be aware that the given domain_id always takes precedence over the - * configuration. + * It will not be created if a domain with the given domain id already exists. This could + * have been created implicitly by a previous call to this function, @ref + * dds_create_participant or @ref dds_create_domain_with_rawconfig. * - * | domain_id | domain id in config | result | - * |:----------|:--------------------|:------------------------------| - * | n | any (or absent) | n, config is used | - * | n | m == n | n, config is used | - * | n | m != n | n, config is ignored: default | - * - * Config models: - * -# @code{xml} - * - * ... - * - * - * @endcode - * where ... is all that can today be set in children of CycloneDDS - * with the exception of the id - * -# @code{xml} - * - * X - * - * - * @endcode - * Legacy form, domain id must be the first element in the file with - * a value (if nothing has been set previously, it a warning is good - * enough) + * The domain configuration is constructed by amending the default configuration with the + * Domain configuration (fragments) for which the domain id is specifed as "any" and those + * for which the domain id matches the specified domain id in the order in which they are + * encountered in the configuration. * * Using NULL or "" as config will create a domain with default settings. * - * - * @param[in] domain The domain to be created. DEFAULT_DOMAIN is not allowed. + * @param[in] domain The domain to be created. DDS_DEFAULT_DOMAIN is not allowed. * @param[in] config A configuration string containing file names and/or XML fragments representing the configuration. * * @returns A valid entity handle or an error code. @@ -1076,19 +1069,21 @@ dds_create_domain(const dds_domainid_t domain, const char *config); * @component domain * @unstable * - * To explicitly create a domain based on a configuration passed as a raw - * initializer rather than as an XML string. This allows bypassing the XML - * parsing, but tightly couples the initializing to implementation. See - * dds/ddsi/ddsi_config.h:ddsi_config_init_default for a way to initialize - * the default configuration. + * To explicitly create a domain based on a configuration passed as a raw initializer + * rather than as an XML string. This allows bypassing the XML parsing, but tightly + * couples the initializing to implementation. See + * dds/ddsi/ddsi_config.h:ddsi_config_init_default for a way to initialize the default + * configuration. A domain created in this manner must be explicitly deleted by calling + * @ref dds_delete on the domain (or on DDS_CYCLONEDDS_HANDLE). * - * It will not be created if a domain with the given domain id already exists. - * This could have been created implicitly by a dds_create_participant(). + * It will not be created if a domain with the given domain id already exists. This could + * have been created implicitly by a previous call to this function, @ref + * dds_create_participant or @ref dds_create_domain_with_rawconfig. * * Please be aware that the given domain_id always takes precedence over the * configuration. * - * @param[in] domain The domain to be created. DEFAULT_DOMAIN is not allowed. + * @param[in] domain The domain to be created. DDS_DEFAULT_DOMAIN is not allowed. * @param[in] config A configuration initializer. The lifetime of any pointers * in config must be at least that of the lifetime of the domain. * From d315b88e797bba8e1e1c21e123ec199e009b45e6 Mon Sep 17 00:00:00 2001 From: Splinter1984 Date: Tue, 28 May 2024 11:17:38 +0200 Subject: [PATCH 096/207] b64_encode improvements for qos_provider tests --- src/core/ddsc/tests/qos_provider.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/core/ddsc/tests/qos_provider.c b/src/core/ddsc/tests/qos_provider.c index 848d6539b9..0fad947e7b 100644 --- a/src/core/ddsc/tests/qos_provider.c +++ b/src/core/ddsc/tests/qos_provider.c @@ -391,12 +391,13 @@ static uint32_t b64_encode (const unsigned char *text, const uint32_t sz, unsign for (size_t i = 0, j = 0; i < buff_len && j < sz; i+=4, j+=3) { unsigned char chunk[4] = {0x00, 0x00, 0x00, 0x00}; - chunk[0] = base64_etable[(text[j] >> 0x02U)]; - chunk[2] = base64_etable[((text[j+1] & 0x0FU) << 0x02U) | (text[j+2] & 0xC0U) >> 0x06U]; - chunk[1] = base64_etable[((text[j] & 0x03U) << 0x04U) | (text[j+1] >> 0x04U)]; - chunk[3] = base64_etable[text[j+2] & 0x3FU]; - size_t cp_sz = (sz - j) < 3? (sz - j) + 1: 4U; - (void) memcpy(*(buff)+i, chunk, cp_sz); + size_t cp_sz = (sz - j); + unsigned char tmp[3] = {text[j], (cp_sz > 1)? text[j+1]: 0x00, (cp_sz > 2)? text[j+2]: 0x00}; + chunk[3] = base64_etable[tmp[2] & 0x3FU]; + chunk[2] = base64_etable[((tmp[1] & 0x0FU) << 0x02U) | (tmp[2] & 0xC0U) >> 0x06U]; + chunk[1] = base64_etable[((tmp[0] & 0x03U) << 0x04U) | (tmp[1] >> 0x04U)]; + chunk[0] = base64_etable[(tmp[0] >> 0x02U)]; + (void) memcpy(*(buff)+i, chunk, cp_sz > 3? cp_sz + 1: 4U); } return buff_len; From e070ffc1237c33cb5b1a934e1d32d36ed30edf9b Mon Sep 17 00:00:00 2001 From: Splinter1984 Date: Tue, 28 May 2024 13:16:07 +0200 Subject: [PATCH 097/207] sysdef_parser tsn mac addresses support --- src/core/ddsc/src/dds__sysdef_model.h | 8 ++++++ src/core/ddsc/src/dds_sysdef_parser.c | 37 ++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/core/ddsc/src/dds__sysdef_model.h b/src/core/ddsc/src/dds__sysdef_model.h index b7da3656c2..85a1d24dcb 100644 --- a/src/core/ddsc/src/dds__sysdef_model.h +++ b/src/core/ddsc/src/dds__sysdef_model.h @@ -161,6 +161,12 @@ enum element_kind ELEMENT_KIND_DEPLOYMENT_CONF_TSN, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_VLAN_TAG, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_VLAN_TAG_PRIORITY_CODE_POINT, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_VLAN_TAG_VLAN_ID, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_MAC_ADDRESSES, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_MAC_ADDRESSES_DESTINATION_MAC_ADDRESS, + ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_MAC_ADDRESSES_SOURCE_MAC_ADDRESS, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_SOURCE_IP_ADDRESS, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_DESTINATION_IP_ADDRESS, @@ -606,6 +612,8 @@ struct dds_sysdef_tsn_ieee802_mac_addresses { char *source_mac_address; }; +#define SYSDEF_TSN_VLAN_TAG_PRIORITY_CODE_POINT_PARAM_VALUE (1 << 0u) +#define SYSDEF_TSN_VLAN_TAG_VLAN_ID_PARAM_VALUE (1 << 1u) struct dds_sysdef_tsn_ieee802_vlan_tag { struct xml_element xmlnode; uint8_t priority_code_point; diff --git a/src/core/ddsc/src/dds_sysdef_parser.c b/src/core/ddsc/src/dds_sysdef_parser.c index bbc029f25a..397c645c8d 100644 --- a/src/core/ddsc/src/dds_sysdef_parser.c +++ b/src/core/ddsc/src/dds_sysdef_parser.c @@ -503,6 +503,13 @@ static void fini_conf_tsn_ip_tuple (struct xml_element *node) ddsrt_free (conf->source_ip_address); } +static void fini_conf_tsn_mac_addresses (struct xml_element *node) +{ + struct dds_sysdef_tsn_ieee802_mac_addresses *conf = (struct dds_sysdef_tsn_ieee802_mac_addresses *) node; + ddsrt_free (conf->source_mac_address); + ddsrt_free (conf->destination_mac_address); +} + static void fini_conf_tsn_data_frame_specification (struct xml_element *node) { struct dds_sysdef_tsn_data_frame_specification *conf = (struct dds_sysdef_tsn_data_frame_specification *) node; @@ -2137,6 +2144,18 @@ static int proc_elem_data (void *varg, UNUSED_ARG (uintptr_t eleminfo), const ch } break; } + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_VLAN_TAG_PRIORITY_CODE_POINT: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_VLAN_TAG, dds_sysdef_tsn_ieee802_vlan_tag, uint8, priority_code_point, SYSDEF_TSN_VLAN_TAG_PRIORITY_CODE_POINT_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_VLAN_TAG_VLAN_ID: + PARENT_PARAM_DATA_NUMERIC(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_VLAN_TAG, dds_sysdef_tsn_ieee802_vlan_tag, uint16, vlan_id, SYSDEF_TSN_VLAN_TAG_VLAN_ID_PARAM_VALUE); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_MAC_ADDRESSES_DESTINATION_MAC_ADDRESS: + PARENT_PARAM_DATA_STRING(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_MAC_ADDRESSES, dds_sysdef_tsn_ieee802_mac_addresses, destination_mac_address); + break; + case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_MAC_ADDRESSES_SOURCE_MAC_ADDRESS: + PARENT_PARAM_DATA_STRING(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_MAC_ADDRESSES, dds_sysdef_tsn_ieee802_mac_addresses, source_mac_address); + break; case ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE_SOURCE_IP_ADDRESS: PARENT_PARAM_DATA_STRING(ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, dds_sysdef_tsn_ip_tuple, source_ip_address); break; @@ -2625,11 +2644,23 @@ static int proc_elem_open (void *varg, UNUSED_ARG (uintptr_t parentinfo), UNUSED else if (ddsrt_strcasecmp (name, "tsn_listener") == 0) CREATE_NODE_LIST (pstate, dds_sysdef_tsn_listener_configuration, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_LISTENER, NO_INIT, fini_conf_tsn_listener, tsn_listener_configurations, dds_sysdef_tsn_configuration, ELEMENT_KIND_DEPLOYMENT_CONF_TSN, pstate->current); else if (ddsrt_strcasecmp (name, "data_frame_specification") == 0) - CREATE_NODE_LIST (pstate, dds_sysdef_tsn_data_frame_specification, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC, NO_INIT, fini_conf_tsn_data_frame_specification, data_frame_specification, dds_sysdef_tsn_talker_configuration, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER, pstate->current); + CREATE_NODE_SINGLE (pstate, dds_sysdef_tsn_data_frame_specification, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC, NO_INIT, fini_conf_tsn_data_frame_specification, data_frame_specification, dds_sysdef_tsn_talker_configuration, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER, pstate->current); + else if (ddsrt_strcasecmp (name, "vlan_tag") == 0) + CREATE_NODE_SINGLE (pstate, dds_sysdef_tsn_ieee802_vlan_tag, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_VLAN_TAG, NO_INIT, NO_FINI, vlan_tag, dds_sysdef_tsn_data_frame_specification, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC, pstate->current); + else if (ddsrt_strcasecmp (name, "priority_code_point") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_VLAN_TAG_PRIORITY_CODE_POINT, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_VLAN_TAG, pstate->current); + else if (ddsrt_strcasecmp (name, "vlan_id") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_VLAN_TAG_VLAN_ID, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_VLAN_TAG, pstate->current); + else if (ddsrt_strcasecmp (name, "mac_addresses") == 0) + CREATE_NODE_SINGLE (pstate, dds_sysdef_tsn_ieee802_mac_addresses, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_MAC_ADDRESSES, NO_INIT, fini_conf_tsn_mac_addresses, mac_addresses, dds_sysdef_tsn_data_frame_specification, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC, pstate->current); + else if (ddsrt_strcasecmp (name, "destination_mac_address") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_MAC_ADDRESSES_DESTINATION_MAC_ADDRESS, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_MAC_ADDRESSES, pstate->current); + else if (ddsrt_strcasecmp (name, "source_mac_address") == 0) + CREATE_NODE_CUSTOM (pstate, dds_sysdef_qos_generic_property, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_MAC_ADDRESSES_SOURCE_MAC_ADDRESS, NO_INIT, NO_FINI, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_MAC_ADDRESSES, pstate->current); else if (ddsrt_strcasecmp (name, "ipv4_tuple") == 0) - CREATE_NODE_LIST (pstate, dds_sysdef_tsn_ip_tuple, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, NO_INIT, fini_conf_tsn_ip_tuple, ipv4_tuple, dds_sysdef_tsn_data_frame_specification, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC, pstate->current); + CREATE_NODE_SINGLE (pstate, dds_sysdef_tsn_ip_tuple, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE, NO_INIT, fini_conf_tsn_ip_tuple, ipv4_tuple, dds_sysdef_tsn_data_frame_specification, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC, pstate->current); else if (ddsrt_strcasecmp (name, "ipv6_tuple") == 0) - CREATE_NODE_LIST (pstate, dds_sysdef_tsn_ip_tuple, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, NO_INIT, fini_conf_tsn_ip_tuple, ipv6_tuple, dds_sysdef_tsn_data_frame_specification, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC, pstate->current); + CREATE_NODE_SINGLE (pstate, dds_sysdef_tsn_ip_tuple, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV6_TUPLE, NO_INIT, fini_conf_tsn_ip_tuple, ipv6_tuple, dds_sysdef_tsn_data_frame_specification, ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC, pstate->current); else if (ddsrt_strcasecmp (name, "source_ip_address") == 0) { if (pstate->current->kind == ELEMENT_KIND_DEPLOYMENT_CONF_TSN_TALKER_DATA_FRAME_SPEC_IPV4_TUPLE) From 12e115846221ab03b1ba707f3791fe8f47b1b510 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Thu, 23 May 2024 16:16:27 +0200 Subject: [PATCH 098/207] Support for IDL modules in XML parser This adds support to the XML sysdef parser for referring to types that are in a module (namespace) in the IDL, using :: as separator for the type name parts. A leading :: is not allowed, so that the type name syntax used here matches the type name used in the type object. Signed-off-by: Dennis Potman --- src/core/ddsc/src/dds__sysdef_parser.h | 2 ++ src/core/ddsc/src/dds_sysdef_parser.c | 43 +++++++++++++++++++++----- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/core/ddsc/src/dds__sysdef_parser.h b/src/core/ddsc/src/dds__sysdef_parser.h index 0c5d74e009..e726979f27 100644 --- a/src/core/ddsc/src/dds__sysdef_parser.h +++ b/src/core/ddsc/src/dds__sysdef_parser.h @@ -46,6 +46,8 @@ extern "C" { #define SD_PARSE_RESULT_INVALID_REF -5 #define SD_PARSE_RESULT_DUPLICATE -6 +#define SD_REF_SEPARATOR "::" + /** * @defgroup sysdef_parser (SysdefParser) */ diff --git a/src/core/ddsc/src/dds_sysdef_parser.c b/src/core/ddsc/src/dds_sysdef_parser.c index 397c645c8d..62efb65baf 100644 --- a/src/core/ddsc/src/dds_sysdef_parser.c +++ b/src/core/ddsc/src/dds_sysdef_parser.c @@ -179,6 +179,9 @@ struct parse_sysdef_state { char err_msg[MAX_ERRMSG_SZ]; }; +static bool dds_sysdef_is_valid_identifier_syntax (const char *name); + + static bool str_to_int32 (const char *str, int32_t *value) { char *endptr; @@ -613,6 +616,7 @@ static int init_qos (UNUSED_ARG (struct parse_sysdef_state * const pstate), stru } while (0) #define PROC_ATTR_NAME(type) PROC_ATTR_STRING(type, "name", name, dds_sysdef_is_valid_identifier_syntax) +#define PROC_ATTR_TYPE_NAME(type,attr_name,param_field) PROC_ATTR_STRING(type, attr_name, param_field, is_valid_type_name) #define _PROC_ATTR_INTEGER(type, attr_type, attr_name, param_field, param_populated_bit) \ do { \ @@ -778,7 +782,7 @@ static int proc_attr_resolve_topic_ref (struct parse_sysdef_state * const pstate static int split_ref (const char *ref, char **lib, char **local_name) { int ret = SD_PARSE_RESULT_OK; - const char *sep = "::"; + const char *sep = SD_REF_SEPARATOR; const char *spos = strstr (ref, sep); if (spos != NULL) { @@ -931,6 +935,29 @@ static int dds_sysdef_parse_hex (const char* hex, unsigned char* bytes) return SD_PARSE_RESULT_OK; } +static bool is_valid_type_name (const char *value) +{ + bool result = true; + const char *spos = NULL; + for (const char *str = value; result; str = spos + strlen (SD_REF_SEPARATOR)) + { + spos = strstr (str, SD_REF_SEPARATOR); + if (spos == NULL) + { + result = dds_sysdef_is_valid_identifier_syntax (str); + break; + } + + char *part = ddsrt_strndup (str, (size_t) (spos - str)); + /* A leading :: (empty first part) is not allowed; the type name + syntax used in the XML must matches the type name used in the + type object */ + result = dds_sysdef_is_valid_identifier_syntax (part); + ddsrt_free (part); + } + return result; +} + static int proc_attr_type_identifier (struct parse_sysdef_state * const pstate, const char *value, unsigned char **identifier) { (void) pstate; @@ -1011,7 +1038,7 @@ static int proc_attr (void *varg, UNUSED_ARG (uintptr_t eleminfo), const char *n { // Type library case ELEMENT_KIND_TYPE: - PROC_ATTR_NAME(dds_sysdef_type); + PROC_ATTR_TYPE_NAME(dds_sysdef_type, "name", name); PROC_ATTR_FN(dds_sysdef_type, "identifier", identifier, proc_attr_type_identifier); break; @@ -1049,7 +1076,7 @@ static int proc_attr (void *varg, UNUSED_ARG (uintptr_t eleminfo), const char *n PROC_ATTR_FN(dds_sysdef_participant, "guid_prefix", guid_prefix, proc_attr_guid_prefix); break; case ELEMENT_KIND_REGISTER_TYPE: - PROC_ATTR_NAME(dds_sysdef_register_type); + PROC_ATTR_TYPE_NAME(dds_sysdef_register_type, "name", name); PROC_ATTR_FN(dds_sysdef_register_type, "type_ref", type_ref, proc_attr_resolve_type_ref); break; case ELEMENT_KIND_PARTICIPANT_LIB: @@ -1616,7 +1643,7 @@ static int proc_elem_close (void *varg, UNUSED_ARG (uintptr_t eleminfo), UNUSED_ return ret; } -static const unsigned char base64_dtable[256] = { +static const unsigned char base64_dtable[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55, @@ -1635,15 +1662,15 @@ static uint32_t b64_decode (const unsigned char *text, const uint32_t sz, unsign for (size_t i = 0, j = 0; i < sz && j < buff_len; i+=4, j+=3) { unsigned char chunk[3] = {0x00, 0x00, 0x00}; - uint32_t tmp = (uint32_t)(base64_dtable[text[i]] << 0x06U) | base64_dtable[text[i+1]]; + uint32_t tmp = (uint32_t)(base64_dtable[text[i]] << 0x06U) | base64_dtable[text[i+1]]; uint32_t safe = tmp & 0x0FU; chunk[0] = (unsigned char)(tmp >> 0x04U); tmp = (safe << 0x0CU) | ((uint32_t)(base64_dtable[text[i+2]] << 0x06U) | base64_dtable[text[i+3]]); chunk[2] = (unsigned char)(tmp & 0xFFU); chunk[1] = (unsigned char)(tmp >> 0x08U); - size_t cp_sz = (buff_len - j) < 3? buff_len - j: 3; + size_t cp_sz = (buff_len - j) < 3? buff_len - j: 3; (void) memcpy(*buff+j, chunk, cp_sz); - } + } return buff_len; } @@ -1950,7 +1977,7 @@ static int proc_elem_data (void *varg, UNUSED_ARG (uintptr_t eleminfo), const ch struct parse_sysdef_state * const pstate = varg; int ret = SD_PARSE_RESULT_OK; if (pstate == NULL) { - return SD_PARSE_RESULT_ERR; + return SD_PARSE_RESULT_ERR; } if (!pstate->current) { From be0e64a641aebd25947c842d8fbf4e648b9ab392 Mon Sep 17 00:00:00 2001 From: Martijn Reicher Date: Wed, 29 May 2024 13:48:17 +0200 Subject: [PATCH 099/207] Fix bug in dds_request_loan_of_size The return code in case of dds_entity_pin failing would be "false", which is not a valid dds_return_t, also this equates to 0, which is DDS_RETCODE_OK, which is exactly NOT what it should return here Signed-off-by: Martijn Reicher --- src/core/ddsc/src/dds_psmx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ddsc/src/dds_psmx.c b/src/core/ddsc/src/dds_psmx.c index 7f613984d9..d382c1524d 100644 --- a/src/core/ddsc/src/dds_psmx.c +++ b/src/core/ddsc/src/dds_psmx.c @@ -549,8 +549,8 @@ dds_return_t dds_request_loan_of_size (dds_entity_t writer, size_t size, void ** dds_entity *e; dds_return_t ret = DDS_RETCODE_OK; - if (dds_entity_pin (writer, &e) != DDS_RETCODE_OK) - return false; + if ((ret = dds_entity_pin (writer, &e)) != DDS_RETCODE_OK) + return ret; if (dds_entity_kind (e) == DDS_KIND_WRITER) ret = dds_request_writer_loan ((struct dds_writer *) e, DDS_WRITER_LOAN_RAW, (uint32_t) size, sample); From e46c53350c2e71933bd2c58660e7247f46092eb1 Mon Sep 17 00:00:00 2001 From: Patrick Masselink Date: Tue, 4 Jun 2024 16:56:18 +0200 Subject: [PATCH 100/207] Remove invalid curly brace in Zephyr support code Signed-off-by: Patrick Masselink --- src/core/ddsi/src/ddsi_udp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ddsi/src/ddsi_udp.c b/src/core/ddsi/src/ddsi_udp.c index 5ad3b4b86d..6a68f398e7 100644 --- a/src/core/ddsi/src/ddsi_udp.c +++ b/src/core/ddsi/src/ddsi_udp.c @@ -731,7 +731,7 @@ static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const ddsi_lo #if __ZEPHYR__ struct ip_mreqn mreq; mreq.imr_ifindex = 0; - if (interf) { + if (interf) memcpy (&mreq.imr_address, interf->loc.address + 12, sizeof (mreq.imr_address)); else mreq.imr_address.s_addr = htonl (INADDR_ANY); From e3de8410864bc653e9f0408a3a435112930f7aee Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 11 Jun 2024 09:52:09 +0200 Subject: [PATCH 101/207] Bump CI platforms Signed-off-by: Erik Boasson --- .azure/templates/build-test.yml | 8 +++++ azure-pipelines.yml | 54 ++++++++++++--------------------- src/tools/idlpp/src/system.c | 2 +- 3 files changed, 29 insertions(+), 35 deletions(-) diff --git a/.azure/templates/build-test.yml b/.azure/templates/build-test.yml index c6a4f17765..78a8a8a60b 100644 --- a/.azure/templates/build-test.yml +++ b/.azure/templates/build-test.yml @@ -18,6 +18,7 @@ steps: - task: UsePythonVersion@0 inputs: versionSpec: '3.8' + condition: eq(variables['Agent.OS'], 'Windows_NT') name: install_python - bash: | # Asan in llvm 14 provided in ubuntu 22.04 is incompatible with @@ -46,6 +47,13 @@ steps: echo "###vso[task.setvariable variable=pip_cache;]${HOME}/Library/Caches/pip" echo "###vso[task.setvariable variable=PATH;]$(python3 -m site --user-base)/bin:${PATH}" echo "###vso[task.setvariable variable=build_tool_options;]-j 4" + # If preferred compiler version is not available, try updating homebrew and installing it + if which "$CC" ; then \ + echo "$CC" is already available ; \ + else \ + brew update ; \ + brew install "`echo "$CC" | sed -e 's/-/@/'`" ; \ + fi condition: eq(variables['Agent.OS'], 'Darwin') name: setup_macos # Use PowerShell rather than Bash to ensure Windows-style paths diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 88e76ab3d5..9b3b75cdce 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -24,23 +24,12 @@ jobs: vmImage: $(image) strategy: matrix: - #gcc-12.2 is the first version of gcc's static analyzer that accepts this code - #without -Wno-analyzer-malloc-leak without any false positives. Ubuntu is far - #behind in gcc versions, and so falling back to macOS is the most pragmatic - #option at this time. - #'Ubuntu 22.04 LTS with GCC 12 (Debug, x86_64)': - # image: ubuntu-22.04 - # analyzer: on - # # not enabling "undefined" because of some false positives - # sanitizer: address - # cc: gcc-12 - # coverage: on - 'Ubuntu 20.04 LTS with GCC 10 (Release, x86_64)': + 'Ubuntu 20.04 LTS (Release, x86_64)': image: ubuntu-20.04 build_type: Release sanitizer: undefined - cc: gcc-10 - 'Ubuntu 22.04 LTS with GCC 13 (Debug, x86_64, Iceoryx)': + cc: gcc + 'Ubuntu 22.04 LTS (Debug, x86_64, Iceoryx)': image: ubuntu-22.04 # No address sanitizer because of this in test run: # Shadow memory range interleaves with an existing memory mapping. @@ -49,13 +38,13 @@ jobs: # range. sanitizer: undefined iceoryx: on - cc: gcc-13 + cc: gcc coverage: on - 'Ubuntu 22.04 LTS with GCC 13 (Release, x86_64)': + 'Ubuntu 22.04 LTS (Release, x86_64)': image: ubuntu-22.04 build_type: Release sanitizer: undefined - cc: gcc-13 + cc: gcc 'Ubuntu 22.04 LTS with GCC 12 (Debug, x86_64, security only)': image: ubuntu-22.04 sanitizer: address,undefined @@ -71,39 +60,37 @@ jobs: cc: gcc-12 testing: off idlc_xtests: off - 'Ubuntu 22.04 LTS with Clang 15 (Debug, x86_64)': + 'Ubuntu 22.04 LTS with Clang (Debug, x86_64)': image: ubuntu-22.04 analyzer: on sanitizer: address,undefined - cc: clang-15 - 'Ubuntu 22.04 LTS with Clang 15 (Debug, x86_64, no security)': + cc: clang + 'Ubuntu 22.04 LTS with Clang (Debug, x86_64, no security)': image: ubuntu-22.04 sanitizer: address,undefined security: off - cc: clang-15 - 'Ubuntu 22.04 LTS with Clang 15 (Release, x86_64, no topic discovery)': + cc: clang + 'Ubuntu 22.04 LTS with Clang (Release, x86_64, no topic discovery)': image: ubuntu-22.04 build_type: Release sanitizer: undefined topic_discovery: off idlc_xtests: off # temporary disabled because of passing -t option to idlc in this test for recursive types - cc: clang-15 - 'macOS 13 with Clang 15 (Debug, x86_64)': - image: macos-13 + cc: clang + 'macOS 14 with Clang (Debug, x86_64)': + image: macos-14 sanitizer: address,undefined deadline_update_skip: on cc: clang - 'macOS 13 with Clang 15 (Release, x86_64)': - image: macos-13 + coverage: on + 'macOS 14 with Clang (Release, x86_64)': + image: macos-14 build_type: Release sanitizer: undefined - deadline_update_skip: on cc: clang - coverage: on - 'macOS 13 with gcc 13 (Debug, analyzer, x86_64)': - image: macos-13 - deadline_update_skip: on - cc: gcc-13 + 'macOS 14 with GCC 14 (Debug, analyzer, x86_64)': + image: macos-14 + cc: gcc-14 analyzer: on # 32-bit Windows: without SSL/security because Chocolateley only provides 64-bit OpenSSL 'Windows 2022 with Visual Studio 2022 (Debug, x86, no security)': @@ -113,7 +100,6 @@ jobs: security: off idlc_xtests: off generator: 'Visual Studio 17 2022' - toolset: v141 'Windows 2022 with Visual Studio 2022 (Debug, x86_64)': image: windows-2022 idlc_xtests: off diff --git a/src/tools/idlpp/src/system.c b/src/tools/idlpp/src/system.c index 9c55fc3abe..74ee280814 100644 --- a/src/tools/idlpp/src/system.c +++ b/src/tools/idlpp/src/system.c @@ -2517,7 +2517,7 @@ static char * norm_path( * open_file(). */ { -#if !defined (__clang__) && defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 1300 && ((__GNUC__ * 100) + __GNUC_MINOR__) < 1302 +#if !defined (__clang__) && defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 1100 && ((__GNUC__ * 100) + __GNUC_MINOR__) < 1302 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wstringop-overread\"") #endif From e1e2811c43c01c59e491e268ab28310791752565 Mon Sep 17 00:00:00 2001 From: Ivan Santiago Paunovic Date: Fri, 24 May 2024 22:44:11 -0300 Subject: [PATCH 102/207] Slightly improve dds_waitset_wait_impl() performance by avoinding to iterate over all conditions Signed-off-by: Ivan Santiago Paunovic --- src/core/ddsc/src/dds_waitset.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ddsc/src/dds_waitset.c b/src/core/ddsc/src/dds_waitset.c index e1978d16eb..6e18f1b6d7 100644 --- a/src/core/ddsc/src/dds_waitset.c +++ b/src/core/ddsc/src/dds_waitset.c @@ -64,8 +64,9 @@ static dds_return_t dds_waitset_wait_impl (dds_entity_t waitset, dds_attach_t *x /* Move any previously but no longer triggering entities back to the observed list */ ddsrt_mutex_lock (&ws->wait_lock); + size_t previous_ntriggered = ws->ntriggered; ws->ntriggered = 0; - for (size_t i = 0; i < ws->nentities; i++) + for (size_t i = 0; i < previous_ntriggered; i++) { if (is_triggered (ws->entities[i].entity)) { From d0a2df1bd6718c6ba695877e8fd2ad7b0a28c524 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Mon, 11 Mar 2024 15:41:25 +0100 Subject: [PATCH 103/207] Provide writer meta-data when storing loaned sample This commit adds the dds_reader_store_loaned_sample_wr_metadata that allows to provide certain writer meta-data when storing a loaned sample in the reader. This function can e.g. be used when using a PSMX implementation that received data from writers that are not matched (because there is no discovery). The additional parameters in this function are used to provide the reader history cache the information it needs for managing instance ownership and instance lifecycle. Signed-off-by: Dennis Potman --- .../ddsc/include/dds/ddsc/dds_loaned_sample.h | 24 +++++++++ src/core/ddsc/src/dds_reader.c | 52 ++++++++++++++----- .../ddsi/include/dds/ddsi/ddsi_endpoint.h | 5 +- src/core/ddsi/src/ddsi_endpoint.c | 20 ++++--- src/core/xtests/symbol_export/symbol_export.c | 1 + 5 files changed, 80 insertions(+), 22 deletions(-) diff --git a/src/core/ddsc/include/dds/ddsc/dds_loaned_sample.h b/src/core/ddsc/include/dds/ddsc/dds_loaned_sample.h index cc9469f0bb..f7c5189df4 100644 --- a/src/core/ddsc/include/dds/ddsc/dds_loaned_sample.h +++ b/src/core/ddsc/include/dds/ddsc/dds_loaned_sample.h @@ -133,6 +133,30 @@ DDS_INLINE_EXPORT inline void ddsrt_nonnull_all dds_loaned_sample_unref (dds_loa DDS_EXPORT dds_return_t dds_reader_store_loaned_sample (dds_entity_t reader, dds_loaned_sample_t *data) ddsrt_nonnull_all; +/** + * @brief insert data from a loaned sample into the reader history cache using the provided writer meta-data + * @ingroup reading + * + * @param[in] reader The reader entity. + * @param[in] data Pointer to the loaned sample of the entity received + * @param[in] ownership_strength The ownership strength of the writer + * @param[in] autodispose_unregistered_instances Writer setting for auto-disposing unregistered entities + * @param[in] lifespan_duration Lifespan duration value configured for the writer + * + * @returns A dds_return_t indicating success or failure. + * + * @retval DDS_RETCODE_OK + * The operation was successful. + * @retval DDS_RETCODE_BAD_PARAMETER + * One or more parameters are invalid. + * @retval DDS_RETCODE_ILLEGAL_OPERATION + * The operation is invoked on an inappropriate object. + * @retval DDS_RETCODE_ALREADY_DELETED + * The reader entity has already been deleted. + */ +DDS_EXPORT dds_return_t dds_reader_store_loaned_sample_wr_metadata (dds_entity_t reader, dds_loaned_sample_t *data, int32_t ownership_strength, bool autodispose_unregistered_instances, dds_duration_t lifespan_duration) + ddsrt_nonnull_all; + #if defined(__cplusplus) } #endif diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index ed38aba178..c7ef1dd321 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -697,7 +697,14 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe return rc; } -static dds_return_t get_writer_info (struct ddsi_domaingv *gv, dds_guid_t *dds_guid, uint32_t statusinfo, struct ddsi_writer_info *wi) +struct writer_metadata +{ + int32_t ownership_strength; + bool autodispose_unregistered_instances; + dds_duration_t lifespan_duration; +}; + +static dds_return_t get_writer_info (struct ddsi_domaingv *gv, dds_guid_t *dds_guid, uint32_t statusinfo, const struct writer_metadata *writer_md, struct ddsi_writer_info *wi) { dds_return_t ret = DDS_RETCODE_OK; struct dds_qos *xqos = NULL; @@ -706,24 +713,32 @@ static dds_return_t get_writer_info (struct ddsi_domaingv *gv, dds_guid_t *dds_g // FIXME ntoh required? memcpy (&guid, dds_guid, sizeof (guid)); - struct ddsi_entity_common *ec = ddsi_entidx_lookup_guid_untyped (gv->entity_index, &guid); - if (ec == NULL || (ec->kind != DDSI_EK_PROXY_WRITER && ec->kind != DDSI_EK_WRITER)) + if (writer_md == NULL) { - ret = DDS_RETCODE_NOT_FOUND; - goto err; + struct ddsi_entity_common *ec = ddsi_entidx_lookup_guid_untyped (gv->entity_index, &guid); + if (ec == NULL || (ec->kind != DDSI_EK_PROXY_WRITER && ec->kind != DDSI_EK_WRITER)) + { + ret = DDS_RETCODE_NOT_FOUND; + goto err; + } + else if (ec->kind == DDSI_EK_PROXY_WRITER) + xqos = ((struct ddsi_proxy_writer *) ec)->c.xqos; + else + xqos = ((struct ddsi_writer *) ec)->xqos; + + ddsi_make_writer_info (wi, ec, xqos, statusinfo); } - else if (ec->kind == DDSI_EK_PROXY_WRITER) - xqos = ((struct ddsi_proxy_writer *) ec)->c.xqos; else - xqos = ((struct ddsi_writer *) ec)->xqos; - - ddsi_make_writer_info (wi, ec, xqos, statusinfo); + { + uint64_t iid = ((uint64_t) guid.prefix.u[2] << 32llu) + guid.entityid.u; + ddsi_make_writer_info_params (wi, &guid, writer_md->ownership_strength, writer_md->autodispose_unregistered_instances, iid, statusinfo, writer_md->lifespan_duration); + } err: return ret; } -dds_return_t dds_reader_store_loaned_sample (dds_entity_t reader, dds_loaned_sample_t *data) +static dds_return_t dds_reader_store_loaned_sample_impl (dds_entity_t reader, dds_loaned_sample_t *data, const struct writer_metadata *writer_md) { dds_return_t ret; dds_entity * e; @@ -745,8 +760,6 @@ dds_return_t dds_reader_store_loaned_sample (dds_entity_t reader, dds_loaned_sam // FIXME: what if the sample is overwritten? // if the sample is not matched to this reader, return ownership to the PSMX? - // After this call, loaned sample (data) may be freed - dds_guid_t guid = data->metadata->guid; struct ddsi_serdata * sd = ddsi_serdata_from_psmx (rd->type, data); if (sd == NULL) { @@ -755,7 +768,7 @@ dds_return_t dds_reader_store_loaned_sample (dds_entity_t reader, dds_loaned_sam } struct ddsi_writer_info wi; - if ((ret = get_writer_info (gv, &guid, sd->statusinfo, &wi)) != DDS_RETCODE_OK) + if ((ret = get_writer_info (gv, &data->metadata->guid, sd->statusinfo, writer_md, &wi)) != DDS_RETCODE_OK) goto fail_get_writer_info; struct ddsi_tkmap_instance * tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, sd); @@ -782,6 +795,17 @@ dds_return_t dds_reader_store_loaned_sample (dds_entity_t reader, dds_loaned_sam return ret; } +dds_return_t dds_reader_store_loaned_sample (dds_entity_t reader, dds_loaned_sample_t *data) +{ + return dds_reader_store_loaned_sample_impl (reader, data, NULL); +} + +dds_return_t dds_reader_store_loaned_sample_wr_metadata (dds_entity_t reader, dds_loaned_sample_t *data, int32_t ownership_strength, bool autodispose_unregistered_instances, dds_duration_t lifespan_duration) +{ + struct writer_metadata writer_md = { .ownership_strength = ownership_strength, .autodispose_unregistered_instances = autodispose_unregistered_instances, .lifespan_duration = lifespan_duration }; + return dds_reader_store_loaned_sample_impl (reader, data, &writer_md); +} + dds_entity_t dds_create_reader (dds_entity_t participant_or_subscriber, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener) { return dds_create_reader_int (participant_or_subscriber, topic, qos, listener, NULL); diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_endpoint.h b/src/core/ddsi/include/dds/ddsi/ddsi_endpoint.h index 8aae34141f..1151b8aab3 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_endpoint.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_endpoint.h @@ -196,7 +196,10 @@ dds_return_t ddsi_new_writer (struct ddsi_writer **wr_out, struct ddsi_guid *wrg void ddsi_update_writer_qos (struct ddsi_writer *wr, const struct dds_qos *xqos); /** @component ddsi_endpoint */ -void ddsi_make_writer_info(struct ddsi_writer_info *wrinfo, const struct ddsi_entity_common *e, const struct dds_qos *xqos, uint32_t statusinfo); +void ddsi_make_writer_info (struct ddsi_writer_info *wrinfo, const struct ddsi_entity_common *e, const struct dds_qos *xqos, uint32_t statusinfo); + +/** @component ddsi_endpoint */ +void ddsi_make_writer_info_params (struct ddsi_writer_info *wrinfo, const ddsi_guid_t *wr_guid, int32_t ownership_strength, bool autodispose_unregistered_instances, uint64_t iid, uint32_t statusinfo, dds_duration_t lifespan_duration); /** @component ddsi_endpoint */ dds_return_t ddsi_writer_wait_for_acks (struct ddsi_writer *wr, const ddsi_guid_t *rdguid, dds_time_t abstimeout); diff --git a/src/core/ddsi/src/ddsi_endpoint.c b/src/core/ddsi/src/ddsi_endpoint.c index 8d8a5968b8..6ce3001b19 100644 --- a/src/core/ddsi/src/ddsi_endpoint.c +++ b/src/core/ddsi/src/ddsi_endpoint.c @@ -132,23 +132,29 @@ int ddsi_is_keyed_endpoint_entityid (ddsi_entityid_t id) } } -void ddsi_make_writer_info(struct ddsi_writer_info *wrinfo, const struct ddsi_entity_common *e, const struct dds_qos *xqos, uint32_t statusinfo) +void ddsi_make_writer_info_params (struct ddsi_writer_info *wrinfo, const ddsi_guid_t *wr_guid, int32_t ownership_strength, bool autodispose_unregistered_instances, uint64_t iid, uint32_t statusinfo, dds_duration_t lifespan_duration) { #ifndef DDS_HAS_LIFESPAN DDSRT_UNUSED_ARG (statusinfo); + DDSRT_UNUSED_ARG (lifespan_duration); #endif - wrinfo->guid = e->guid; - wrinfo->ownership_strength = xqos->ownership_strength.value; - wrinfo->auto_dispose = xqos->writer_data_lifecycle.autodispose_unregistered_instances; - wrinfo->iid = e->iid; + wrinfo->guid = *wr_guid; + wrinfo->ownership_strength = ownership_strength; + wrinfo->auto_dispose = autodispose_unregistered_instances; + wrinfo->iid = iid; #ifdef DDS_HAS_LIFESPAN - if (xqos->lifespan.duration != DDS_INFINITY && (statusinfo & (DDSI_STATUSINFO_UNREGISTER | DDSI_STATUSINFO_DISPOSE)) == 0) - wrinfo->lifespan_exp = ddsrt_mtime_add_duration(ddsrt_time_monotonic(), xqos->lifespan.duration); + if (lifespan_duration != DDS_INFINITY && (statusinfo & (DDSI_STATUSINFO_UNREGISTER | DDSI_STATUSINFO_DISPOSE)) == 0) + wrinfo->lifespan_exp = ddsrt_mtime_add_duration (ddsrt_time_monotonic (), lifespan_duration); else wrinfo->lifespan_exp = DDSRT_MTIME_NEVER; #endif } +void ddsi_make_writer_info (struct ddsi_writer_info *wrinfo, const struct ddsi_entity_common *e, const struct dds_qos *xqos, uint32_t statusinfo) +{ + ddsi_make_writer_info_params (wrinfo, &e->guid, xqos->ownership_strength.value, xqos->writer_data_lifecycle.autodispose_unregistered_instances, e->iid, statusinfo, xqos->lifespan.duration); +} + static uint32_t get_min_receive_buffer_size (struct ddsi_writer *wr) { uint32_t min_receive_buffer_size = UINT32_MAX; diff --git a/src/core/xtests/symbol_export/symbol_export.c b/src/core/xtests/symbol_export/symbol_export.c index 8eaa18730a..74f7f3bc66 100644 --- a/src/core/xtests/symbol_export/symbol_export.c +++ b/src/core/xtests/symbol_export/symbol_export.c @@ -522,6 +522,7 @@ int main (int argc, char **argv) dds_loaned_sample_ref (ptr); dds_loaned_sample_unref (ptr); dds_reader_store_loaned_sample (1, ptr); + dds_reader_store_loaned_sample_wr_metadata (0, ptr, 0, 0, 0); #ifdef DDS_HAS_SECURITY // dds_security_timed_cb.h From 5ed950088b80f334d8a2118ad8ee3a2963027a77 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Thu, 26 Oct 2023 17:38:59 +0200 Subject: [PATCH 104/207] Add user-defined log categories Reserve a number of log categories to be used by applications, so that these can use the Cyclone logging mechanism. Signed-off-by: Dennis Potman --- docs/manual/config/config_file_reference.rst | 14 +++++++++++--- docs/manual/options.md | 14 +++++++++++--- etc/cyclonedds.rnc | 10 +++++++--- etc/cyclonedds.xsd | 10 +++++++--- src/core/ddsi/defconfig.c | 4 ++-- src/core/ddsi/src/ddsi__cfgelems.h | 6 +++++- src/core/ddsi/src/ddsi_config.c | 4 ++-- src/ddsrt/include/dds/ddsrt/log.h | 8 +++++++- 8 files changed, 52 insertions(+), 18 deletions(-) diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index f006338727..a87911336c 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -2591,7 +2591,7 @@ The default value is: ``false`` ------------------------------------ One of: -* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, content, malformed, trace +* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, content, malformed, trace, user, user1, user2, user3 * Or empty This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are: @@ -2632,6 +2632,14 @@ This element enables individual logging categories. These are enabled in additio * malformed: dump malformed full packet as warning + * user: all user-defined tracing categories + + * user1: user-defined tracing category 1 + + * user2: user-defined tracing category 2 + + * user3: user-defined tracing category 3 + In addition, there is the keyword trace that enables: fatal, error, warning, info, config, discovery, data, trace, timing, traffic, tcp, throttle, content.. @@ -2698,8 +2706,8 @@ The default value is: ``none`` .. generated from ddsi_config.h[007a7968df8cbc42a122109bd139ac85bab0f6c9] generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] - generated from ddsi__cfgelems.h[607a8f573eb5d87d6f93b1d9bce2947f29da56dc] - generated from ddsi_config.c[d4ef67f90737b1bf8ae94ad932774fa015e3a2cf] + generated from ddsi__cfgelems.h[194217161977869610495a7889bbc1e6bc976ce1] + generated from ddsi_config.c[8c7ad90526d135063496f4a55e4e5992fa7bc72a] generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] diff --git a/docs/manual/options.md b/docs/manual/options.md index 756ef31c67..e1d4778154 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -1801,7 +1801,7 @@ The default value is: `false` #### //CycloneDDS/Domain/Tracing/Category One of: -* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, content, malformed, trace +* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, content, malformed, trace, user, user1, user2, user3 * Or empty This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are: @@ -1842,6 +1842,14 @@ This element enables individual logging categories. These are enabled in additio * malformed: dump malformed full packet as warning + * user: all user-defined tracing categories + + * user1: user-defined tracing category 1 + + * user2: user-defined tracing category 2 + + * user3: user-defined tracing category 3 + In addition, there is the keyword trace that enables: fatal, error, warning, info, config, discovery, data, trace, timing, traffic, tcp, throttle, content.. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is trace. @@ -1892,8 +1900,8 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: `none` - - + + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index 13525d3680..bb887862b5 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -1266,12 +1266,16 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==

  • plist: tracing of discovery parameter list interpretation
  • content: tracing of sample contents
  • malformed: dump malformed full packet as warning
  • +
  • user: all user-defined tracing categories
  • +
  • user1: user-defined tracing category 1
  • +
  • user2: user-defined tracing category 2
  • +
  • user3: user-defined tracing category 3
  • In addition, there is the keyword trace that enables: fatal, error, warning, info, config, discovery, data, trace, timing, traffic, tcp, throttle, content.

    .

    The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is trace.

    The default value is: <empty>

    """ ] ] element Category { - xsd:token { pattern = "((fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|malformed|trace)(,(fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|malformed|trace))*)|" } + xsd:token { pattern = "((fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|malformed|trace|user|user1|user2|user3)(,(fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|malformed|trace|user|user1|user2|user3))*)|" } }? & [ a:documentation [ xml:lang="en" """

    This option specifies where the logging is printed to. Note that stdout and stderr are treated as special values, representing "standard out" and "standard error" respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings.

    @@ -1311,8 +1315,8 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
    } # generated from ddsi_config.h[007a7968df8cbc42a122109bd139ac85bab0f6c9] # generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] -# generated from ddsi__cfgelems.h[607a8f573eb5d87d6f93b1d9bce2947f29da56dc] -# generated from ddsi_config.c[d4ef67f90737b1bf8ae94ad932774fa015e3a2cf] +# generated from ddsi__cfgelems.h[194217161977869610495a7889bbc1e6bc976ce1] +# generated from ddsi_config.c[8c7ad90526d135063496f4a55e4e5992fa7bc72a] # generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] # generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] # generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index 7bb7f013b2..121b51cdd9 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -1892,6 +1892,10 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> <li><i>plist</i>: tracing of discovery parameter list interpretation</li> <li><i>content</i>: tracing of sample contents</li> <li><i>malformed</i>: dump malformed full packet as warning</li> +<li><i>user</i>: all user-defined tracing categories</li> +<li><i>user1</i>: user-defined tracing category 1</li> +<li><i>user2</i>: user-defined tracing category 2</li> +<li><i>user3</i>: user-defined tracing category 3</li> </ul> <p>In addition, there is the keyword <i>trace</i> that enables: <i>fatal</i>, <i>error</i>, <i>warning</i>, <i>info</i>, <i>config</i>, <i>discovery</i>, <i>data</i>, <i>trace</i>, <i>timing</i>, <i>traffic</i>, <i>tcp</i>, <i>throttle</i>, <i>content</i>.</p>. <p>The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is <i>trace</i>.</p> @@ -1899,7 +1903,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - +
    @@ -1969,8 +1973,8 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - - + + diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index f268c3b5ac..655cc6a61c 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -101,8 +101,8 @@ void ddsi_config_init_default (struct ddsi_config *cfg) } /* generated from ddsi_config.h[007a7968df8cbc42a122109bd139ac85bab0f6c9] */ /* generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] */ -/* generated from ddsi__cfgelems.h[607a8f573eb5d87d6f93b1d9bce2947f29da56dc] */ -/* generated from ddsi_config.c[d4ef67f90737b1bf8ae94ad932774fa015e3a2cf] */ +/* generated from ddsi__cfgelems.h[194217161977869610495a7889bbc1e6bc976ce1] */ +/* generated from ddsi_config.c[8c7ad90526d135063496f4a55e4e5992fa7bc72a] */ /* generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] */ /* generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] */ /* generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] */ diff --git a/src/core/ddsi/src/ddsi__cfgelems.h b/src/core/ddsi/src/ddsi__cfgelems.h index f6d08f5b9d..2b17969bb6 100644 --- a/src/core/ddsi/src/ddsi__cfgelems.h +++ b/src/core/ddsi/src/ddsi__cfgelems.h @@ -2013,6 +2013,10 @@ static struct cfgelem tracing_cfgelems[] = { "
  • plist: tracing of discovery parameter list interpretation
  • \n" "
  • content: tracing of sample contents
  • \n" "
  • malformed: dump malformed full packet as warning
  • \n" + "
  • user: all user-defined tracing categories
  • \n" + "
  • user1: user-defined tracing category 1
  • \n" + "
  • user2: user-defined tracing category 2
  • \n" + "
  • user3: user-defined tracing category 3
  • \n" "\n" "

    In addition, there is the keyword trace that enables: " "fatal, error, warning, info, config, " @@ -2026,7 +2030,7 @@ static struct cfgelem tracing_cfgelems[] = { VALUES( "fatal","error","warning","info","config","discovery","data","radmin", "timing","traffic","topic","tcp","plist","whc","throttle","rhc", - "content","malformed","trace" + "content","malformed","trace","user","user1","user2","user3" )), ENUM("Verbosity", NULL, 1, "none", NOMEMBER, diff --git a/src/core/ddsi/src/ddsi_config.c b/src/core/ddsi/src/ddsi_config.c index 0ee326451e..4c72227619 100644 --- a/src/core/ddsi/src/ddsi_config.c +++ b/src/core/ddsi/src/ddsi_config.c @@ -1007,10 +1007,10 @@ GENERIC_ENUM_CTYPE (shm_loglevel, enum ddsi_shm_loglevel) /* "trace" is special: it enables (nearly) everything */ static const char *tracemask_names[] = { - "fatal", "error", "warning", "info", "config", "discovery", "data", "radmin", "timing", "traffic", "topic", "tcp", "plist", "whc", "throttle", "rhc", "content", "malformed", "trace", NULL + "fatal", "error", "warning", "info", "config", "discovery", "data", "radmin", "timing", "traffic", "topic", "tcp", "plist", "whc", "throttle", "rhc", "content", "malformed", "user1", "user2", "user3", "user", "trace", NULL }; static const uint32_t tracemask_codes[] = { - DDS_LC_FATAL, DDS_LC_ERROR, DDS_LC_WARNING, DDS_LC_INFO, DDS_LC_CONFIG, DDS_LC_DISCOVERY, DDS_LC_DATA, DDS_LC_RADMIN, DDS_LC_TIMING, DDS_LC_TRAFFIC, DDS_LC_TOPIC, DDS_LC_TCP, DDS_LC_PLIST, DDS_LC_WHC, DDS_LC_THROTTLE, DDS_LC_RHC, DDS_LC_CONTENT, DDS_LC_MALFORMED, DDS_LC_ALL + DDS_LC_FATAL, DDS_LC_ERROR, DDS_LC_WARNING, DDS_LC_INFO, DDS_LC_CONFIG, DDS_LC_DISCOVERY, DDS_LC_DATA, DDS_LC_RADMIN, DDS_LC_TIMING, DDS_LC_TRAFFIC, DDS_LC_TOPIC, DDS_LC_TCP, DDS_LC_PLIST, DDS_LC_WHC, DDS_LC_THROTTLE, DDS_LC_RHC, DDS_LC_CONTENT, DDS_LC_MALFORMED, DDS_LC_USER1, DDS_LC_USER2, DDS_LC_USER3, DDS_LC_USER, DDS_LC_ALL }; static enum update_result uf_tracemask (struct ddsi_cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) diff --git a/src/ddsrt/include/dds/ddsrt/log.h b/src/ddsrt/include/dds/ddsrt/log.h index 8e05864ff4..c4971b1f0a 100644 --- a/src/ddsrt/include/dds/ddsrt/log.h +++ b/src/ddsrt/include/dds/ddsrt/log.h @@ -82,12 +82,18 @@ extern "C" { #define DDS_LC_SYSDEF (524288u) /** Debug/trace messages related to qos provider. */ #define DDS_LC_QOSPROV (1048576u) +/** Reserved for user defined log categories (e.g. user application that uses Cyclone logger) */ +#define DDS_LC_USER1 (1u << 29) +#define DDS_LC_USER2 (1u << 30) +#define DDS_LC_USER3 (1u << 31) +#define DDS_LC_USER (DDS_LC_USER1 | DDS_LC_USER2 | DDS_LC_USER3) + /** All common trace categories. */ #define DDS_LC_ALL \ (DDS_LC_FATAL | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_INFO | \ DDS_LC_CONFIG | DDS_LC_DISCOVERY | DDS_LC_DATA | DDS_LC_TRACE | \ DDS_LC_TIMING | DDS_LC_TRAFFIC | DDS_LC_TCP | DDS_LC_THROTTLE | \ - DDS_LC_CONTENT) + DDS_LC_CONTENT | DDS_LC_USER) /** @}*/ #define DDS_LOG_MASK \ From 093269707bdd8e5c97eccbc407fe101aff47a242 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Tue, 21 Nov 2023 12:12:24 +0100 Subject: [PATCH 105/207] Add create-participant-with-guid function Adds function to create a participant with a specific GUID. Signed-off-by: Dennis Potman --- .../ddsc/include/dds/ddsc/dds_internal_api.h | 19 ++++++++++++ src/core/ddsc/src/dds_participant.c | 30 +++++++++++++++---- .../ddsi/include/dds/ddsi/ddsi_participant.h | 26 ++++++++-------- src/core/ddsi/src/ddsi_participant.c | 14 ++++----- src/core/ddsi/tests/plist_leasedur.c | 1 + src/core/ddsi/tests/pmd_message.c | 1 + src/core/ddsi/tests/wraddrset.c | 1 + src/core/xtests/symbol_export/symbol_export.c | 1 + 8 files changed, 69 insertions(+), 24 deletions(-) diff --git a/src/core/ddsc/include/dds/ddsc/dds_internal_api.h b/src/core/ddsc/include/dds/ddsc/dds_internal_api.h index 4b9f64b67e..24c733d5d1 100644 --- a/src/core/ddsc/include/dds/ddsc/dds_internal_api.h +++ b/src/core/ddsc/include/dds/ddsc/dds_internal_api.h @@ -15,6 +15,7 @@ #define DDS_INTERNAL_API_H #include "dds/export.h" +#include "dds/dds.h" #include "dds/cdr/dds_cdrstream.h" #if defined (__cplusplus) @@ -34,6 +35,24 @@ extern "C" { DDS_EXPORT void dds_cdrstream_desc_from_topic_desc (struct dds_cdrstream_desc *desc, const dds_topic_descriptor_t *topic_desc); +/** + * @ingroup internal + * @component participant + * @unstable + * @brief Create a participant with the specified GUID + * + * @param[in] domain The domain in which to create the participant (can be DDS_DOMAIN_DEFAULT). DDS_DOMAIN_DEFAULT is for using the domain in the configuration. + * @param[in] qos The QoS to set on the new participant (can be NULL). + * @param[in] listener Any listener functions associated with the new participant (can be NULL). + * @param[in] flags The flags to be used when creating the participant + * @param[in] guid The GUID for the new participant + * + * @returns A valid participant handle or an error code. @see dds_create_participant for details + */ +DDS_EXPORT dds_entity_t +dds_create_participant_guid (const dds_domainid_t domain, const dds_qos_t *qos, const dds_listener_t *listener, uint32_t flags, const dds_guid_t *guid); + + #if defined (__cplusplus) } #endif diff --git a/src/core/ddsc/src/dds_participant.c b/src/core/ddsc/src/dds_participant.c index bb661c36fb..2fd791a3f9 100644 --- a/src/core/ddsc/src/dds_participant.c +++ b/src/core/ddsc/src/dds_participant.c @@ -91,11 +91,11 @@ const struct dds_entity_deriver dds_entity_deriver_participant = { .invoke_cbs_for_pending_events = dds_entity_deriver_dummy_invoke_cbs_for_pending_events }; -dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_t *qos, const dds_listener_t *listener) +static dds_entity_t create_participant_flags_guid (const dds_domainid_t domain, const dds_qos_t *qos, const dds_listener_t *listener, uint32_t flags, const dds_guid_t *guid) { dds_domain *dom; dds_entity_t ret; - ddsi_guid_t guid; + ddsi_guid_t ddsi_guid; dds_participant * pp; ddsi_plist_t plist; dds_qos_t *new_qos = NULL; @@ -132,7 +132,16 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ ddsi_xqos_mergein_missing (&plist.qos, new_qos, ~(uint64_t)0); ddsi_thread_state_awake (ddsi_lookup_thread_state (), &dom->gv); - ret = ddsi_new_participant (&guid, &dom->gv, 0, &plist); + if (guid == NULL) + ddsi_generate_participant_guid (&ddsi_guid, &dom->gv); + else + { + ddsi_guid_t ddsi_guid_tmp; + DDSRT_STATIC_ASSERT (sizeof (dds_guid_t) == sizeof (ddsi_guid_t)); + memcpy (&ddsi_guid_tmp, guid, sizeof (ddsi_guid_tmp)); + ddsi_guid = ddsi_ntoh_guid (ddsi_guid_tmp); + } + ret = ddsi_new_participant (&ddsi_guid, &dom->gv, flags, &plist); ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); ddsi_plist_fini (&plist); if (ret < 0) @@ -145,8 +154,8 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ if ((ret = dds_entity_init (&pp->m_entity, &dom->m_entity, DDS_KIND_PARTICIPANT, false, true, new_qos, listener, DDS_PARTICIPANT_STATUS_MASK)) < 0) goto err_entity_init; - pp->m_entity.m_guid = guid; - pp->m_entity.m_iid = ddsi_get_entity_instanceid (&dom->gv, &guid); + pp->m_entity.m_guid = ddsi_guid; + pp->m_entity.m_iid = ddsi_get_entity_instanceid (&dom->gv, &ddsi_guid); pp->m_entity.m_domain = dom; pp->m_builtin_subscriber = 0; ddsrt_avl_init (&participant_ktopics_treedef, &pp->m_ktopics); @@ -174,6 +183,17 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ return ret; } +dds_entity_t dds_create_participant_guid (const dds_domainid_t domain, const dds_qos_t *qos, const dds_listener_t *listener, uint32_t flags, const dds_guid_t *guid) +{ + return create_participant_flags_guid (domain, qos, listener, flags, guid); +} + +dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_t *qos, const dds_listener_t *listener) +{ + return create_participant_flags_guid (domain, qos, listener, 0, NULL); +} + + dds_return_t dds_lookup_participant (dds_domainid_t domain_id, dds_entity_t *participants, size_t size) { dds_return_t ret; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_participant.h b/src/core/ddsi/include/dds/ddsi/ddsi_participant.h index 1d68f57f6c..e02d304b37 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_participant.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_participant.h @@ -62,12 +62,19 @@ struct ddsi_participant }; /** - * @brief Create a new participant in the domain + * @brief Generates a new participant GUID + * + * @param[out] ppguid The generated participant GUID + * @param[in] gv Domain globals + */ +void ddsi_generate_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv); + +/** + * @brief Create a new participant with a specified GUID * @component ddsi_participant * - * @param[out] ppguid - * On successful return: the GUID of the new participant; - * Undefined on error. + * @param[in] ppguid The GUID for the new participant + * @param[in] gv Domain globals * @param[in] flags * Zero or more of: * - RTPS_PF_NO_BUILTIN_READERS do not create discovery readers in new ppant @@ -75,21 +82,16 @@ struct ddsi_participant * - RTPS_PF_PRIVILEGED_PP FIXME: figure out how to describe this ... * - RTPS_PF_IS_DDSI2_PP FIXME: OSPL holdover - there is no DDSI2E here * - RTPS_PF_ONLY_LOCAL FIXME: not used, it seems - * @param[in] plist - * Parameters/QoS for this participant + * @param[in] plist Parameters/QoS for this participant * * @returns A dds_return_t indicating success or failure. * * @retval DDS_RETCODE_OK - * Success, there is now a local participant with the GUID stored in - * *ppguid - * @retval DDS_RETCODE_OUT_OF_RESOURCES - * Failed to allocate a new GUID (note: currently this will always - * happen after 2**24-1 successful calls to new_participant ...). + * Success * @retval DDS_RETCODE_OUT_OF_RESOURCES * The configured maximum number of participants has been reached. */ -dds_return_t ddsi_new_participant (struct ddsi_guid *ppguid, struct ddsi_domaingv *gv, unsigned flags, const struct ddsi_plist *plist); +dds_return_t ddsi_new_participant (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv, unsigned flags, const struct ddsi_plist *plist); /** * @component ddsi_participant diff --git a/src/core/ddsi/src/ddsi_participant.c b/src/core/ddsi/src/ddsi_participant.c index 42d6ff0247..398852a9d2 100644 --- a/src/core/ddsi/src/ddsi_participant.c +++ b/src/core/ddsi/src/ddsi_participant.c @@ -771,7 +771,7 @@ void ddsi_unref_participant (struct ddsi_participant *pp, const struct ddsi_guid } } -static dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv, unsigned flags, const ddsi_plist_t *plist) +dds_return_t ddsi_new_participant (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv, unsigned flags, const ddsi_plist_t *plist) { struct ddsi_participant *pp; ddsi_guid_t subguid, group_guid; @@ -1013,17 +1013,17 @@ static dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domai return ret; } -dds_return_t ddsi_new_participant (ddsi_guid_t *p_ppguid, struct ddsi_domaingv *gv, unsigned flags, const ddsi_plist_t *plist) +void ddsi_generate_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv) { union { uint64_t u64; uint32_t u32[2]; } u; u.u32[0] = gv->ppguid_base.prefix.u[1]; u.u32[1] = gv->ppguid_base.prefix.u[2]; u.u64 += ddsi_iid_gen (); - p_ppguid->prefix.u[0] = gv->ppguid_base.prefix.u[0]; - p_ppguid->prefix.u[1] = u.u32[0]; - p_ppguid->prefix.u[2] = u.u32[1]; - p_ppguid->entityid.u = DDSI_ENTITYID_PARTICIPANT; - return new_participant_guid (p_ppguid, gv, flags, plist); + + ppguid->prefix.u[0] = gv->ppguid_base.prefix.u[0]; + ppguid->prefix.u[1] = u.u32[0]; + ppguid->prefix.u[2] = u.u32[1]; + ppguid->entityid.u = DDSI_ENTITYID_PARTICIPANT; } void ddsi_update_participant_plist (struct ddsi_participant *pp, const ddsi_plist_t *plist) diff --git a/src/core/ddsi/tests/plist_leasedur.c b/src/core/ddsi/tests/plist_leasedur.c index b56711010c..0d32165ebf 100644 --- a/src/core/ddsi/tests/plist_leasedur.c +++ b/src/core/ddsi/tests/plist_leasedur.c @@ -368,6 +368,7 @@ static void ddsi_plist_leasedur_new_proxyrd_impl (bool include_lease_duration) plist.qos.liveliness.kind = DDS_LIVELINESS_AUTOMATIC; plist.qos.liveliness.lease_duration = DDS_SECS (10); ddsi_thread_state_awake (thrst, &gv); + ddsi_generate_participant_guid (&ppguid, &gv); dds_return_t ret = ddsi_new_participant (&ppguid, &gv, RTPS_PF_PRIVILEGED_PP | RTPS_PF_IS_DDSI2_PP, &plist); ddsi_thread_state_asleep (thrst); CU_ASSERT_FATAL (ret >= 0); diff --git a/src/core/ddsi/tests/pmd_message.c b/src/core/ddsi/tests/pmd_message.c index 6460dfc799..bb0107d3c0 100644 --- a/src/core/ddsi/tests/pmd_message.c +++ b/src/core/ddsi/tests/pmd_message.c @@ -227,6 +227,7 @@ static void create_fake_proxy_participant (void) ddsi_plist_init_empty (&plist); ddsi_xqos_mergein_missing (&plist.qos, &gv.default_local_xqos_pp, ~(uint64_t)0); ddsi_thread_state_awake (thrst, &gv); + ddsi_generate_participant_guid (&ppguid, &gv); dds_return_t ret = ddsi_new_participant (&ppguid, &gv, RTPS_PF_IS_DDSI2_PP | RTPS_PF_PRIVILEGED_PP, &plist); ddsi_thread_state_asleep (thrst); ddsi_plist_fini (&plist); diff --git a/src/core/ddsi/tests/wraddrset.c b/src/core/ddsi/tests/wraddrset.c index f8f1708faa..93e77969c8 100644 --- a/src/core/ddsi/tests/wraddrset.c +++ b/src/core/ddsi/tests/wraddrset.c @@ -145,6 +145,7 @@ static void ddsi_wraddrset_some_cases (int casenumber, int cost, bool wr_psmx, c setup_and_start (); ddsi_thread_state_awake (ddsi_lookup_thread_state(), &gv); + ddsi_generate_participant_guid (&wrppguid, &gv); ddsi_new_participant (&wrppguid, &gv, RTPS_PF_PRIVILEGED_PP | RTPS_PF_IS_DDSI2_PP, &plist_pp[0]); const struct ddsi_sertype st = { diff --git a/src/core/xtests/symbol_export/symbol_export.c b/src/core/xtests/symbol_export/symbol_export.c index 74f7f3bc66..13dd91c791 100644 --- a/src/core/xtests/symbol_export/symbol_export.c +++ b/src/core/xtests/symbol_export/symbol_export.c @@ -145,6 +145,7 @@ int main (int argc, char **argv) dds_get_listener (1, ptr); dds_set_listener (1, ptr); dds_create_participant (0, ptr, ptr); + dds_create_participant_guid (1, ptr, ptr2, 0, ptr3); dds_create_domain (0, ptr); dds_create_domain_with_rawconfig (0, ptr); dds_get_parent (1); From 39a909e95b1250f0cf99ad7caf6db8eaba7c00f6 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Wed, 29 Nov 2023 08:56:31 +0100 Subject: [PATCH 106/207] Add create-endpoint-with-guid Add functions for creating DDS readers and writers with a specific GUID. Signed-off-by: Dennis Potman --- .../ddsc/include/dds/ddsc/dds_internal_api.h | 33 ++++++++++++ src/core/ddsc/src/dds_reader.c | 46 +++++++++++++--- src/core/ddsc/src/dds_writer.c | 36 +++++++++++-- .../ddsi/include/dds/ddsi/ddsi_endpoint.h | 10 +++- src/core/ddsi/src/ddsi__endpoint.h | 6 --- src/core/ddsi/src/ddsi_endpoint.c | 37 +++++-------- src/core/ddsi/src/ddsi_participant.c | 52 +++++++++---------- src/core/ddsi/tests/wraddrset.c | 3 ++ src/core/xtests/symbol_export/symbol_export.c | 2 + 9 files changed, 158 insertions(+), 67 deletions(-) diff --git a/src/core/ddsc/include/dds/ddsc/dds_internal_api.h b/src/core/ddsc/include/dds/ddsc/dds_internal_api.h index 24c733d5d1..0eb786a1de 100644 --- a/src/core/ddsc/include/dds/ddsc/dds_internal_api.h +++ b/src/core/ddsc/include/dds/ddsc/dds_internal_api.h @@ -52,6 +52,39 @@ dds_cdrstream_desc_from_topic_desc (struct dds_cdrstream_desc *desc, const dds_t DDS_EXPORT dds_entity_t dds_create_participant_guid (const dds_domainid_t domain, const dds_qos_t *qos, const dds_listener_t *listener, uint32_t flags, const dds_guid_t *guid); +/** + * @ingroup internal + * @component writer + * @unstable + * @brief Create a writer with the specified GUID + * + * @param[in] participant_or_publisher The participant or publisher on which the writer is being created. + * @param[in] topic The topic to write. + * @param[in] qos The QoS to set on the new writer (can be NULL). + * @param[in] listener Any listener functions associated with the new writer (can be NULL). + * @param[in] guid The GUID for the new writer + * + * @returns A valid writer handle or an error code. @see dds_create_writer for details + */ +DDS_EXPORT dds_entity_t +dds_create_writer_guid (dds_entity_t participant_or_publisher, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener, dds_guid_t *guid); + +/** + * @ingroup internal + * @component reader + * @unstable + * @brief Create a reader with the specified GUID + * + * @param[in] participant_or_subscriber The participant or subscriber on which the reader is being created. + * @param[in] topic The topic to read. + * @param[in] qos The QoS to set on the new reader (can be NULL). + * @param[in] listener Any listener functions associated with the new reader (can be NULL). + * @param[in] guid The GUID for the new reader + * + * @returns A valid reader handle or an error code. @see dds_create_reader for details + */ +DDS_EXPORT dds_entity_t +dds_create_reader_guid (dds_entity_t participant_or_subscriber, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener, dds_guid_t *guid); #if defined (__cplusplus) } diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index c7ef1dd321..fc76c17cb4 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -27,6 +27,7 @@ #include "dds/ddsi/ddsi_endpoint_match.h" #include "dds/ddsi/ddsi_tkmap.h" #include "dds/ddsc/dds_rhc.h" +#include "dds/ddsc/dds_internal_api.h" #include "dds__participant.h" #include "dds__subscriber.h" #include "dds__reader.h" @@ -483,7 +484,7 @@ const struct dds_entity_deriver dds_entity_deriver_reader = { .invoke_cbs_for_pending_events = dds_reader_invoke_cbs_for_pending_events }; -static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscriber, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener, struct dds_rhc *rhc) +static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscriber, dds_entity_t topic, dds_guid_t *guid, const dds_qos_t *qos, const dds_listener_t *listener, struct dds_rhc *rhc) { dds_subscriber *sub = NULL; dds_entity_t subscriber; @@ -605,7 +606,7 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe { rc = DDS_RETCODE_NOT_ALLOWED_BY_SECURITY; ddsi_thread_state_asleep(ddsi_lookup_thread_state()); - goto err_bad_qos; + goto err_not_allowed; } } #endif @@ -637,7 +638,10 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe dds_entity_add_ref_locked (&tp->m_entity); if ((rc = dds_endpoint_add_psmx_endpoint (&rd->m_endpoint, rqos, &tp->m_ktopic->psmx_topics, DDS_PSMX_ENDPOINT_TYPE_READER)) != DDS_RETCODE_OK) + { + ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); goto err_create_endpoint; + } /* FIXME: listeners can come too soon ... should set mask based on listeners then atomically set the listeners, save the mask to a pending set and clear @@ -645,11 +649,32 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe dds_entity_init_complete (&rd->m_entity); + if (guid == NULL) + { + rc = ddsi_generate_reader_guid (&rd->m_entity.m_guid, pp, tp->m_stype); + if (rc != DDS_RETCODE_OK) + { + ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); + goto err_rd_guid; + } + } + else + { + ddsi_guid_t ddsi_guid; + DDSRT_STATIC_ASSERT (sizeof (dds_guid_t) == sizeof (ddsi_guid_t)); + memcpy (&ddsi_guid, guid, sizeof (ddsi_guid)); + rd->m_entity.m_guid = ddsi_ntoh_guid (ddsi_guid); + } + struct ddsi_psmx_locators_set *vl_set = dds_get_psmx_locators_set (rqos, &rd->m_entity.m_domain->psmx_instances); + /* Reader gets the sertype from the topic, as the serdata functions the reader uses are not specific for a data representation (the representation can be retrieved from the cdr header) */ - struct ddsi_psmx_locators_set *vl_set = dds_get_psmx_locators_set (rqos, &rd->m_entity.m_domain->psmx_instances); rc = ddsi_new_reader (&rd->m_rd, &rd->m_entity.m_guid, NULL, pp, tp->m_name, tp->m_stype, rqos, &rd->m_rhc->common.rhc, dds_reader_status_cb, rd, vl_set); - assert (rc == DDS_RETCODE_OK); /* FIXME: can be out-of-resources at the very least */ + if (rc != DDS_RETCODE_OK) + { + /* FIXME: can be out-of-resources at the very least; would leak allocated entity id */ + abort (); + } dds_psmx_locators_set_free (vl_set); ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); @@ -680,9 +705,13 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe return reader; err_psmx_endpoint_setcb: +err_rd_guid: dds_endpoint_remove_psmx_endpoints (&rd->m_endpoint); err_create_endpoint: err_bad_qos: +#ifdef DDS_HAS_SECURITY +err_not_allowed: +#endif err_data_repr: err_psmx: if (own_rqos) @@ -808,14 +837,19 @@ dds_return_t dds_reader_store_loaned_sample_wr_metadata (dds_entity_t reader, dd dds_entity_t dds_create_reader (dds_entity_t participant_or_subscriber, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener) { - return dds_create_reader_int (participant_or_subscriber, topic, qos, listener, NULL); + return dds_create_reader_int (participant_or_subscriber, topic, NULL, qos, listener, NULL); +} + +dds_entity_t dds_create_reader_guid (dds_entity_t participant_or_subscriber, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener, dds_guid_t *guid) +{ + return dds_create_reader_int (participant_or_subscriber, topic, guid, qos, listener, NULL); } dds_entity_t dds_create_reader_rhc (dds_entity_t participant_or_subscriber, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener, struct dds_rhc *rhc) { if (rhc == NULL) return DDS_RETCODE_BAD_PARAMETER; - return dds_create_reader_int (participant_or_subscriber, topic, qos, listener, rhc); + return dds_create_reader_int (participant_or_subscriber, topic, NULL, qos, listener, rhc); } dds_return_t dds_reader_wait_for_historical_data (dds_entity_t reader, dds_duration_t max_wait) diff --git a/src/core/ddsc/src/dds_writer.c b/src/core/ddsc/src/dds_writer.c index 85d8961cb9..96928fcb30 100644 --- a/src/core/ddsc/src/dds_writer.c +++ b/src/core/ddsc/src/dds_writer.c @@ -27,6 +27,7 @@ #include "dds/ddsi/ddsi_statistics.h" #include "dds/ddsi/ddsi_sertype.h" #include "dds/cdr/dds_cdrstream.h" +#include "dds/ddsc/dds_internal_api.h" #include "dds__writer.h" #include "dds__listener.h" #include "dds__init.h" @@ -298,7 +299,8 @@ const struct dds_entity_deriver dds_entity_deriver_writer = { .invoke_cbs_for_pending_events = dds_writer_invoke_cbs_for_pending_events }; -dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener) + +static dds_entity_t dds_create_writer_int (dds_entity_t participant_or_publisher, dds_guid_t *guid, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener) { dds_return_t rc; dds_publisher *pub = NULL; @@ -427,9 +429,26 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit if (!sertype) sertype = tp->m_stype; + if (guid == NULL) + { + rc = ddsi_generate_writer_guid (&wr->m_entity.m_guid, pp, sertype); + if (rc != DDS_RETCODE_OK) + goto err_wr_guid; + } + else + { + ddsi_guid_t ddsi_guid; + DDSRT_STATIC_ASSERT (sizeof (dds_guid_t) == sizeof (ddsi_guid_t)); + memcpy (&ddsi_guid, guid, sizeof (ddsi_guid)); + wr->m_entity.m_guid = ddsi_ntoh_guid (ddsi_guid); + } struct ddsi_psmx_locators_set *vl_set = dds_get_psmx_locators_set (wqos, &wr->m_entity.m_domain->psmx_instances); rc = ddsi_new_writer (&wr->m_wr, &wr->m_entity.m_guid, NULL, pp, tp->m_name, sertype, wqos, wr->m_whc, dds_writer_status_cb, wr, vl_set); - assert(rc == DDS_RETCODE_OK); + if (rc != DDS_RETCODE_OK) + { + /* FIXME: can be out-of-resources at the very least; would leak allocated entity id */ + abort (); + } dds_psmx_locators_set_free (vl_set); ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); @@ -452,11 +471,12 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit ddsrt_mutex_unlock (&gv->sendq_running_lock); return writer; +err_wr_guid: err_pipe_open: #ifdef DDS_HAS_SECURITY err_not_allowed: - ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); #endif + ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); err_bad_qos: err_data_repr: err_psmx: @@ -472,6 +492,16 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit return rc; } +dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener) +{ + return dds_create_writer_int (participant_or_publisher, NULL, topic, qos, listener); +} + +dds_entity_t dds_create_writer_guid (dds_entity_t participant_or_publisher, dds_entity_t topic, const dds_qos_t *qos, const dds_listener_t *listener, dds_guid_t *guid) +{ + return dds_create_writer_int (participant_or_publisher, guid, topic, qos, listener); +} + dds_entity_t dds_get_publisher (dds_entity_t writer) { dds_entity *e; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_endpoint.h b/src/core/ddsi/include/dds/ddsi/ddsi_endpoint.h index 1151b8aab3..b37325c2c8 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_endpoint.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_endpoint.h @@ -190,7 +190,10 @@ struct ddsi_local_orphan_writer *ddsi_new_local_orphan_writer (struct ddsi_domai void ddsi_delete_local_orphan_writer (struct ddsi_local_orphan_writer *wr); /** @component ddsi_endpoint */ -dds_return_t ddsi_new_writer (struct ddsi_writer **wr_out, struct ddsi_guid *wrguid, const struct ddsi_guid *group_guid, struct ddsi_participant *pp, const char *topic_name, const struct ddsi_sertype *type, const struct dds_qos *xqos, struct ddsi_whc * whc, ddsi_status_cb_t status_cb, void *status_cb_arg, struct ddsi_psmx_locators_set *psmx_locators); +dds_return_t ddsi_generate_writer_guid (struct ddsi_guid *wrguid, struct ddsi_participant *participant, const struct ddsi_sertype *sertype); + +/** @component ddsi_endpoint */ +dds_return_t ddsi_new_writer (struct ddsi_writer **wr_out, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct ddsi_participant *pp, const char *topic_name, const struct ddsi_sertype *type, const struct dds_qos *xqos, struct ddsi_whc *whc, ddsi_status_cb_t status_cb, void *status_entity, struct ddsi_psmx_locators_set *psmx_locators); /** @component ddsi_endpoint */ void ddsi_update_writer_qos (struct ddsi_writer *wr, const struct dds_qos *xqos); @@ -217,7 +220,10 @@ struct ddsi_reader *ddsi_writer_first_in_sync_reader (struct ddsi_entity_index * struct ddsi_reader *ddsi_writer_next_in_sync_reader (struct ddsi_entity_index *entity_index, ddsrt_avl_iter_t *it); /** @component ddsi_endpoint */ -dds_return_t ddsi_new_reader (struct ddsi_reader **rd_out, struct ddsi_guid *rdguid, const struct ddsi_guid *group_guid, struct ddsi_participant *pp, const char *topic_name, const struct ddsi_sertype *type, const struct dds_qos *xqos, struct ddsi_rhc * rhc, ddsi_status_cb_t status_cb, void *status_cb_arg, struct ddsi_psmx_locators_set *psmx_locators); +dds_return_t ddsi_generate_reader_guid (struct ddsi_guid *rdguid, struct ddsi_participant *participant, const struct ddsi_sertype *sertype); + +/** @component ddsi_endpoint */ +dds_return_t ddsi_new_reader (struct ddsi_reader **rd_out, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct ddsi_participant *pp, const char *topic_name, const struct ddsi_sertype *type, const struct dds_qos *xqos, struct ddsi_rhc *rhc, ddsi_status_cb_t status_cb, void * status_entity, struct ddsi_psmx_locators_set *psmx_locators); /** @component ddsi_endpoint */ void ddsi_update_reader_qos (struct ddsi_reader *rd, const struct dds_qos *xqos); diff --git a/src/core/ddsi/src/ddsi__endpoint.h b/src/core/ddsi/src/ddsi__endpoint.h index b150abbcc6..8a7f13de03 100644 --- a/src/core/ddsi/src/ddsi__endpoint.h +++ b/src/core/ddsi/src/ddsi__endpoint.h @@ -59,9 +59,6 @@ int ddsi_is_keyed_endpoint_entityid (ddsi_entityid_t id); /** @component ddsi_endpoint */ int ddsi_is_builtin_volatile_endpoint (ddsi_entityid_t id); -/** @component ddsi_endpoint */ -dds_return_t ddsi_new_writer_guid (struct ddsi_writer **wr_out, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct ddsi_participant *pp, const char *topic_name, const struct ddsi_sertype *type, const struct dds_qos *xqos, struct ddsi_whc *whc, ddsi_status_cb_t status_cb, void *status_entity, struct ddsi_psmx_locators_set *psmx_locators); - /** @component ddsi_endpoint */ int ddsi_is_writer_entityid (ddsi_entityid_t id); @@ -98,9 +95,6 @@ void ddsi_writer_set_alive_may_unlock (struct ddsi_writer *wr, bool notify); /** @component ddsi_endpoint */ int ddsi_writer_set_notalive (struct ddsi_writer *wr, bool notify); -/** @component ddsi_endpoint */ -dds_return_t ddsi_new_reader_guid (struct ddsi_reader **rd_out, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct ddsi_participant *pp, const char *topic_name, const struct ddsi_sertype *type, const struct dds_qos *xqos, struct ddsi_rhc *rhc, ddsi_status_cb_t status_cb, void * status_entity, struct ddsi_psmx_locators_set *psmx_locators); - /** @component ddsi_endpoint */ int ddsi_is_reader_entityid (ddsi_entityid_t id); diff --git a/src/core/ddsi/src/ddsi_endpoint.c b/src/core/ddsi/src/ddsi_endpoint.c index 6ce3001b19..2b66387b47 100644 --- a/src/core/ddsi/src/ddsi_endpoint.c +++ b/src/core/ddsi/src/ddsi_endpoint.c @@ -960,7 +960,7 @@ static void ddsi_new_writer_guid_common_init (struct ddsi_writer *wr, const char ddsi_local_reader_ary_init (&wr->rdary); } -dds_return_t ddsi_new_writer_guid (struct ddsi_writer **wr_out, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct ddsi_participant *pp, const char *topic_name, const struct ddsi_sertype *type, const struct dds_qos *xqos, struct ddsi_whc *whc, ddsi_status_cb_t status_cb, void *status_entity, struct ddsi_psmx_locators_set *psmx_locators) +dds_return_t ddsi_new_writer (struct ddsi_writer **wr_out, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct ddsi_participant *pp, const char *topic_name, const struct ddsi_sertype *type, const struct dds_qos *xqos, struct ddsi_whc *whc, ddsi_status_cb_t status_cb, void *status_entity, struct ddsi_psmx_locators_set *psmx_locators) { struct ddsi_writer *wr; ddsrt_mtime_t tnow = ddsrt_time_monotonic (); @@ -1044,19 +1044,13 @@ dds_return_t ddsi_new_writer_guid (struct ddsi_writer **wr_out, const struct dds return 0; } -dds_return_t ddsi_new_writer (struct ddsi_writer **wr_out, struct ddsi_guid *wrguid, const struct ddsi_guid *group_guid, struct ddsi_participant *pp, const char *topic_name, const struct ddsi_sertype *type, const struct dds_qos *xqos, struct ddsi_whc * whc, ddsi_status_cb_t status_cb, void *status_cb_arg, struct ddsi_psmx_locators_set *psmx_locators) +dds_return_t ddsi_generate_writer_guid (struct ddsi_guid *wrguid, struct ddsi_participant *participant, const struct ddsi_sertype *sertype) { - dds_return_t rc; - uint32_t kind; - - /* participant can't be freed while we're mucking around cos we are - awake and do not touch the thread's vtime (entidx_lookup already - verifies we're awake) */ - wrguid->prefix = pp->e.guid.prefix; - kind = type->has_key ? DDSI_ENTITYID_KIND_WRITER_WITH_KEY : DDSI_ENTITYID_KIND_WRITER_NO_KEY; - if ((rc = ddsi_participant_allocate_entityid (&wrguid->entityid, kind, pp)) < 0) - return rc; - return ddsi_new_writer_guid (wr_out, wrguid, group_guid, pp, topic_name, type, xqos, whc, status_cb, status_cb_arg, psmx_locators); + /* participant can't be freed while we're mucking around cos we are awake and do not touch the thread's vtime + (entidx_lookup already verifies we're awake) */ + wrguid->prefix = participant->e.guid.prefix; + uint32_t kind = sertype->has_key ? DDSI_ENTITYID_KIND_WRITER_WITH_KEY : DDSI_ENTITYID_KIND_WRITER_NO_KEY; + return ddsi_participant_allocate_entityid (&wrguid->entityid, kind, participant); } struct ddsi_local_orphan_writer *ddsi_new_local_orphan_writer (struct ddsi_domaingv *gv, ddsi_entityid_t entityid, const char *topic_name, struct ddsi_sertype *type, const struct dds_qos *xqos, struct ddsi_whc *whc) @@ -1479,9 +1473,9 @@ static void reader_init_network_partition (struct ddsi_reader *rd) } #endif /* DDS_HAS_NETWORK_PARTITIONS */ -dds_return_t ddsi_new_reader_guid (struct ddsi_reader **rd_out, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct ddsi_participant *pp, const char *topic_name, const struct ddsi_sertype *type, const struct dds_qos *xqos, struct ddsi_rhc *rhc, ddsi_status_cb_t status_cb, void * status_entity, struct ddsi_psmx_locators_set *psmx_locators) +dds_return_t ddsi_new_reader (struct ddsi_reader **rd_out, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct ddsi_participant *pp, const char *topic_name, const struct ddsi_sertype *type, const struct dds_qos *xqos, struct ddsi_rhc *rhc, ddsi_status_cb_t status_cb, void * status_entity, struct ddsi_psmx_locators_set *psmx_locators) { - /* see ddsi_new_writer_guid for commenets */ + /* see ddsi_new_writer for commenets */ struct ddsi_reader *rd; ddsrt_mtime_t tnow = ddsrt_time_monotonic (); @@ -1565,16 +1559,11 @@ dds_return_t ddsi_new_reader_guid (struct ddsi_reader **rd_out, const struct dds return 0; } -dds_return_t ddsi_new_reader (struct ddsi_reader **rd_out, struct ddsi_guid *rdguid, const struct ddsi_guid *group_guid, struct ddsi_participant *pp, const char *topic_name, const struct ddsi_sertype *type, const struct dds_qos *xqos, struct ddsi_rhc * rhc, ddsi_status_cb_t status_cb, void *status_cb_arg, struct ddsi_psmx_locators_set *psmx_locators) +dds_return_t ddsi_generate_reader_guid (struct ddsi_guid *rdguid, struct ddsi_participant *participant, const struct ddsi_sertype *sertype) { - dds_return_t rc; - uint32_t kind; - - rdguid->prefix = pp->e.guid.prefix; - kind = type->has_key ? DDSI_ENTITYID_KIND_READER_WITH_KEY : DDSI_ENTITYID_KIND_READER_NO_KEY; - if ((rc = ddsi_participant_allocate_entityid (&rdguid->entityid, kind, pp)) < 0) - return rc; - return ddsi_new_reader_guid (rd_out, rdguid, group_guid, pp, topic_name, type, xqos, rhc, status_cb, status_cb_arg, psmx_locators); + rdguid->prefix = participant->e.guid.prefix; + uint32_t kind = sertype->has_key ? DDSI_ENTITYID_KIND_READER_WITH_KEY : DDSI_ENTITYID_KIND_READER_NO_KEY; + return ddsi_participant_allocate_entityid (&rdguid->entityid, kind, participant); } static void gc_delete_reader (struct ddsi_gcreq *gcreq) diff --git a/src/core/ddsi/src/ddsi_participant.c b/src/core/ddsi/src/ddsi_participant.c index 398852a9d2..a3a59340a8 100644 --- a/src/core/ddsi/src/ddsi_participant.c +++ b/src/core/ddsi/src/ddsi_participant.c @@ -198,7 +198,7 @@ static void add_security_builtin_endpoints (struct ddsi_participant *pp, ddsi_gu subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER); wrinfo = dds_whc_make_wrinfo (NULL, &gv->builtin_endpoint_xqos_wr); - ddsi_new_writer_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_SECURE_NAME, gv->spdp_secure_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo), NULL, NULL, NULL); + ddsi_new_writer (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_SECURE_NAME, gv->spdp_secure_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo), NULL, NULL, NULL); dds_whc_free_wrinfo (wrinfo); /* But we need the as_disc address set for SPDP, because we need to send it to everyone regardless of the existence of readers. */ @@ -207,28 +207,28 @@ static void add_security_builtin_endpoints (struct ddsi_participant *pp, ddsi_gu subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER); wrinfo = dds_whc_make_wrinfo (NULL, &gv->builtin_stateless_xqos_wr); - ddsi_new_writer_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_STATELESS_MESSAGE_NAME, gv->pgm_stateless_type, &gv->builtin_stateless_xqos_wr, dds_whc_new(gv, wrinfo), NULL, NULL, NULL); + ddsi_new_writer (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_STATELESS_MESSAGE_NAME, gv->pgm_stateless_type, &gv->builtin_stateless_xqos_wr, dds_whc_new(gv, wrinfo), NULL, NULL, NULL); dds_whc_free_wrinfo (wrinfo); pp->bes |= DDSI_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_ANNOUNCER; subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER); wrinfo = dds_whc_make_wrinfo (NULL, &gv->builtin_secure_volatile_xqos_wr); - ddsi_new_writer_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_VOLATILE_MESSAGE_SECURE_NAME, gv->pgm_volatile_type, &gv->builtin_secure_volatile_xqos_wr, dds_whc_new(gv, wrinfo), NULL, NULL, NULL); + ddsi_new_writer (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_VOLATILE_MESSAGE_SECURE_NAME, gv->pgm_volatile_type, &gv->builtin_secure_volatile_xqos_wr, dds_whc_new(gv, wrinfo), NULL, NULL, NULL); dds_whc_free_wrinfo (wrinfo); pp->bes |= DDSI_BUILTIN_ENDPOINT_PARTICIPANT_VOLATILE_SECURE_ANNOUNCER; wrinfo = dds_whc_make_wrinfo (NULL, &gv->builtin_endpoint_xqos_wr); subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER); - ddsi_new_writer_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_MESSAGE_SECURE_NAME, gv->pmd_secure_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo), NULL, NULL, NULL); + ddsi_new_writer (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_MESSAGE_SECURE_NAME, gv->pmd_secure_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo), NULL, NULL, NULL); pp->bes |= DDSI_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_SECURE_ANNOUNCER; subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER); - ddsi_new_writer_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PUBLICATION_SECURE_NAME, gv->sedp_writer_secure_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo), NULL, NULL, NULL); + ddsi_new_writer (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PUBLICATION_SECURE_NAME, gv->sedp_writer_secure_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo), NULL, NULL, NULL); pp->bes |= DDSI_BUILTIN_ENDPOINT_PUBLICATION_MESSAGE_SECURE_ANNOUNCER; subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER); - ddsi_new_writer_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_SUBSCRIPTION_SECURE_NAME, gv->sedp_reader_secure_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo), NULL, NULL, NULL); + ddsi_new_writer (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_SUBSCRIPTION_SECURE_NAME, gv->sedp_reader_secure_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo), NULL, NULL, NULL); pp->bes |= DDSI_BUILTIN_ENDPOINT_SUBSCRIPTION_MESSAGE_SECURE_ANNOUNCER; dds_whc_free_wrinfo (wrinfo); @@ -237,11 +237,11 @@ static void add_security_builtin_endpoints (struct ddsi_participant *pp, ddsi_gu if (add_readers) { subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER); - ddsi_new_reader_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_SUBSCRIPTION_SECURE_NAME, gv->sedp_reader_secure_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); + ddsi_new_reader (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_SUBSCRIPTION_SECURE_NAME, gv->sedp_reader_secure_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); pp->bes |= DDSI_BUILTIN_ENDPOINT_SUBSCRIPTION_MESSAGE_SECURE_DETECTOR; subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_READER); - ddsi_new_reader_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PUBLICATION_SECURE_NAME, gv->sedp_writer_secure_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); + ddsi_new_reader (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PUBLICATION_SECURE_NAME, gv->sedp_writer_secure_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); pp->bes |= DDSI_BUILTIN_ENDPOINT_PUBLICATION_MESSAGE_SECURE_DETECTOR; } @@ -250,19 +250,19 @@ static void add_security_builtin_endpoints (struct ddsi_participant *pp, ddsi_gu * besmode flag setting, because all participant do require authentication. */ subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_READER); - ddsi_new_reader_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_SECURE_NAME, gv->spdp_secure_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); + ddsi_new_reader (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_SECURE_NAME, gv->spdp_secure_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); pp->bes |= DDSI_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_DETECTOR; subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER); - ddsi_new_reader_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_VOLATILE_MESSAGE_SECURE_NAME, gv->pgm_volatile_type, &gv->builtin_secure_volatile_xqos_rd, NULL, NULL, NULL, NULL); + ddsi_new_reader (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_VOLATILE_MESSAGE_SECURE_NAME, gv->pgm_volatile_type, &gv->builtin_secure_volatile_xqos_rd, NULL, NULL, NULL, NULL); pp->bes |= DDSI_BUILTIN_ENDPOINT_PARTICIPANT_VOLATILE_SECURE_DETECTOR; subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_READER); - ddsi_new_reader_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_STATELESS_MESSAGE_NAME, gv->pgm_stateless_type, &gv->builtin_stateless_xqos_rd, NULL, NULL, NULL, NULL); + ddsi_new_reader (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_STATELESS_MESSAGE_NAME, gv->pgm_stateless_type, &gv->builtin_stateless_xqos_rd, NULL, NULL, NULL, NULL); pp->bes |= DDSI_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_DETECTOR; subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER); - ddsi_new_reader_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_MESSAGE_SECURE_NAME, gv->pmd_secure_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); + ddsi_new_reader (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_MESSAGE_SECURE_NAME, gv->pmd_secure_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); pp->bes |= DDSI_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_SECURE_DETECTOR; } @@ -312,16 +312,16 @@ static void add_builtin_endpoints (struct ddsi_participant *pp, ddsi_guid_t *sub /* SEDP writers: */ subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER); - ddsi_new_writer_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_SUBSCRIPTION_NAME, gv->sedp_reader_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo_tl), NULL, NULL, NULL); + ddsi_new_writer (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_SUBSCRIPTION_NAME, gv->sedp_reader_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo_tl), NULL, NULL, NULL); pp->bes |= DDSI_DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER; subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER); - ddsi_new_writer_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PUBLICATION_NAME, gv->sedp_writer_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo_tl), NULL, NULL, NULL); + ddsi_new_writer (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PUBLICATION_NAME, gv->sedp_writer_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo_tl), NULL, NULL, NULL); pp->bes |= DDSI_DISC_BUILTIN_ENDPOINT_PUBLICATION_ANNOUNCER; /* PMD writer: */ subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER); - ddsi_new_writer_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_MESSAGE_NAME, gv->pmd_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo_tl), NULL, NULL, NULL); + ddsi_new_writer (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_MESSAGE_NAME, gv->pmd_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo_tl), NULL, NULL, NULL); pp->bes |= DDSI_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER; #ifdef DDS_HAS_TOPIC_DISCOVERY @@ -329,7 +329,7 @@ static void add_builtin_endpoints (struct ddsi_participant *pp, ddsi_guid_t *sub { /* SEDP topic writer: */ subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_SEDP_BUILTIN_TOPIC_WRITER); - ddsi_new_writer_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_TOPIC_NAME, gv->sedp_topic_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo_tl), NULL, NULL, NULL); + ddsi_new_writer (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_TOPIC_NAME, gv->sedp_topic_type, &gv->builtin_endpoint_xqos_wr, dds_whc_new(gv, wrinfo_tl), NULL, NULL, NULL); pp->bes |= DDSI_DISC_BUILTIN_ENDPOINT_TOPICS_ANNOUNCER; } #endif @@ -339,11 +339,11 @@ static void add_builtin_endpoints (struct ddsi_participant *pp, ddsi_guid_t *sub struct ddsi_writer *wr_tl_req, *wr_tl_reply; subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_TL_SVC_BUILTIN_REQUEST_WRITER); - ddsi_new_writer_guid (&wr_tl_req, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_TYPELOOKUP_REQUEST_NAME, gv->tl_svc_request_type, &gv->builtin_volatile_xqos_wr, dds_whc_new(gv, wrinfo_vol), NULL, NULL, NULL); + ddsi_new_writer (&wr_tl_req, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_TYPELOOKUP_REQUEST_NAME, gv->tl_svc_request_type, &gv->builtin_volatile_xqos_wr, dds_whc_new(gv, wrinfo_vol), NULL, NULL, NULL); pp->bes |= DDSI_BUILTIN_ENDPOINT_TL_SVC_REQUEST_DATA_WRITER; subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_TL_SVC_BUILTIN_REPLY_WRITER); - ddsi_new_writer_guid (&wr_tl_reply, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_TYPELOOKUP_REPLY_NAME, gv->tl_svc_reply_type, &gv->builtin_volatile_xqos_wr, dds_whc_new(gv, wrinfo_vol), NULL, NULL, NULL); + ddsi_new_writer (&wr_tl_reply, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_TYPELOOKUP_REPLY_NAME, gv->tl_svc_reply_type, &gv->builtin_volatile_xqos_wr, dds_whc_new(gv, wrinfo_vol), NULL, NULL, NULL); pp->bes |= DDSI_BUILTIN_ENDPOINT_TL_SVC_REPLY_DATA_WRITER; /* The built-in type lookup writers are keep-all writers, because the topic is keyless (using DDS-RPC request @@ -364,21 +364,21 @@ static void add_builtin_endpoints (struct ddsi_participant *pp, ddsi_guid_t *sub { /* SPDP reader: */ subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER); - ddsi_new_reader_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_NAME, gv->spdp_type, &gv->spdp_endpoint_xqos, NULL, NULL, NULL, NULL); + ddsi_new_reader (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_NAME, gv->spdp_type, &gv->spdp_endpoint_xqos, NULL, NULL, NULL, NULL); pp->bes |= DDSI_DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR; /* SEDP readers: */ subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_READER); - ddsi_new_reader_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_SUBSCRIPTION_NAME, gv->sedp_reader_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); + ddsi_new_reader (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_SUBSCRIPTION_NAME, gv->sedp_reader_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); pp->bes |= DDSI_DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_DETECTOR; subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER); - ddsi_new_reader_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PUBLICATION_NAME, gv->sedp_writer_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); + ddsi_new_reader (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PUBLICATION_NAME, gv->sedp_writer_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); pp->bes |= DDSI_DISC_BUILTIN_ENDPOINT_PUBLICATION_DETECTOR; /* PMD reader: */ subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER); - ddsi_new_reader_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_MESSAGE_NAME, gv->pmd_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); + ddsi_new_reader (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_MESSAGE_NAME, gv->pmd_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); pp->bes |= DDSI_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER; #ifdef DDS_HAS_TOPIC_DISCOVERY @@ -386,18 +386,18 @@ static void add_builtin_endpoints (struct ddsi_participant *pp, ddsi_guid_t *sub { /* SEDP topic reader: */ subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_SEDP_BUILTIN_TOPIC_READER); - ddsi_new_reader_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_TOPIC_NAME, gv->sedp_topic_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); + ddsi_new_reader (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_TOPIC_NAME, gv->sedp_topic_type, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL, NULL); pp->bes |= DDSI_DISC_BUILTIN_ENDPOINT_TOPICS_DETECTOR; } #endif #ifdef DDS_HAS_TYPE_DISCOVERY /* TypeLookup readers: */ subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_TL_SVC_BUILTIN_REQUEST_READER); - ddsi_new_reader_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_TYPELOOKUP_REQUEST_NAME, gv->tl_svc_request_type, &gv->builtin_volatile_xqos_rd, NULL, NULL, NULL, NULL); + ddsi_new_reader (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_TYPELOOKUP_REQUEST_NAME, gv->tl_svc_request_type, &gv->builtin_volatile_xqos_rd, NULL, NULL, NULL, NULL); pp->bes |= DDSI_BUILTIN_ENDPOINT_TL_SVC_REQUEST_DATA_READER; subguid->entityid = ddsi_to_entityid (DDSI_ENTITYID_TL_SVC_BUILTIN_REPLY_READER); - ddsi_new_reader_guid (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_TYPELOOKUP_REPLY_NAME, gv->tl_svc_reply_type, &gv->builtin_volatile_xqos_rd, NULL, NULL, NULL, NULL); + ddsi_new_reader (NULL, subguid, group_guid, pp, DDS_BUILTIN_TOPIC_TYPELOOKUP_REPLY_NAME, gv->tl_svc_reply_type, &gv->builtin_volatile_xqos_rd, NULL, NULL, NULL, NULL); pp->bes |= DDSI_BUILTIN_ENDPOINT_TL_SVC_REPLY_DATA_READER; #endif } @@ -906,7 +906,7 @@ dds_return_t ddsi_new_participant (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv { subguid.entityid = ddsi_to_entityid (DDSI_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER); wrinfo = dds_whc_make_wrinfo (NULL, &gv->spdp_endpoint_xqos); - ddsi_new_writer_guid (NULL, &subguid, &group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_NAME, gv->spdp_type, &gv->spdp_endpoint_xqos, dds_whc_new(gv, wrinfo), NULL, NULL, NULL); + ddsi_new_writer (NULL, &subguid, &group_guid, pp, DDS_BUILTIN_TOPIC_PARTICIPANT_NAME, gv->spdp_type, &gv->spdp_endpoint_xqos, dds_whc_new(gv, wrinfo), NULL, NULL, NULL); dds_whc_free_wrinfo (wrinfo); /* But we need the as_disc address set for SPDP, because we need to send it to everyone regardless of the existence of readers. */ diff --git a/src/core/ddsi/tests/wraddrset.c b/src/core/ddsi/tests/wraddrset.c index 93e77969c8..330b82e088 100644 --- a/src/core/ddsi/tests/wraddrset.c +++ b/src/core/ddsi/tests/wraddrset.c @@ -176,6 +176,9 @@ static void ddsi_wraddrset_some_cases (int casenumber, int cost, bool wr_psmx, c .free = whc_free } }; + dds_return_t ret = ddsi_generate_writer_guid (&wrguid, pp, &st); + assert (ret == DDS_RETCODE_OK); + (void) ret; ddsi_new_writer (&wr, &wrguid, NULL, pp, "Q", &st, &ddsi_default_qos_writer, &whc, NULL, NULL, wr_psmx ? &psmx_locs : NULL); assert (ddsi_entidx_lookup_writer_guid (gv.entity_index, &wrguid)); diff --git a/src/core/xtests/symbol_export/symbol_export.c b/src/core/xtests/symbol_export/symbol_export.c index 13dd91c791..c46abf4412 100644 --- a/src/core/xtests/symbol_export/symbol_export.c +++ b/src/core/xtests/symbol_export/symbol_export.c @@ -171,9 +171,11 @@ int main (int argc, char **argv) dds_resume (1); dds_wait_for_acks (1, 0); dds_create_reader (1, 1, ptr, ptr); + dds_create_reader_guid (1, 1, ptr, ptr2, ptr3); dds_create_reader_rhc (1, 1, ptr, ptr, ptr); dds_reader_wait_for_historical_data (1, 0); dds_create_writer (1, 1, ptr, ptr); + dds_create_writer_guid (1, 1, ptr, ptr2, ptr3); dds_register_instance (1, ptr, ptr); dds_unregister_instance (1, ptr); dds_unregister_instance_ih (1, 1); From 21736edf50307a9a208bf61d6c295e23ff70b4c3 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Thu, 7 Dec 2023 13:49:44 +0100 Subject: [PATCH 107/207] Add no-discovery flag Adds a flag that can be passed when creating a participant, to indicate that discovery for the participant should be disabled. This also introduces a flag on the DDSI participant object that indicates that the participant is using a static topology for child entities. Signed-off-by: Dennis Potman --- .../ddsc/include/dds/ddsc/dds_internal_api.h | 4 + src/core/ddsc/src/dds_participant.c | 2 + src/core/ddsc/tests/liveliness.c | 3 +- .../ddsi/include/dds/ddsi/ddsi_participant.h | 23 +++++ src/core/ddsi/src/ddsi__participant.h | 25 +----- src/core/ddsi/src/ddsi_discovery.c | 5 +- src/core/ddsi/src/ddsi_discovery_endpoint.c | 75 +++++++++------- src/core/ddsi/src/ddsi_discovery_spdp.c | 27 +++--- src/core/ddsi/src/ddsi_discovery_topic.c | 27 +++--- src/core/ddsi/src/ddsi_participant.c | 88 ++++++++++++------- src/core/ddsi/src/ddsi_pmd.c | 25 +++--- src/core/ddsi/src/ddsi_security_exchange.c | 4 +- src/core/ddsi/src/ddsi_typelookup.c | 2 +- src/security/core/tests/common/test_utils.c | 5 +- 14 files changed, 186 insertions(+), 129 deletions(-) diff --git a/src/core/ddsc/include/dds/ddsc/dds_internal_api.h b/src/core/ddsc/include/dds/ddsc/dds_internal_api.h index 0eb786a1de..b592f0f63f 100644 --- a/src/core/ddsc/include/dds/ddsc/dds_internal_api.h +++ b/src/core/ddsc/include/dds/ddsc/dds_internal_api.h @@ -22,6 +22,10 @@ extern "C" { #endif +// Magic numbers match the set of internal flags we want to use but do not want to expose in the API. +// The implementation contains static assert to ensure this is kept in sync. +#define DDS_PARTICIPANT_FLAGS_NO_DISCOVERY (1u | 2u | 32u) + /** * @ingroup internal * @component topic diff --git a/src/core/ddsc/src/dds_participant.c b/src/core/ddsc/src/dds_participant.c index 2fd791a3f9..cdcdde81f0 100644 --- a/src/core/ddsc/src/dds_participant.c +++ b/src/core/ddsc/src/dds_participant.c @@ -183,6 +183,8 @@ static dds_entity_t create_participant_flags_guid (const dds_domainid_t domain, return ret; } +DDSRT_STATIC_ASSERT (DDS_PARTICIPANT_FLAGS_NO_DISCOVERY == (RTPS_PF_NO_BUILTIN_READERS | RTPS_PF_NO_BUILTIN_WRITERS | RTPS_PF_NO_PRIVILEGED_PP)); + dds_entity_t dds_create_participant_guid (const dds_domainid_t domain, const dds_qos_t *qos, const dds_listener_t *listener, uint32_t flags, const dds_guid_t *guid) { return create_participant_flags_guid (domain, qos, listener, flags, guid); diff --git a/src/core/ddsc/tests/liveliness.c b/src/core/ddsc/tests/liveliness.c index 56ec915978..5db8a17e3a 100644 --- a/src/core/ddsc/tests/liveliness.c +++ b/src/core/ddsc/tests/liveliness.c @@ -83,8 +83,9 @@ static ddsi_seqno_t get_pmd_seqno(dds_entity_t participant) CU_ASSERT_EQUAL_FATAL(dds_entity_pin(participant, &pp_entity), 0); ddsi_thread_state_awake(ddsi_lookup_thread_state(), &pp_entity->m_domain->gv); pp = ddsi_entidx_lookup_participant_guid(pp_entity->m_domain->gv.entity_index, &pp_entity->m_guid); - wr = ddsi_get_builtin_writer (pp, DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER); + dds_return_t ret = ddsi_get_builtin_writer (pp, DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER, &wr); CU_ASSERT_FATAL(wr != NULL); + CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); seqno = wr->seq; ddsi_thread_state_asleep(ddsi_lookup_thread_state()); dds_entity_unpin(pp_entity); diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_participant.h b/src/core/ddsi/include/dds/ddsi/ddsi_participant.h index e02d304b37..8924b0ec98 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_participant.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_participant.h @@ -26,6 +26,28 @@ extern "C" { #endif +/* Set this flag in new_participant to prevent the creation SPDP, SEDP + and PMD readers for that participant. It doesn't really need it, + they all share the information anyway. But you do need it once. */ +#define RTPS_PF_NO_BUILTIN_READERS 1u +/* Set this flag to prevent the creation of SPDP, SEDP and PMD + writers. It will then rely on the "privileged participant", which + must exist at the time of creation. It creates a reference to that + "privileged participant" to ensure it won't disappear too early. */ +#define RTPS_PF_NO_BUILTIN_WRITERS 2u +/* Set this flag to mark the participant as the "privileged + participant", there can only be one of these. The privileged + participant MUST have all builtin readers and writers. */ +#define RTPS_PF_PRIVILEGED_PP 4u +/* Set this flag to mark the participant as is_ddsi2_pp. */ +#define RTPS_PF_IS_DDSI2_PP 8u +/* Set this flag to mark the participant as an local entity only. */ +#define RTPS_PF_ONLY_LOCAL 16u +/* Set this flag to mark that no privileged participant should be used + for the built-in readers and writers. Can be used with NO_BUILTIN_READER and + NO_BUILTIN_WRITER flag to avoid any communication for built-in topics. */ +#define RTPS_PF_NO_PRIVILEGED_PP 32u + struct ddsi_avail_entityid_set { struct ddsi_inverse_uint32_set x; }; @@ -42,6 +64,7 @@ struct ddsi_participant struct ddsi_entity_common e; uint32_t bes; /* built-in endpoint set */ unsigned is_ddsi2_pp: 1; /* true for the "federation leader", the ddsi2 participant itself in OSPL; FIXME: probably should use this for broker mode as well ... */ + uint32_t flags; /* flags used when creating this participant */ struct ddsi_plist *plist; /* settings/QoS for this participant */ struct ddsi_xevent *spdp_xevent; /* timed event for periodically publishing SPDP */ struct ddsi_xevent *pmd_update_xevent; /* timed event for periodically publishing ParticipantMessageData */ diff --git a/src/core/ddsi/src/ddsi__participant.h b/src/core/ddsi/src/ddsi__participant.h index 1ea2676268..b0e79819e3 100644 --- a/src/core/ddsi/src/ddsi__participant.h +++ b/src/core/ddsi/src/ddsi__participant.h @@ -49,24 +49,6 @@ struct ddsi_deleted_participants_admin { int64_t delay; }; -/* Set this flag in new_participant to prevent the creation SPDP, SEDP - and PMD readers for that participant. It doesn't really need it, - they all share the information anyway. But you do need it once. */ -#define RTPS_PF_NO_BUILTIN_READERS 1u -/* Set this flag to prevent the creation of SPDP, SEDP and PMD - writers. It will then rely on the "privileged participant", which - must exist at the time of creation. It creates a reference to that - "privileged participant" to ensure it won't disappear too early. */ -#define RTPS_PF_NO_BUILTIN_WRITERS 2u -/* Set this flag to mark the participant as the "privileged - participant", there can only be one of these. The privileged - participant MUST have all builtin readers and writers. */ -#define RTPS_PF_PRIVILEGED_PP 4u - /* Set this flag to mark the participant as is_ddsi2_pp. */ -#define RTPS_PF_IS_DDSI2_PP 8u - /* Set this flag to mark the participant as an local entity only. */ -#define RTPS_PF_ONLY_LOCAL 16u - /** @component ddsi_participant */ void ddsi_participant_add_wr_lease_locked (struct ddsi_participant * pp, const struct ddsi_writer * wr); @@ -121,13 +103,14 @@ dds_duration_t ddsi_participant_get_pmd_interval (struct ddsi_participant *pp); * @component ddsi_participant * @brief To obtain the builtin writer to be used for publishing SPDP, SEDP, PMD stuff for * PP and its endpoints, given the entityid. If PP has its own writer, use it; else use the - * privileged participant. + * privileged participant, unless the NO_PRIVILEGED_PP flag is set. * * @param[in] pp The participant * @param[in] entityid The entity ID of the writer - * @returns The built-in writer + * @param[out] bwr The built-in writer + * @returns Return code indicating success or failure */ -struct ddsi_writer *ddsi_get_builtin_writer (const struct ddsi_participant *pp, unsigned entityid); +dds_return_t ddsi_get_builtin_writer (const struct ddsi_participant *pp, unsigned entityid, struct ddsi_writer **bwr); #if defined (__cplusplus) } diff --git a/src/core/ddsi/src/ddsi_discovery.c b/src/core/ddsi/src/ddsi_discovery.c index c402728eaf..9cd35b7abf 100644 --- a/src/core/ddsi/src/ddsi_discovery.c +++ b/src/core/ddsi/src/ddsi_discovery.c @@ -65,8 +65,9 @@ struct ddsi_writer *ddsi_get_sedp_writer (const struct ddsi_participant *pp, unsigned entityid) { - struct ddsi_writer *sedp_wr = ddsi_get_builtin_writer (pp, entityid); - if (sedp_wr == NULL) + struct ddsi_writer *sedp_wr; + dds_return_t ret = ddsi_get_builtin_writer (pp, entityid, &sedp_wr); + if (ret != DDS_RETCODE_OK) DDS_FATAL ("sedp_write_writer: no SEDP builtin writer %x for "PGUIDFMT"\n", entityid, PGUID (pp->e.guid)); return sedp_wr; } diff --git a/src/core/ddsi/src/ddsi_discovery_endpoint.c b/src/core/ddsi/src/ddsi_discovery_endpoint.c index f2269b5d8e..eee1cc9975 100644 --- a/src/core/ddsi/src/ddsi_discovery_endpoint.c +++ b/src/core/ddsi/src/ddsi_discovery_endpoint.c @@ -263,30 +263,32 @@ static int sedp_write_endpoint_impl int ddsi_sedp_write_writer (struct ddsi_writer *wr) { - if ((!ddsi_is_builtin_entityid(wr->e.guid.entityid, DDSI_VENDORID_ECLIPSE)) && (!wr->e.onlylocal)) - { - unsigned entityid = ddsi_determine_publication_writer(wr); - struct ddsi_writer *sedp_wr = ddsi_get_sedp_writer (wr->c.pp, entityid); - ddsi_security_info_t *security = NULL; + if (ddsi_is_builtin_entityid (wr->e.guid.entityid, DDSI_VENDORID_ECLIPSE) || wr->e.onlylocal) + return 0; + + unsigned entityid = ddsi_determine_publication_writer (wr); + struct ddsi_writer *sedp_wr = ddsi_get_sedp_writer (wr->c.pp, entityid); + if (sedp_wr == NULL) + return 0; + #ifdef DDS_HAS_SSM - struct ddsi_addrset *as = wr->ssm_as; + struct ddsi_addrset *as = wr->ssm_as; #else - struct ddsi_addrset *as = NULL; + struct ddsi_addrset *as = NULL; #endif + + ddsi_security_info_t *security = NULL; #ifdef DDS_HAS_SECURITY - ddsi_security_info_t tmp; - if (ddsi_omg_get_writer_security_info (wr, &tmp)) - { - security = &tmp; - } + ddsi_security_info_t tmp; + if (ddsi_omg_get_writer_security_info (wr, &tmp)) + security = &tmp; #endif + #ifdef DDS_HAS_TYPELIB - return sedp_write_endpoint_impl (sedp_wr, 1, &wr->e.guid, &wr->c, wr->xqos, as, security, wr->type); + return sedp_write_endpoint_impl (sedp_wr, 1, &wr->e.guid, &wr->c, wr->xqos, as, security, wr->type); #else - return sedp_write_endpoint_impl (sedp_wr, 1, &wr->e.guid, &wr->c, wr->xqos, as, security); + return sedp_write_endpoint_impl (sedp_wr, 1, &wr->e.guid, &wr->c, wr->xqos, as, security); #endif - } - return 0; } int ddsi_sedp_write_reader (struct ddsi_reader *rd) @@ -294,8 +296,11 @@ int ddsi_sedp_write_reader (struct ddsi_reader *rd) if (ddsi_is_builtin_entityid (rd->e.guid.entityid, DDSI_VENDORID_ECLIPSE) || rd->e.onlylocal) return 0; - unsigned entityid = ddsi_determine_subscription_writer(rd); + unsigned entityid = ddsi_determine_subscription_writer (rd); struct ddsi_writer *sedp_wr = ddsi_get_sedp_writer (rd->c.pp, entityid); + if (sedp_wr == NULL) + return 0; + ddsi_security_info_t *security = NULL; struct ddsi_addrset *as = NULL; #ifdef DDS_HAS_NETWORK_PARTITIONS @@ -333,32 +338,36 @@ int ddsi_sedp_write_reader (struct ddsi_reader *rd) int ddsi_sedp_dispose_unregister_writer (struct ddsi_writer *wr) { - if ((!ddsi_is_builtin_entityid(wr->e.guid.entityid, DDSI_VENDORID_ECLIPSE)) && (!wr->e.onlylocal)) - { - unsigned entityid = ddsi_determine_publication_writer(wr); - struct ddsi_writer *sedp_wr = ddsi_get_sedp_writer (wr->c.pp, entityid); + if (ddsi_is_builtin_entityid (wr->e.guid.entityid, DDSI_VENDORID_ECLIPSE) || wr->e.onlylocal) + return 0; + + unsigned entityid = ddsi_determine_publication_writer (wr); + struct ddsi_writer *sedp_wr = ddsi_get_sedp_writer (wr->c.pp, entityid); + if (sedp_wr == NULL) + return 0; + #ifdef DDS_HAS_TYPELIB - return sedp_write_endpoint_impl (sedp_wr, 0, &wr->e.guid, NULL, NULL, NULL, NULL, NULL); + return sedp_write_endpoint_impl (sedp_wr, 0, &wr->e.guid, NULL, NULL, NULL, NULL, NULL); #else - return sedp_write_endpoint_impl (sedp_wr, 0, &wr->e.guid, NULL, NULL, NULL, NULL); + return sedp_write_endpoint_impl (sedp_wr, 0, &wr->e.guid, NULL, NULL, NULL, NULL); #endif - } - return 0; } int ddsi_sedp_dispose_unregister_reader (struct ddsi_reader *rd) { - if ((!ddsi_is_builtin_entityid(rd->e.guid.entityid, DDSI_VENDORID_ECLIPSE)) && (!rd->e.onlylocal)) - { - unsigned entityid = ddsi_determine_subscription_writer(rd); - struct ddsi_writer *sedp_wr = ddsi_get_sedp_writer (rd->c.pp, entityid); + if (ddsi_is_builtin_entityid (rd->e.guid.entityid, DDSI_VENDORID_ECLIPSE) || rd->e.onlylocal) + return 0; + + unsigned entityid = ddsi_determine_subscription_writer (rd); + struct ddsi_writer *sedp_wr = ddsi_get_sedp_writer (rd->c.pp, entityid); + if (sedp_wr == NULL) + return 0; + #ifdef DDS_HAS_TYPELIB - return sedp_write_endpoint_impl (sedp_wr, 0, &rd->e.guid, NULL, NULL, NULL, NULL, NULL); + return sedp_write_endpoint_impl (sedp_wr, 0, &rd->e.guid, NULL, NULL, NULL, NULL, NULL); #else - return sedp_write_endpoint_impl (sedp_wr, 0, &rd->e.guid, NULL, NULL, NULL, NULL); + return sedp_write_endpoint_impl (sedp_wr, 0, &rd->e.guid, NULL, NULL, NULL, NULL); #endif - } - return 0; } static const char *durability_to_string (dds_durability_kind_t k) diff --git a/src/core/ddsi/src/ddsi_discovery_spdp.c b/src/core/ddsi/src/ddsi_discovery_spdp.c index caa1f12e73..baae9d9231 100644 --- a/src/core/ddsi/src/ddsi_discovery_spdp.c +++ b/src/core/ddsi/src/ddsi_discovery_spdp.c @@ -236,18 +236,21 @@ int ddsi_spdp_write (struct ddsi_participant *pp) struct ddsi_participant_builtin_topic_data_locators locs; if (pp->e.onlylocal) { - /* This topic is only locally available. */ - return 0; + /* This topic is only locally available. */ + return 0; } - ETRACE (pp, "ddsi_spdp_write("PGUIDFMT")\n", PGUID (pp->e.guid)); + dds_return_t ret = ddsi_get_builtin_writer (pp, DDSI_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER, &wr); + if (ret == DDS_RETCODE_OK && wr == NULL) + return 0; - if ((wr = ddsi_get_builtin_writer (pp, DDSI_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)) == NULL) + ETRACE (pp, "ddsi_spdp_write("PGUIDFMT")\n", PGUID (pp->e.guid)); + if (ret != DDS_RETCODE_OK) { ETRACE (pp, "ddsi_spdp_write("PGUIDFMT") - builtin participant writer not found\n", PGUID (pp->e.guid)); return 0; } - + assert (wr != NULL); ddsi_get_participant_builtin_topic_data (pp, &ps, &locs); return ddsi_write_and_fini_plist (wr, &ps, true); } @@ -257,14 +260,16 @@ static int ddsi_spdp_dispose_unregister_with_wr (struct ddsi_participant *pp, un ddsi_plist_t ps; struct ddsi_writer *wr; - if ((wr = ddsi_get_builtin_writer (pp, entityid)) == NULL) + dds_return_t ret = ddsi_get_builtin_writer (pp, entityid, &wr); + if (ret == DDS_RETCODE_OK && wr == NULL) + return 0; + else if (ret != DDS_RETCODE_OK) { ETRACE (pp, "ddsi_spdp_dispose_unregister("PGUIDFMT") - builtin participant %s writer not found\n", - PGUID (pp->e.guid), - entityid == DDSI_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER ? "secure" : ""); + PGUID (pp->e.guid), entityid == DDSI_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER ? "secure" : ""); return 0; } - + assert (wr != NULL); ddsi_plist_init_empty (&ps); ps.present |= PP_PARTICIPANT_GUID; ps.participant_guid = pp->e.guid; @@ -331,11 +336,13 @@ static bool get_pp_and_spdp_wr (struct ddsi_domaingv *gv, const ddsi_guid_t *pp_ GVTRACE ("handle_xevk_spdp "PGUIDFMT" - unknown guid\n", PGUID (*pp_guid)); return false; } - if ((*spdp_wr = ddsi_get_builtin_writer (*pp, DDSI_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)) == NULL) + if (ddsi_get_builtin_writer (*pp, DDSI_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER, spdp_wr) != DDS_RETCODE_OK) { GVTRACE ("handle_xevk_spdp "PGUIDFMT" - spdp writer of participant not found\n", PGUID (*pp_guid)); return false; } + if (*spdp_wr == NULL) + return false; return true; } diff --git a/src/core/ddsi/src/ddsi_discovery_topic.c b/src/core/ddsi/src/ddsi_discovery_topic.c index cfeb84ec0d..651caa3c1e 100644 --- a/src/core/ddsi/src/ddsi_discovery_topic.c +++ b/src/core/ddsi/src/ddsi_discovery_topic.c @@ -62,19 +62,22 @@ static int ddsi_sedp_write_topic_impl (struct ddsi_writer *wr, int alive, const int ddsi_sedp_write_topic (struct ddsi_topic *tp, bool alive) { - int res = 0; if (!(tp->pp->bes & DDSI_DISC_BUILTIN_ENDPOINT_TOPICS_ANNOUNCER)) - return res; - if (!ddsi_is_builtin_entityid (tp->e.guid.entityid, DDSI_VENDORID_ECLIPSE) && !tp->e.onlylocal) - { - unsigned entityid = ddsi_determine_topic_writer (tp); - struct ddsi_writer *sedp_wr = ddsi_get_sedp_writer (tp->pp, entityid); - ddsrt_mutex_lock (&tp->e.qos_lock); - // the allocation type info object is freed with the plist - res = ddsi_sedp_write_topic_impl (sedp_wr, alive, &tp->e.guid, tp->definition->xqos, ddsi_type_pair_get_typeinfo (tp->e.gv, tp->definition->type_pair)); - ddsrt_mutex_unlock (&tp->e.qos_lock); - } - return res; + return 0; + if (ddsi_is_builtin_entityid (tp->e.guid.entityid, DDSI_VENDORID_ECLIPSE) || tp->e.onlylocal) + return 0; + + unsigned entityid = ddsi_determine_topic_writer (tp); + struct ddsi_writer *sedp_wr = ddsi_get_sedp_writer (tp->pp, entityid); + if (sedp_wr == NULL) + return 0; + + int ret = 0; + ddsrt_mutex_lock (&tp->e.qos_lock); + // the allocation type info object is freed with the plist + ret = ddsi_sedp_write_topic_impl (sedp_wr, alive, &tp->e.guid, tp->definition->xqos, ddsi_type_pair_get_typeinfo (tp->e.gv, tp->definition->type_pair)); + ddsrt_mutex_unlock (&tp->e.qos_lock); + return ret; } static const char *durability_to_string (dds_durability_kind_t k) diff --git a/src/core/ddsi/src/ddsi_participant.c b/src/core/ddsi/src/ddsi_participant.c index a3a59340a8..efc8f1ce7b 100644 --- a/src/core/ddsi/src/ddsi_participant.c +++ b/src/core/ddsi/src/ddsi_participant.c @@ -717,7 +717,7 @@ void ddsi_unref_participant (struct ddsi_participant *pp, const struct ddsi_guid if (!(pp->e.onlylocal)) { - if ((pp->bes & builtin_writers_besmask) != builtin_writers_besmask) + if ((pp->bes & builtin_writers_besmask) != builtin_writers_besmask && !(pp->flags & RTPS_PF_NO_PRIVILEGED_PP)) { /* Participant doesn't have a full complement of built-in writers, therefore, it relies on gv->privileged_pp, and @@ -780,7 +780,7 @@ dds_return_t ddsi_new_participant (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv struct ddsi_tran_conn * ppconn; /* no reserved bits may be set */ - assert ((flags & ~(RTPS_PF_NO_BUILTIN_READERS | RTPS_PF_NO_BUILTIN_WRITERS | RTPS_PF_PRIVILEGED_PP | RTPS_PF_IS_DDSI2_PP | RTPS_PF_ONLY_LOCAL)) == 0); + assert ((flags & ~(RTPS_PF_NO_BUILTIN_READERS | RTPS_PF_NO_BUILTIN_WRITERS | RTPS_PF_PRIVILEGED_PP | RTPS_PF_IS_DDSI2_PP | RTPS_PF_ONLY_LOCAL | RTPS_PF_NO_PRIVILEGED_PP)) == 0); /* privileged participant MUST have builtin readers and writers */ assert (!(flags & RTPS_PF_PRIVILEGED_PP) || (flags & (RTPS_PF_NO_BUILTIN_READERS | RTPS_PF_NO_BUILTIN_WRITERS)) == 0); @@ -840,6 +840,7 @@ dds_return_t ddsi_new_participant (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv pp->builtin_refc = 0; pp->state = DDSI_PARTICIPANT_STATE_INITIALIZING; pp->is_ddsi2_pp = (flags & (RTPS_PF_PRIVILEGED_PP | RTPS_PF_IS_DDSI2_PP)) ? 1 : 0; + pp->flags = flags; ddsrt_mutex_init (&pp->refc_lock); ddsi_inverse_uint32_set_init(&pp->avail_entityids.x, 1, UINT32_MAX / DDSI_ENTITYID_ALLOCSTEP); assert (plist->qos.present & DDSI_QP_LIVELINESS); @@ -862,7 +863,7 @@ dds_return_t ddsi_new_participant (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv ddsi_tkmap_instance_unref (gv->m_tkmap, pp->e.tk); pp->e.tk = ddsi_builtintopic_get_tkmap_entry (gv->builtin_topic_interface, &pp->e.guid); pp->e.iid = pp->e.tk->m_iid; - } + } #else if (ddsi_xqos_has_prop_prefix (&pp->plist->qos, "dds.sec.")) { @@ -873,6 +874,14 @@ dds_return_t ddsi_new_participant (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv } #endif +#ifdef DDS_HAS_SECURITY + if (ddsi_omg_participant_is_secure (pp) && (flags & RTPS_PF_NO_BUILTIN_WRITERS)) + { + ret = DDS_RETCODE_BAD_PARAMETER; + goto not_allowed; + } +#endif + if (gv->logconfig.c.mask & DDS_LC_DISCOVERY) { GVLOGDISC ("PARTICIPANT "PGUIDFMT" QOS={", PGUID (pp->e.guid)); @@ -925,8 +934,9 @@ dds_return_t ddsi_new_participant (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv the reference count of the privileged participant is incremented. If it is the privileged participant, set the global variable pointing to it. - Except when the participant is only locally available. */ - if (!(flags & RTPS_PF_ONLY_LOCAL)) + Except when the participant is only locally available or is + using a static topology. */ + if (!(flags & (RTPS_PF_ONLY_LOCAL | RTPS_PF_NO_PRIVILEGED_PP))) { ddsrt_mutex_lock (&gv->privileged_pp_lock); if ((pp->bes & builtin_writers_besmask) != builtin_writers_besmask) @@ -965,35 +975,36 @@ dds_return_t ddsi_new_participant (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv ddsi_builtintopic_write_endpoint (gv->builtin_topic_interface, &pp->e, ddsrt_time_wallclock(), true); - /* SPDP periodic broadcast uses the retransmit path, so the initial - publication must be done differently. Must be later than making - the participant globally visible, or the SPDP processing won't - recognise the participant as a local one. */ - if (ddsi_spdp_write (pp) >= 0) + if (!(flags & RTPS_PF_NO_BUILTIN_WRITERS) || !(flags & RTPS_PF_NO_PRIVILEGED_PP)) { - /* Once the initial sample has been written, the automatic and - asynchronous broadcasting required by SPDP can start. Also, - since we're new alive, PMD updates can now start, too. - Schedule the first update for 100ms in the future to reduce the - impact of the first sample getting lost. Note: these two may - fire before the calls return. If the initial sample wasn't - accepted, all is lost, but we continue nonetheless, even though - the participant won't be able to discover or be discovered. */ - struct ddsi_spdp_broadcast_xevent_cb_arg arg = { .pp_guid = pp->e.guid }; - pp->spdp_xevent = ddsi_qxev_callback (gv->xevents, ddsrt_mtime_add_duration (ddsrt_time_monotonic (), DDS_MSECS (100)), ddsi_spdp_broadcast_xevent_cb, &arg, sizeof (arg), false); - } + /* SPDP periodic broadcast uses the retransmit path, so the initial + publication must be done differently. Must be later than making + the participant globally visible, or the SPDP processing won't + recognise the participant as a local one. */ + if (ddsi_spdp_write (pp) >= 0) + { + /* Once the initial sample has been written, the automatic and + asynchronous broadcasting required by SPDP can start. Also, + since we're new alive, PMD updates can now start, too. + Schedule the first update for 100ms in the future to reduce the + impact of the first sample getting lost. Note: these two may + fire before the calls return. If the initial sample wasn't + accepted, all is lost, but we continue nonetheless, even though + the participant won't be able to discover or be discovered. */ + struct ddsi_spdp_broadcast_xevent_cb_arg arg = { .pp_guid = pp->e.guid }; + pp->spdp_xevent = ddsi_qxev_callback (gv->xevents, ddsrt_mtime_add_duration (ddsrt_time_monotonic (), DDS_MSECS (100)), ddsi_spdp_broadcast_xevent_cb, &arg, sizeof (arg), false); + } - { - ddsrt_mtime_t tsched = (pp->plist->qos.liveliness.lease_duration == DDS_INFINITY) ? DDSRT_MTIME_NEVER : (ddsrt_mtime_t){0}; - struct ddsi_write_pmd_message_xevent_cb_arg arg = { .pp_guid = pp->e.guid }; - pp->pmd_update_xevent = ddsi_qxev_callback (gv->xevents, tsched, ddsi_write_pmd_message_xevent_cb, &arg, sizeof (arg), false); + { + ddsrt_mtime_t tsched = (pp->plist->qos.liveliness.lease_duration == DDS_INFINITY) ? DDSRT_MTIME_NEVER : (ddsrt_mtime_t){0}; + struct ddsi_write_pmd_message_xevent_cb_arg arg = { .pp_guid = pp->e.guid }; + pp->pmd_update_xevent = ddsi_qxev_callback (gv->xevents, tsched, ddsi_write_pmd_message_xevent_cb, &arg, sizeof (arg), false); + } } #ifdef DDS_HAS_SECURITY if (ddsi_omg_participant_is_secure (pp)) - { connect_participant_secure (gv, pp); - } #endif return ret; @@ -1074,13 +1085,16 @@ dds_return_t ddsi_delete_participant (struct ddsi_domaingv *gv, const struct dds return 0; } -struct ddsi_writer *ddsi_get_builtin_writer (const struct ddsi_participant *pp, unsigned entityid) +dds_return_t ddsi_get_builtin_writer (const struct ddsi_participant *pp, unsigned entityid, struct ddsi_writer **bwr) { ddsi_guid_t bwr_guid; uint32_t bes_mask = 0; - if (pp->e.onlylocal) { - return NULL; + assert (bwr); + if (pp->e.onlylocal) + { + *bwr = NULL; + return DDS_RETCODE_OK; } /* If the participant the required built-in writer, we use it. We @@ -1139,7 +1153,7 @@ struct ddsi_writer *ddsi_get_builtin_writer (const struct ddsi_participant *pp, break; default: DDS_FATAL ("get_builtin_writer called with entityid %x\n", entityid); - return NULL; + return DDS_RETCODE_BAD_PARAMETER; } if (pp->bes & bes_mask) @@ -1148,7 +1162,7 @@ struct ddsi_writer *ddsi_get_builtin_writer (const struct ddsi_participant *pp, bwr_guid.prefix = pp->e.guid.prefix; bwr_guid.entityid.u = entityid; } - else + else if (!(pp->flags & RTPS_PF_NO_PRIVILEGED_PP)) { /* Must have a designated participant to use -- that is, before any application readers and writers may be created (indeed, @@ -1164,8 +1178,16 @@ struct ddsi_writer *ddsi_get_builtin_writer (const struct ddsi_participant *pp, ddsrt_mutex_unlock (&pp->e.gv->privileged_pp_lock); bwr_guid.entityid.u = entityid; } + else + { + /* NO_PRIVILEGED_PP flag is set, so it's okay that we don't have + a built-in writer at this point */ + *bwr = NULL; + return DDS_RETCODE_OK; + } - return ddsi_entidx_lookup_writer_guid (pp->e.gv->entity_index, &bwr_guid); + *bwr = ddsi_entidx_lookup_writer_guid (pp->e.gv->entity_index, &bwr_guid); + return (*bwr != NULL) ? DDS_RETCODE_OK : DDS_RETCODE_PRECONDITION_NOT_MET; } dds_duration_t ddsi_participant_get_pmd_interval (struct ddsi_participant *pp) diff --git a/src/core/ddsi/src/ddsi_pmd.c b/src/core/ddsi/src/ddsi_pmd.c index d6d1ea5eb6..6eb45cfddc 100644 --- a/src/core/ddsi/src/ddsi_pmd.c +++ b/src/core/ddsi/src/ddsi_pmd.c @@ -63,22 +63,23 @@ void ddsi_write_pmd_message (struct ddsi_thread_state * const thrst, struct ddsi struct ddsi_serdata *serdata; struct ddsi_tkmap_instance *tk; - if ((wr = ddsi_get_builtin_writer (pp, DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER)) == NULL) + if (ddsi_get_builtin_writer (pp, DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER, &wr) != DDS_RETCODE_OK) { GVTRACE ("ddsi_write_pmd_message ("PGUIDFMT") - builtin pmd writer not found\n", PGUID (pp->e.guid)); - return; } + else if (wr != NULL) + { + pmd.participantGuidPrefix = pp->e.guid.prefix; + pmd.kind = pmd_kind; + pmd.value.length = (uint32_t) sizeof (data); + pmd.value.value = data; + serdata = ddsi_serdata_from_sample (gv->pmd_type, SDK_DATA, &pmd); + serdata->timestamp = ddsrt_time_wallclock (); - pmd.participantGuidPrefix = pp->e.guid.prefix; - pmd.kind = pmd_kind; - pmd.value.length = (uint32_t) sizeof (data); - pmd.value.value = data; - serdata = ddsi_serdata_from_sample (gv->pmd_type, SDK_DATA, &pmd); - serdata->timestamp = ddsrt_time_wallclock (); - - tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata); - ddsi_write_sample_nogc (thrst, xp, wr, serdata, tk); - ddsi_tkmap_instance_unref (gv->m_tkmap, tk); + tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata); + ddsi_write_sample_nogc (thrst, xp, wr, serdata, tk); + ddsi_tkmap_instance_unref (gv->m_tkmap, tk); + } #undef PMD_DATA_LENGTH } diff --git a/src/core/ddsi/src/ddsi_security_exchange.c b/src/core/ddsi/src/ddsi_security_exchange.c index bcf41eab98..157d4527fa 100644 --- a/src/core/ddsi/src/ddsi_security_exchange.c +++ b/src/core/ddsi/src/ddsi_security_exchange.c @@ -42,7 +42,7 @@ bool ddsi_write_auth_handshake_message(const struct ddsi_participant *pp, const ddsi_guid_t prd_guid; bool result = false; - if ((wr = ddsi_get_builtin_writer (pp, DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER)) == NULL) { + if (ddsi_get_builtin_writer (pp, DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER, &wr) != DDS_RETCODE_OK || wr == NULL) { GVTRACE ("write_handshake("PGUIDFMT") - builtin stateless message writer not found", PGUID (pp->e.guid)); return false; } @@ -152,7 +152,7 @@ static bool write_crypto_exchange_message(const struct ddsi_participant *pp, con ddsi_seqno_t seq; int r; - if ((wr = ddsi_get_builtin_writer (pp, DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER)) == NULL) + if (ddsi_get_builtin_writer (pp, DDSI_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER, &wr) != DDS_RETCODE_OK || wr == NULL) { GVLOG (DDS_LC_DISCOVERY, "write_crypto_exchange_message("PGUIDFMT") - builtin volatile secure writer not found\n", PGUID (pp->e.guid)); return false; diff --git a/src/core/ddsi/src/ddsi_typelookup.c b/src/core/ddsi/src/ddsi_typelookup.c index 552610c186..e91e3329b9 100644 --- a/src/core/ddsi/src/ddsi_typelookup.c +++ b/src/core/ddsi/src/ddsi_typelookup.c @@ -59,7 +59,7 @@ static struct ddsi_writer *get_typelookup_writer (const struct ddsi_domaingv *gv while (wr == NULL && (pp = ddsi_entidx_enum_participant_next (&est)) != NULL) { if (participant_builtin_writers_ready (pp)) - wr = ddsi_get_builtin_writer (pp, wr_eid); + (void) ddsi_get_builtin_writer (pp, wr_eid, &wr); } ddsi_entidx_enum_participant_fini (&est); ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); diff --git a/src/security/core/tests/common/test_utils.c b/src/security/core/tests/common/test_utils.c index d078cc1ee8..605de1eba7 100644 --- a/src/security/core/tests/common/test_utils.c +++ b/src/security/core/tests/common/test_utils.c @@ -632,8 +632,9 @@ DDS_Security_DatawriterCryptoHandle get_builtin_writer_crypto_handle(dds_entity_ CU_ASSERT_EQUAL_FATAL(dds_entity_pin(participant, &pp_entity), 0); ddsi_thread_state_awake(ddsi_lookup_thread_state(), &pp_entity->m_domain->gv); pp = ddsi_entidx_lookup_participant_guid(pp_entity->m_domain->gv.entity_index, &pp_entity->m_guid); - wr = ddsi_get_builtin_writer (pp, entityid); - CU_ASSERT_FATAL(wr != NULL); + dds_return_t ret = ddsi_get_builtin_writer (pp, entityid, &wr); + CU_ASSERT_FATAL(ret, DDS_RETCODE_OK); + CU_ASSERT_EQUAL_FATAL(wr != NULL); crypto_handle = wr->sec_attr->crypto_handle; ddsi_thread_state_asleep(ddsi_lookup_thread_state()); dds_entity_unpin(pp_entity); From f709b826ffa4365761681cd682fd20f8f1ea9fb6 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Thu, 14 Dec 2023 17:15:53 +0100 Subject: [PATCH 108/207] Add ddsi_get_port_int to internal header Signed-off-by: Dennis Potman --- src/core/ddsi/src/ddsi__portmapping.h | 3 +++ src/core/ddsi/src/ddsi_portmapping.c | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/ddsi/src/ddsi__portmapping.h b/src/core/ddsi/src/ddsi__portmapping.h index 5bda5b7e68..47f4a93414 100644 --- a/src/core/ddsi/src/ddsi__portmapping.h +++ b/src/core/ddsi/src/ddsi__portmapping.h @@ -35,6 +35,9 @@ bool ddsi_valid_portmapping (const struct ddsi_config *config, int32_t participa /** @component port_mapping */ uint32_t ddsi_get_port (const struct ddsi_config *config, enum ddsi_port which, int32_t participant_index); +/** @component port_mapping */ +bool ddsi_get_port_int (uint32_t *port, const struct ddsi_portmapping *map, enum ddsi_port which, uint32_t domain_id, int32_t participant_index, char *str_if_overflow, size_t strsize); + #if defined (__cplusplus) } #endif diff --git a/src/core/ddsi/src/ddsi_portmapping.c b/src/core/ddsi/src/ddsi_portmapping.c index 126d92ebc6..44aea56759 100644 --- a/src/core/ddsi/src/ddsi_portmapping.c +++ b/src/core/ddsi/src/ddsi_portmapping.c @@ -18,7 +18,7 @@ // for a static assert on DDSI_TRAN_RANDOM_PORT_NUMBER #include "ddsi__tran.h" -static bool get_port_int (uint32_t *port, const struct ddsi_portmapping *map, enum ddsi_port which, uint32_t domain_id, int32_t participant_index, char *str_if_overflow, size_t strsize) +bool ddsi_get_port_int (uint32_t *port, const struct ddsi_portmapping *map, enum ddsi_port which, uint32_t domain_id, int32_t participant_index, char *str_if_overflow, size_t strsize) { uint32_t off = UINT32_MAX, ppidx = UINT32_MAX; @@ -109,7 +109,7 @@ bool ddsi_valid_portmapping (const struct ddsi_config *config, int32_t participa int n = snprintf (msg, msgsize, "port number(s) of out range:"); size_t pos = (n >= 0 && (size_t) n <= msgsize) ? (size_t) n : msgsize; do { - if (!get_port_int (&dummy_port, &config->ports, which, config->extDomainId.value, participant_index, str, sizeof (str))) + if (!ddsi_get_port_int (&dummy_port, &config->ports, which, config->extDomainId.value, participant_index, str, sizeof (str))) { n = snprintf (msg + pos, msgsize - pos, "%s %s %s", ok ? "" : ",", portname (which), str); if (n >= 0 && (size_t) n <= msgsize - pos) @@ -125,7 +125,7 @@ uint32_t ddsi_get_port (const struct ddsi_config *config, enum ddsi_port which, /* Not supposed to come here if port mapping is invalid */ uint32_t port; char str[32]; - bool ok = get_port_int (&port, &config->ports, which, config->extDomainId.value, participant_index, str, sizeof (str)); + bool ok = ddsi_get_port_int (&port, &config->ports, which, config->extDomainId.value, participant_index, str, sizeof (str)); assert (ok); (void) ok; return port; From 28e7f98b387270944555f23743561e1e9110ef44 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Thu, 4 Jan 2024 20:14:09 +0100 Subject: [PATCH 109/207] Add function to get type name This adds a function to get the type name from a specific type in a type-map. Signed-off-by: Dennis Potman --- src/core/ddsi/include/dds/ddsi/ddsi_typelib.h | 3 +++ src/core/ddsi/src/ddsi__typewrap.h | 2 ++ src/core/ddsi/src/ddsi_typelib.c | 8 +++++++ src/core/ddsi/src/ddsi_typewrap.c | 24 +++++++++++++++++++ src/core/xtests/symbol_export/symbol_export.c | 1 + 5 files changed, 38 insertions(+) diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_typelib.h b/src/core/ddsi/include/dds/ddsi/ddsi_typelib.h index 18efb89554..8efce1d120 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_typelib.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_typelib.h @@ -88,6 +88,9 @@ DDS_EXPORT void ddsi_typemap_fini (ddsi_typemap_t *typemap); /** @component type_system */ DDS_EXPORT bool ddsi_typemap_equal (const ddsi_typemap_t *a, const ddsi_typemap_t *b); +/** @component type_system */ +DDS_EXPORT const char * ddsi_typemap_get_type_name (const ddsi_typemap_t *typemap, const ddsi_typeid_t *type_id); + /** @component type_system */ dds_return_t ddsi_type_ref_local (struct ddsi_domaingv *gv, struct ddsi_type **type, const struct ddsi_sertype *sertype, ddsi_typeid_kind_t kind); diff --git a/src/core/ddsi/src/ddsi__typewrap.h b/src/core/ddsi/src/ddsi__typewrap.h index c923dc0f43..40099d16d1 100644 --- a/src/core/ddsi/src/ddsi__typewrap.h +++ b/src/core/ddsi/src/ddsi__typewrap.h @@ -47,6 +47,8 @@ dds_return_t ddsi_typeobj_get_hash_id (const struct DDS_XTypes_TypeObject *type_ /** @component xtypes_wrapper */ void ddsi_typeobj_get_hash_id_impl (const struct DDS_XTypes_TypeObject *type_obj, struct DDS_XTypes_TypeIdentifier *type_id); +/** @component xtypes_wrapper */ +const char *ddsi_typeobj_get_type_name_impl (const struct DDS_XTypes_TypeObject *type_obj); /** @component xtypes_wrapper */ dds_return_t ddsi_xt_type_init (struct ddsi_domaingv *gv, struct xt_type *xt, const ddsi_typeid_t *ti, const ddsi_typeobj_t *to); diff --git a/src/core/ddsi/src/ddsi_typelib.c b/src/core/ddsi/src/ddsi_typelib.c index a124b8d675..56c2243eed 100644 --- a/src/core/ddsi/src/ddsi_typelib.c +++ b/src/core/ddsi/src/ddsi_typelib.c @@ -206,6 +206,14 @@ const struct DDS_XTypes_TypeObject * ddsi_typemap_typeobj (const ddsi_typemap_t return NULL; } +const char * ddsi_typemap_get_type_name (const ddsi_typemap_t *typemap, const ddsi_typeid_t *type_id) +{ + const struct DDS_XTypes_TypeObject *type_obj = ddsi_typemap_typeobj (typemap, &type_id->x); + if (type_obj == NULL) + return NULL; + return ddsi_typeobj_get_type_name_impl (type_obj); +} + ddsi_typemap_t *ddsi_typemap_deser (const unsigned char *data, uint32_t sz) { unsigned char *data_ne; diff --git a/src/core/ddsi/src/ddsi_typewrap.c b/src/core/ddsi/src/ddsi_typewrap.c index fda899893e..edd3e24d74 100644 --- a/src/core/ddsi/src/ddsi_typewrap.c +++ b/src/core/ddsi/src/ddsi_typewrap.c @@ -445,6 +445,30 @@ dds_return_t ddsi_typeobj_get_hash_id (const struct DDS_XTypes_TypeObject *type_ return DDS_RETCODE_OK; } +const char *ddsi_typeobj_get_type_name_impl (const struct DDS_XTypes_TypeObject *type_obj) +{ + if (type_obj->_d != DDS_XTypes_EK_COMPLETE) + return NULL; + + switch (type_obj->_u.complete._d) + { + case DDS_XTypes_TK_ALIAS: + return type_obj->_u.complete._u.alias_type.header.detail.type_name; + case DDS_XTypes_TK_STRUCTURE: + return type_obj->_u.complete._u.struct_type.header.detail.type_name; + case DDS_XTypes_TK_UNION: + return type_obj->_u.complete._u.union_type.header.detail.type_name; + case DDS_XTypes_TK_BITSET: + return type_obj->_u.complete._u.bitset_type.header.detail.type_name; + case DDS_XTypes_TK_ENUM: + return type_obj->_u.complete._u.enumerated_type.header.detail.type_name; + case DDS_XTypes_TK_BITMASK: + return type_obj->_u.complete._u.bitmask_type.header.detail.type_name; + default: + return NULL; + } +} + void ddsi_typeobj_fini_impl (struct DDS_XTypes_TypeObject *typeobj) { dds_stream_free_sample (typeobj, &dds_cdrstream_default_allocator, DDS_XTypes_TypeObject_desc.m_ops); diff --git a/src/core/xtests/symbol_export/symbol_export.c b/src/core/xtests/symbol_export/symbol_export.c index c46abf4412..f6e75fa51b 100644 --- a/src/core/xtests/symbol_export/symbol_export.c +++ b/src/core/xtests/symbol_export/symbol_export.c @@ -711,6 +711,7 @@ int main (int argc, char **argv) ddsi_typemap_deser (ptr, 0); ddsi_typemap_fini (ptr); ddsi_typemap_equal (ptr, ptr); + ddsi_typemap_get_type_name (ptr, ptr2); ddsi_type_lookup (ptr, ptr); ddsi_type_compare (ptr, ptr); From 7cfb88f38ec4e3a33b65686d560c8fa26736998e Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Mon, 5 Feb 2024 14:40:26 +0100 Subject: [PATCH 110/207] Add output parameter to DDSI proxy endpoint create functions Signed-off-by: Dennis Potman --- src/core/ddsc/tests/xtypes_common.c | 5 ++- .../include/dds/ddsi/ddsi_proxy_endpoint.h | 42 +++++++++++++++++++ src/core/ddsi/src/ddsi__proxy_endpoint.h | 38 ----------------- src/core/ddsi/src/ddsi_discovery.c | 2 +- src/core/ddsi/src/ddsi_discovery_endpoint.c | 8 ++-- src/core/ddsi/src/ddsi_proxy_endpoint.c | 8 +++- src/core/ddsi/src/ddsi_proxy_participant.c | 10 +++-- src/core/ddsi/tests/wraddrset.c | 7 ++-- src/core/xtests/symbol_export/symbol_export.c | 11 ++++- 9 files changed, 78 insertions(+), 53 deletions(-) diff --git a/src/core/ddsc/tests/xtypes_common.c b/src/core/ddsc/tests/xtypes_common.c index a26b11421d..23a468d443 100644 --- a/src/core/ddsc/tests/xtypes_common.c +++ b/src/core/ddsc/tests/xtypes_common.c @@ -75,10 +75,11 @@ void test_proxy_rd_create (struct ddsi_domaingv *gv, const char *topic_name, DDS CU_ASSERT_FATAL (rc); ddsi_xqos_mergein_missing (&plist->qos, &ddsi_default_qos_reader, ~(uint64_t)0); + struct ddsi_proxy_reader *proxy_reader; #ifdef DDS_HAS_SSM - rc = ddsi_new_proxy_reader (gv, pp_guid, rd_guid, as, plist, ddsrt_time_wallclock (), 1, 0); + rc = ddsi_new_proxy_reader (&proxy_reader, gv, pp_guid, rd_guid, as, plist, ddsrt_time_wallclock (), 1, 0); #else - rc = ddsi_new_proxy_reader (gv, pp_guid, rd_guid, as, plist, ddsrt_time_wallclock (), 1); + rc = ddsi_new_proxy_reader (&proxy_reader, gv, pp_guid, rd_guid, as, plist, ddsrt_time_wallclock (), 1); #endif CU_ASSERT_EQUAL_FATAL (rc, exp_ret); ddsi_plist_fini (plist); diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_proxy_endpoint.h b/src/core/ddsi/include/dds/ddsi/ddsi_proxy_endpoint.h index 92b8e65a70..efef7ab994 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_proxy_endpoint.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_proxy_endpoint.h @@ -101,6 +101,48 @@ struct ddsi_proxy_reader { ddsi_filter_fn_t filter; }; + +/** + * @brief To create a new proxy writer + * @component ddsi_proxy_endpoint + * + * @param proxy_writer out parameter for the created proxy writer + * @param gv domain globals + * @param ppguid the proxy participant is determined from the GUID and must exist + * @param guid guid for the proxy writer + * @param as address set + * @param plist parameter list + * @param dqueue receive queue + * @param evq event queue + * @param timestamp timestamp to be used as creation time for the proxy writer + * @param seq sequence number + * @returns 0 on success + */ +DDS_EXPORT int ddsi_new_proxy_writer (struct ddsi_proxy_writer **proxy_writer, struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct ddsi_addrset *as, const struct ddsi_plist *plist, struct ddsi_dqueue *dqueue, struct ddsi_xeventq *evq, ddsrt_wctime_t timestamp, ddsi_seqno_t seq); + + +/** + * @brief To create a new proxy reader + * @component ddsi_proxy_endpoint + * + * @param proxy_reader out parameter for the created proxy reader + * @param gv domain globals + * @param ppguid the proxy participant is determined from the GUID and must exist + * @param guid guid for the proxy reader + * @param as address set + * @param plist parameter list + * @param timestamp timestamp to be used as creation time for the proxy reader + * @param seq sequence number + * @param favours_ssm indicates if the proxy reader favors ssm + * @return int + */ +DDS_EXPORT int ddsi_new_proxy_reader (struct ddsi_proxy_reader **proxy_reader, struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct ddsi_addrset *as, const struct ddsi_plist *plist, ddsrt_wctime_t timestamp, ddsi_seqno_t seq + +#ifdef DDS_HAS_SSM +, int favours_ssm +#endif +); + #if defined (__cplusplus) } #endif diff --git a/src/core/ddsi/src/ddsi__proxy_endpoint.h b/src/core/ddsi/src/ddsi__proxy_endpoint.h index d157bbe5b4..537c7d2317 100644 --- a/src/core/ddsi/src/ddsi__proxy_endpoint.h +++ b/src/core/ddsi/src/ddsi__proxy_endpoint.h @@ -54,44 +54,6 @@ void ddsi_send_entityid_to_pwr (struct ddsi_proxy_writer *pwr, const ddsi_guid_t /** @component ddsi_proxy_endpoint */ void ddsi_send_entityid_to_prd (struct ddsi_proxy_reader *prd, const ddsi_guid_t *guid); -/** - * @brief To create a new proxy writer - * @component ddsi_proxy_endpoint - * - * @param gv domain globals - * @param ppguid the proxy participant is determined from the GUID and must exist - * @param guid guid for the proxy writer - * @param as address set - * @param plist parameter list - * @param dqueue receive queue - * @param evq event queue - * @param timestamp timestamp to be used as creation time for the proxy writer - * @param seq sequence number - * @returns 0 on success - */ -int ddsi_new_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct ddsi_addrset *as, const struct ddsi_plist *plist, struct ddsi_dqueue *dqueue, struct ddsi_xeventq *evq, ddsrt_wctime_t timestamp, ddsi_seqno_t seq); - - -/** - * @brief To create a new proxy reader - * @component ddsi_proxy_endpoint - * - * @param gv domain globals - * @param ppguid the proxy participant is determined from the GUID and must exist - * @param guid guid for the proxy reader - * @param as address set - * @param plist parameter list - * @param timestamp timestamp to be used as creation time for the proxy reader - * @param seq sequence number - * @param favours_ssm indicates if the proxy reader favors ssm - * @return int - */ -int ddsi_new_proxy_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct ddsi_addrset *as, const struct ddsi_plist *plist, ddsrt_wctime_t timestamp, ddsi_seqno_t seq -#ifdef DDS_HAS_SSM -, int favours_ssm -#endif -); - /** * @brief Delete a proxy writer * @component ddsi_proxy_endpoint diff --git a/src/core/ddsi/src/ddsi_discovery.c b/src/core/ddsi/src/ddsi_discovery.c index 9cd35b7abf..56695b32fc 100644 --- a/src/core/ddsi/src/ddsi_discovery.c +++ b/src/core/ddsi/src/ddsi_discovery.c @@ -143,7 +143,7 @@ struct ddsi_proxy_participant *ddsi_implicitly_create_proxypp (struct ddsi_domai ddsrt_mutex_unlock (&privpp->e.lock); pp_plist.adlink_participant_version_info.flags &= ~DDSI_ADLINK_FL_PARTICIPANT_IS_DDSI2; - ddsi_new_proxy_participant (gv, ppguid, 0, &privguid, as_default, as_meta, &pp_plist, DDS_INFINITY, vendorid, DDSI_CF_IMPLICITLY_CREATED_PROXYPP | DDSI_CF_PROXYPP_NO_SPDP, timestamp, seq); + (void) ddsi_new_proxy_participant (gv, ppguid, 0, &privguid, as_default, as_meta, &pp_plist, DDS_INFINITY, vendorid, DDSI_CF_IMPLICITLY_CREATED_PROXYPP | DDSI_CF_PROXYPP_NO_SPDP, timestamp, seq); } } diff --git a/src/core/ddsi/src/ddsi_discovery_endpoint.c b/src/core/ddsi/src/ddsi_discovery_endpoint.c index eee1cc9975..fa842e2ea8 100644 --- a/src/core/ddsi/src/ddsi_discovery_endpoint.c +++ b/src/core/ddsi/src/ddsi_discovery_endpoint.c @@ -562,9 +562,10 @@ void ddsi_handle_sedp_alive_endpoint (const struct ddsi_receiver_state *rst, dds ddsi_update_proxy_writer (pwr, seq, as, xqos, timestamp); else { + struct ddsi_proxy_writer *proxy_writer; /* not supposed to get here for built-in ones, so can determine the channel based on the transport priority */ assert (!ddsi_is_builtin_entityid (datap->endpoint_guid.entityid, vendorid)); - ddsi_new_proxy_writer (gv, &ppguid, &datap->endpoint_guid, as, datap, gv->user_dqueue, gv->xevents, timestamp, seq); + ddsi_new_proxy_writer (&proxy_writer, gv, &ppguid, &datap->endpoint_guid, as, datap, gv->user_dqueue, gv->xevents, timestamp, seq); } } else @@ -573,10 +574,11 @@ void ddsi_handle_sedp_alive_endpoint (const struct ddsi_receiver_state *rst, dds ddsi_update_proxy_reader (prd, seq, as, xqos, timestamp); else { + struct ddsi_proxy_reader *proxy_reader; #ifdef DDS_HAS_SSM - ddsi_new_proxy_reader (gv, &ppguid, &datap->endpoint_guid, as, datap, timestamp, seq, ssm); + ddsi_new_proxy_reader (&proxy_reader, gv, &ppguid, &datap->endpoint_guid, as, datap, timestamp, seq, ssm); #else - ddsi_new_proxy_reader (gv, &ppguid, &datap->endpoint_guid, as, datap, timestamp, seq); + ddsi_new_proxy_reader (&proxy_reader, gv, &ppguid, &datap->endpoint_guid, as, datap, timestamp, seq); #endif } } diff --git a/src/core/ddsi/src/ddsi_proxy_endpoint.c b/src/core/ddsi/src/ddsi_proxy_endpoint.c index 14ca192e41..df4b131a95 100644 --- a/src/core/ddsi/src/ddsi_proxy_endpoint.c +++ b/src/core/ddsi/src/ddsi_proxy_endpoint.c @@ -227,7 +227,7 @@ static enum ddsi_reorder_mode get_proxy_writer_reorder_mode(const ddsi_entityid_ return DDSI_REORDER_MODE_MONOTONICALLY_INCREASING; } -int ddsi_new_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct ddsi_addrset *as, const ddsi_plist_t *plist, struct ddsi_dqueue *dqueue, struct ddsi_xeventq *evq, ddsrt_wctime_t timestamp, ddsi_seqno_t seq) +int ddsi_new_proxy_writer (struct ddsi_proxy_writer **proxy_writer, struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct ddsi_addrset *as, const ddsi_plist_t *plist, struct ddsi_dqueue *dqueue, struct ddsi_xeventq *evq, ddsrt_wctime_t timestamp, ddsi_seqno_t seq) { struct ddsi_proxy_participant *proxypp; struct ddsi_proxy_writer *pwr; @@ -236,6 +236,7 @@ int ddsi_new_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *ppg enum ddsi_reorder_mode reorder_mode; int ret; + assert (proxy_writer); assert (ddsi_is_writer_entityid (guid->entityid)); assert (ddsi_entidx_lookup_proxy_writer_guid (gv->entity_index, guid) == NULL); @@ -349,6 +350,7 @@ int ddsi_new_proxy_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *ppg pwr->local_matching_inprogress = 0; ddsrt_mutex_unlock (&pwr->e.lock); + *proxy_writer = pwr; return 0; } @@ -569,7 +571,7 @@ int ddsi_proxy_writer_set_notalive (struct ddsi_proxy_writer *pwr, bool notify) /* PROXY-READER ----------------------------------------------------- */ -int ddsi_new_proxy_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct ddsi_addrset *as, const ddsi_plist_t *plist, ddsrt_wctime_t timestamp, ddsi_seqno_t seq +int ddsi_new_proxy_reader (struct ddsi_proxy_reader **proxy_reader, struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct ddsi_addrset *as, const ddsi_plist_t *plist, ddsrt_wctime_t timestamp, ddsi_seqno_t seq #ifdef DDS_HAS_SSM , int favours_ssm #endif @@ -580,6 +582,7 @@ int ddsi_new_proxy_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *ppg ddsrt_mtime_t tnow = ddsrt_time_monotonic (); int ret; + assert (proxy_reader); assert (!ddsi_is_writer_entityid (guid->entityid)); assert (ddsi_entidx_lookup_proxy_reader_guid (gv->entity_index, guid) == NULL); @@ -627,6 +630,7 @@ int ddsi_new_proxy_reader (struct ddsi_domaingv *gv, const struct ddsi_guid *ppg ddsrt_mutex_unlock (&prd->e.lock); ddsi_match_proxy_reader_with_writers (prd, tnow); + *proxy_reader = prd; return DDS_RETCODE_OK; } diff --git a/src/core/ddsi/src/ddsi_proxy_participant.c b/src/core/ddsi/src/ddsi_proxy_participant.c index c693e7d039..4c245ab967 100644 --- a/src/core/ddsi/src/ddsi_proxy_participant.c +++ b/src/core/ddsi/src/ddsi_proxy_participant.c @@ -115,14 +115,18 @@ static void create_proxy_builtin_endpoint_impl (struct ddsi_domaingv *gv, ddsrt_ plist->qos.topic_name = dds_string_dup (topic_name); plist->qos.present |= DDSI_QP_TOPIC_NAME; if (ddsi_is_writer_entityid (ep_guid->entityid)) - ddsi_new_proxy_writer (gv, ppguid, ep_guid, proxypp->as_meta, plist, gv->builtins_dqueue, gv->xevents, timestamp, 0); + { + struct ddsi_proxy_writer *proxy_writer; + ddsi_new_proxy_writer (&proxy_writer, gv, ppguid, ep_guid, proxypp->as_meta, plist, gv->builtins_dqueue, gv->xevents, timestamp, 0); + } else { + struct ddsi_proxy_reader *proxy_reader; #ifdef DDS_HAS_SSM const int ssm = ddsi_addrset_contains_ssm (gv, proxypp->as_meta); - ddsi_new_proxy_reader (gv, ppguid, ep_guid, proxypp->as_meta, plist, timestamp, 0, ssm); + ddsi_new_proxy_reader (&proxy_reader, gv, ppguid, ep_guid, proxypp->as_meta, plist, timestamp, 0, ssm); #else - ddsi_new_proxy_reader (gv, ppguid, ep_guid, proxypp->as_meta, plist, timestamp, 0); + ddsi_new_proxy_reader (&proxy_reader, gv, ppguid, ep_guid, proxypp->as_meta, plist, timestamp, 0); #endif } } diff --git a/src/core/ddsi/tests/wraddrset.c b/src/core/ddsi/tests/wraddrset.c index 330b82e088..d56aac50e8 100644 --- a/src/core/ddsi/tests/wraddrset.c +++ b/src/core/ddsi/tests/wraddrset.c @@ -224,12 +224,13 @@ static void ddsi_wraddrset_some_cases (int casenumber, int cost, bool wr_psmx, c // something else ddsi_add_xlocator_to_addrset (&gv, rd_as, &(ddsi_xlocator_t){ .conn = &fake_conn, .c = psmxloc[i] }); } + struct ddsi_proxy_reader *proxy_reader; #if DDS_HAS_SSM - ddsi_new_proxy_reader (&gv, &rdppguid[i][j], &rdguid, rd_as, &plist_rd, ddsrt_time_wallclock (), 1, false); + ddsi_new_proxy_reader (&proxy_reader, &gv, &rdppguid[i][j], &rdguid, rd_as, &plist_rd, ddsrt_time_wallclock (), 1, false); #else - ddsi_new_proxy_reader (&gv, &rdppguid[i][j], &rdguid, rd_as, &plist_rd, ddsrt_time_wallclock (), 1); + ddsi_new_proxy_reader (&proxy_reader, &gv, &rdppguid[i][j], &rdguid, rd_as, &plist_rd, ddsrt_time_wallclock (), 1); #endif - assert (ddsi_entidx_lookup_proxy_reader_guid (gv.entity_index, &rdguid)); + assert (proxy_reader); ddsi_unref_addrset (rd_as); } } diff --git a/src/core/xtests/symbol_export/symbol_export.c b/src/core/xtests/symbol_export/symbol_export.c index f6e75fa51b..f8fdf2593d 100644 --- a/src/core/xtests/symbol_export/symbol_export.c +++ b/src/core/xtests/symbol_export/symbol_export.c @@ -56,6 +56,7 @@ #include "dds/ddsi/ddsi_typelib.h" #include "dds/ddsi/ddsi_typebuilder.h" #endif +#include "dds/ddsi/ddsi_proxy_endpoint.h" #ifdef DDS_HAS_SECURITY #include "dds/security/core/dds_security_serialize.h" @@ -117,7 +118,7 @@ int main (int argc, char **argv) { (void) argc; (void) argv; - void *ptr = &ptr, *ptr2 = &ptr2, *ptr3 = &ptr3, *ptr4 = &ptr4; + void *ptr = &ptr, *ptr2 = &ptr2, *ptr3 = &ptr3, *ptr4 = &ptr4, *ptr5 = &ptr5, *ptr6 = &ptr6, *ptr7 = &ptr7, *ptr8 = &ptr8; /* The functions shouldn't actually be called, just included here so that the linker resolves the symbols. An early return (with unreachable code @@ -741,6 +742,14 @@ int main (int argc, char **argv) ddsi_topic_descriptor_fini (ptr); #endif + // ddsi/ddsi_proxy_endpoint.h + ddsi_new_proxy_writer (ptr, ptr2, ptr3, ptr4, ptr5, ptr6, ptr7, ptr8, ddsrt_time_wallclock(), 0); +#ifdef DDS_HAS_SSM + ddsi_new_proxy_reader (ptr, ptr2, ptr3, ptr4, ptr5, ptr6, ddsrt_time_wallclock(), 0, 0); +#else + ddsi_new_proxy_reader (ptr, ptr2, ptr3, ptr4, ptr5, ptr6, ddsrt_time_wallclock(), 0); +#endif + // ddsrt/atomics.h ddsrt_atomic_ld32 (ptr); ddsrt_atomic_ldptr (ptr); From 5c2c8b5af603655b76ad75ae8ca1f75a54300439 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Mon, 5 Feb 2024 16:17:05 +0100 Subject: [PATCH 111/207] Add output parameter to DDSI proxy participant create function Signed-off-by: Dennis Potman --- src/core/ddsc/tests/xtypes_common.c | 3 ++- src/core/ddsi/include/dds/ddsi/ddsi_proxy_participant.h | 3 +++ src/core/ddsi/src/ddsi__proxy_participant.h | 3 --- src/core/ddsi/src/ddsi_discovery.c | 5 +++-- src/core/ddsi/src/ddsi_discovery_spdp.c | 3 ++- src/core/ddsi/src/ddsi_proxy_participant.c | 4 +++- src/core/ddsi/tests/wraddrset.c | 5 +++-- src/core/xtests/symbol_export/symbol_export.c | 4 ++++ 8 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/core/ddsc/tests/xtypes_common.c b/src/core/ddsc/tests/xtypes_common.c index 23a468d443..7644939055 100644 --- a/src/core/ddsc/tests/xtypes_common.c +++ b/src/core/ddsc/tests/xtypes_common.c @@ -71,7 +71,8 @@ void test_proxy_rd_create (struct ddsi_domaingv *gv, const char *topic_name, DDS struct ddsi_addrset *as = ddsi_new_addrset (); ddsi_add_locator_to_addrset (gv, as, &gv->loc_default_uc); ddsi_ref_addrset (as); // increase refc to 2, new_proxy_participant does not add a ref - int rc = ddsi_new_proxy_participant (gv, pp_guid, 0, NULL, as, as, plist, DDS_INFINITY, DDSI_VENDORID_ECLIPSE, 0, ddsrt_time_wallclock (), 1); + struct ddsi_proxy_participant *proxy_participant; + int rc = ddsi_new_proxy_participant (&proxy_participant, gv, pp_guid, 0, NULL, as, as, plist, DDS_INFINITY, DDSI_VENDORID_ECLIPSE, 0, ddsrt_time_wallclock (), 1); CU_ASSERT_FATAL (rc); ddsi_xqos_mergein_missing (&plist->qos, &ddsi_default_qos_reader, ~(uint64_t)0); diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_proxy_participant.h b/src/core/ddsi/include/dds/ddsi/ddsi_proxy_participant.h index b66ef46fac..7585b1f337 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_proxy_participant.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_proxy_participant.h @@ -68,6 +68,9 @@ struct ddsi_proxy_participant extern const ddsrt_avl_treedef_t ddsi_proxypp_proxytp_treedef; #endif +/** @component ddsi_proxy_participant */ +DDS_EXPORT bool ddsi_new_proxy_participant (struct ddsi_proxy_participant **proxy_participant, struct ddsi_domaingv *gv, const struct ddsi_guid *guid, uint32_t bes, const struct ddsi_guid *privileged_pp_guid, struct ddsi_addrset *as_default, struct ddsi_addrset *as_meta, const struct ddsi_plist *plist, dds_duration_t tlease_dur, ddsi_vendorid_t vendor, unsigned custom_flags, ddsrt_wctime_t timestamp, ddsi_seqno_t seq); + #if defined (__cplusplus) } #endif diff --git a/src/core/ddsi/src/ddsi__proxy_participant.h b/src/core/ddsi/src/ddsi__proxy_participant.h index 548d2f1647..a1cefd157f 100644 --- a/src/core/ddsi/src/ddsi__proxy_participant.h +++ b/src/core/ddsi/src/ddsi__proxy_participant.h @@ -74,9 +74,6 @@ void ddsi_proxy_participant_remove_pwr_lease_locked (struct ddsi_proxy_participa */ -/** @component ddsi_proxy_participant */ -bool ddsi_new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, uint32_t bes, const struct ddsi_guid *privileged_pp_guid, struct ddsi_addrset *as_default, struct ddsi_addrset *as_meta, const struct ddsi_plist *plist, dds_duration_t tlease_dur, ddsi_vendorid_t vendor, unsigned custom_flags, ddsrt_wctime_t timestamp, ddsi_seqno_t seq); - /** @component ddsi_proxy_participant */ int ddsi_delete_proxy_participant_by_guid (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, ddsrt_wctime_t timestamp, int isimplicit); diff --git a/src/core/ddsi/src/ddsi_discovery.c b/src/core/ddsi/src/ddsi_discovery.c index 56695b32fc..9d8eb0dbe8 100644 --- a/src/core/ddsi/src/ddsi_discovery.c +++ b/src/core/ddsi/src/ddsi_discovery.c @@ -76,6 +76,7 @@ struct ddsi_proxy_participant *ddsi_implicitly_create_proxypp (struct ddsi_domai { ddsi_guid_t privguid; ddsi_plist_t pp_plist; + struct ddsi_proxy_participant *proxy_participant; if (memcmp (&ppguid->prefix, src_guid_prefix, sizeof (ppguid->prefix)) == 0) /* if the writer is owned by the participant itself, we're not interested */ @@ -109,7 +110,7 @@ struct ddsi_proxy_participant *ddsi_implicitly_create_proxypp (struct ddsi_domai doing anything about (1). That means we fall back to the legacy mode of locally generating GIDs but leaving the system id unchanged if the remote is OSPL. */ actual_vendorid = (datap->present & PP_VENDORID) ? datap->vendorid : vendorid; - (void) ddsi_new_proxy_participant (gv, ppguid, 0, &privguid, ddsi_new_addrset(), ddsi_new_addrset(), &pp_plist, DDS_INFINITY, actual_vendorid, DDSI_CF_IMPLICITLY_CREATED_PROXYPP, timestamp, seq); + (void) ddsi_new_proxy_participant (&proxy_participant, gv, ppguid, 0, &privguid, ddsi_new_addrset(), ddsi_new_addrset(), &pp_plist, DDS_INFINITY, actual_vendorid, DDSI_CF_IMPLICITLY_CREATED_PROXYPP, timestamp, seq); } else if (ppguid->prefix.u[0] == src_guid_prefix->u[0] && ddsi_vendor_is_eclipse_or_opensplice (vendorid)) { @@ -143,7 +144,7 @@ struct ddsi_proxy_participant *ddsi_implicitly_create_proxypp (struct ddsi_domai ddsrt_mutex_unlock (&privpp->e.lock); pp_plist.adlink_participant_version_info.flags &= ~DDSI_ADLINK_FL_PARTICIPANT_IS_DDSI2; - (void) ddsi_new_proxy_participant (gv, ppguid, 0, &privguid, as_default, as_meta, &pp_plist, DDS_INFINITY, vendorid, DDSI_CF_IMPLICITLY_CREATED_PROXYPP | DDSI_CF_PROXYPP_NO_SPDP, timestamp, seq); + (void) ddsi_new_proxy_participant (&proxy_participant, gv, ppguid, 0, &privguid, as_default, as_meta, &pp_plist, DDS_INFINITY, vendorid, DDSI_CF_IMPLICITLY_CREATED_PROXYPP | DDSI_CF_PROXYPP_NO_SPDP, timestamp, seq); } } diff --git a/src/core/ddsi/src/ddsi_discovery_spdp.c b/src/core/ddsi/src/ddsi_discovery_spdp.c index baae9d9231..c97114f704 100644 --- a/src/core/ddsi/src/ddsi_discovery_spdp.c +++ b/src/core/ddsi/src/ddsi_discovery_spdp.c @@ -853,7 +853,8 @@ static int handle_spdp_alive (const struct ddsi_receiver_state *rst, ddsi_seqno_ maybe_add_pp_as_meta_to_as_disc (gv, as_meta); - if (!ddsi_new_proxy_participant (gv, &datap->participant_guid, builtin_endpoint_set, &privileged_pp_guid, as_default, as_meta, datap, lease_duration, rst->vendor, custom_flags, timestamp, seq)) + struct ddsi_proxy_participant *proxy_participant; + if (!ddsi_new_proxy_participant (&proxy_participant, gv, &datap->participant_guid, builtin_endpoint_set, &privileged_pp_guid, as_default, as_meta, datap, lease_duration, rst->vendor, custom_flags, timestamp, seq)) { /* If no proxy participant was created, don't respond */ return 0; diff --git a/src/core/ddsi/src/ddsi_proxy_participant.c b/src/core/ddsi/src/ddsi_proxy_participant.c index 4c245ab967..9be68fe30a 100644 --- a/src/core/ddsi/src/ddsi_proxy_participant.c +++ b/src/core/ddsi/src/ddsi_proxy_participant.c @@ -329,7 +329,7 @@ static void free_proxy_participant (struct ddsi_proxy_participant *proxypp) ddsrt_free (proxypp); } -bool ddsi_new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, uint32_t bes, const struct ddsi_guid *privileged_pp_guid, struct ddsi_addrset *as_default, struct ddsi_addrset *as_meta, const ddsi_plist_t *plist, dds_duration_t tlease_dur, ddsi_vendorid_t vendor, unsigned custom_flags, ddsrt_wctime_t timestamp, ddsi_seqno_t seq) +bool ddsi_new_proxy_participant (struct ddsi_proxy_participant **proxy_participant, struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, uint32_t bes, const struct ddsi_guid *privileged_pp_guid, struct ddsi_addrset *as_default, struct ddsi_addrset *as_meta, const ddsi_plist_t *plist, dds_duration_t tlease_dur, ddsi_vendorid_t vendor, unsigned custom_flags, ddsrt_wctime_t timestamp, ddsi_seqno_t seq) { /* No locking => iff all participants use unique guids, and sedp runs on a single thread, it can't go wrong. FIXME, maybe? The @@ -343,6 +343,7 @@ bool ddsi_new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_gui assert (ppguid->entityid.u == DDSI_ENTITYID_PARTICIPANT); assert (ddsi_entidx_lookup_proxy_participant_guid (gv->entity_index, ppguid) == NULL); assert (privileged_pp_guid == NULL || privileged_pp_guid->entityid.u == DDSI_ENTITYID_PARTICIPANT); + assert (proxy_participant); ddsi_prune_deleted_participant_guids (gv->deleted_participants, ddsrt_time_monotonic ()); @@ -477,6 +478,7 @@ bool ddsi_new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_gui ddsi_proxy_participant_create_handshakes (gv, proxypp); } #endif + *proxy_participant = proxypp; return true; } diff --git a/src/core/ddsi/tests/wraddrset.c b/src/core/ddsi/tests/wraddrset.c index d56aac50e8..6e34f98675 100644 --- a/src/core/ddsi/tests/wraddrset.c +++ b/src/core/ddsi/tests/wraddrset.c @@ -199,11 +199,12 @@ static void ddsi_wraddrset_some_cases (int casenumber, int cost, bool wr_psmx, c .entityid = { .u = DDSI_ENTITYID_PARTICIPANT } }; struct ddsi_addrset *proxypp_as = ddsi_new_addrset (); + struct ddsi_proxy_participant *proxy_participant; ddsi_locator_t loc = ucloc[i]; loc.port = 1000 + (unsigned) j; ddsi_add_locator_to_addrset (&gv, proxypp_as, &loc); ddsi_add_locator_to_addrset (&gv, proxypp_as, &mcloc); - ddsi_new_proxy_participant (&gv, &rdppguid[i][j], 0, NULL, proxypp_as, ddsi_ref_addrset (proxypp_as), &plist_pp[i], DDS_INFINITY, DDSI_VENDORID_ECLIPSE, 0, ddsrt_time_wallclock (), 1); - assert (ddsi_entidx_lookup_proxy_participant_guid (gv.entity_index, &rdppguid[i][j])); + ddsi_new_proxy_participant (&proxy_participant, &gv, &rdppguid[i][j], 0, NULL, proxypp_as, ddsi_ref_addrset (proxypp_as), &plist_pp[i], DDS_INFINITY, DDSI_VENDORID_ECLIPSE, 0, ddsrt_time_wallclock (), 1); + assert (proxy_participant != NULL); const ddsi_guid_t rdguid = { .prefix = rdppguid[i][j].prefix, diff --git a/src/core/xtests/symbol_export/symbol_export.c b/src/core/xtests/symbol_export/symbol_export.c index f8fdf2593d..2b1ea88b71 100644 --- a/src/core/xtests/symbol_export/symbol_export.c +++ b/src/core/xtests/symbol_export/symbol_export.c @@ -56,6 +56,7 @@ #include "dds/ddsi/ddsi_typelib.h" #include "dds/ddsi/ddsi_typebuilder.h" #endif +#include "dds/ddsi/ddsi_proxy_participant.h" #include "dds/ddsi/ddsi_proxy_endpoint.h" #ifdef DDS_HAS_SECURITY @@ -750,6 +751,9 @@ int main (int argc, char **argv) ddsi_new_proxy_reader (ptr, ptr2, ptr3, ptr4, ptr5, ptr6, ddsrt_time_wallclock(), 0); #endif + // ddsi/ddsi_proxy_participant.h + ddsi_new_proxy_participant (ptr, ptr2, ptr3, 0, ptr5, ptr6, ptr7, ptr8, 0, (ddsi_vendorid_t) { 0 }, 0, ddsrt_time_wallclock (), 0); + // ddsrt/atomics.h ddsrt_atomic_ld32 (ptr); ddsrt_atomic_ldptr (ptr); From a95ec6955a9947553fc033c36822f3781c84e7e8 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Mon, 8 Apr 2024 13:52:18 +0200 Subject: [PATCH 112/207] Some minor DDSI type-ref refactoring Some refactoring in ddsi_type ref/add function needed for exporting a function that adds a type based on a type-info + type-map. Signed-off-by: Dennis Potman --- src/core/ddsi/include/dds/ddsi/ddsi_typelib.h | 7 ++- src/core/ddsi/src/ddsi__xt_impl.h | 1 + src/core/ddsi/src/ddsi_typelib.c | 62 ++++++++++++------- 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_typelib.h b/src/core/ddsi/include/dds/ddsi/ddsi_typelib.h index 8efce1d120..c67e30fa4f 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_typelib.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_typelib.h @@ -95,10 +95,13 @@ DDS_EXPORT const char * ddsi_typemap_get_type_name (const ddsi_typemap_t *typema dds_return_t ddsi_type_ref_local (struct ddsi_domaingv *gv, struct ddsi_type **type, const struct ddsi_sertype *sertype, ddsi_typeid_kind_t kind); /** @component type_system */ -void ddsi_type_ref (struct ddsi_domaingv *gv, struct ddsi_type **type, const struct ddsi_type *src); +DDS_EXPORT dds_return_t ddsi_type_add (struct ddsi_domaingv *gv, struct ddsi_type **type_minimal, struct ddsi_type **type_complete, const ddsi_typeinfo_t *type_info, const ddsi_typemap_t *type_map); /** @component type_system */ -void ddsi_type_unref (struct ddsi_domaingv *gv, struct ddsi_type *type); +DDS_EXPORT void ddsi_type_ref (struct ddsi_domaingv *gv, struct ddsi_type **type, const struct ddsi_type *src); + +/** @component type_system */ +DDS_EXPORT void ddsi_type_unref (struct ddsi_domaingv *gv, struct ddsi_type *type); /** @component type_system */ void ddsi_type_unref_sertype (struct ddsi_domaingv *gv, const struct ddsi_sertype *sertype); diff --git a/src/core/ddsi/src/ddsi__xt_impl.h b/src/core/ddsi/src/ddsi__xt_impl.h index db8535e733..a62322af62 100644 --- a/src/core/ddsi/src/ddsi__xt_impl.h +++ b/src/core/ddsi/src/ddsi__xt_impl.h @@ -15,6 +15,7 @@ #include #include +#include #include "dds/ddsrt/avl.h" #include "dds/ddsrt/misc.h" #include "dds/ddsi/ddsi_xt_typeinfo.h" diff --git a/src/core/ddsi/src/ddsi_typelib.c b/src/core/ddsi/src/ddsi_typelib.c index 56c2243eed..d7f62d05fe 100644 --- a/src/core/ddsi/src/ddsi_typelib.c +++ b/src/core/ddsi/src/ddsi_typelib.c @@ -646,30 +646,17 @@ static bool valid_top_level_type (const struct ddsi_type *type) return true; } -dds_return_t ddsi_type_ref_local (struct ddsi_domaingv *gv, struct ddsi_type **type, const struct ddsi_sertype *sertype, ddsi_typeid_kind_t kind) +static dds_return_t type_add_ref_impl (struct ddsi_domaingv *gv, struct ddsi_type **type, const ddsi_typeinfo_t *type_info, const ddsi_typemap_t *type_map, ddsi_typeid_kind_t kind) { struct ddsi_generic_proxy_endpoint **gpe_match_upd = NULL; - uint32_t n_match_upd = 0; - struct ddsi_typeid_str tistr; dds_return_t ret = DDS_RETCODE_OK; + uint32_t n_match_upd = 0; bool resolved = false; - - assert (sertype); - assert (kind == DDSI_TYPEID_KIND_MINIMAL || kind == DDSI_TYPEID_KIND_COMPLETE); - ddsi_typeinfo_t *type_info = ddsi_sertype_typeinfo (sertype); - if (!type_info) - { - if (type) - *type = NULL; - return DDS_RETCODE_OK; - } - - ddsi_typemap_t *type_map = ddsi_sertype_typemap (sertype); + struct ddsi_typeid_str tistr; const struct DDS_XTypes_TypeIdentifier *type_id = (kind == DDSI_TYPEID_KIND_MINIMAL) ? &type_info->x.minimal.typeid_with_size.type_id : &type_info->x.complete.typeid_with_size.type_id; const struct DDS_XTypes_TypeObject *type_obj = ddsi_typemap_typeobj (type_map, type_id); - GVTRACE ("ref ddsi_type local sertype %p id %s", sertype, ddsi_make_typeid_str_impl (&tistr, type_id)); - + assert (kind == DDSI_TYPEID_KIND_MINIMAL || kind == DDSI_TYPEID_KIND_COMPLETE); ddsrt_mutex_lock (&gv->typelib_lock); struct ddsi_type *t = ddsi_type_lookup_locked_impl (gv, type_id); if (!t) @@ -696,7 +683,7 @@ dds_return_t ddsi_type_ref_local (struct ddsi_domaingv *gv, struct ddsi_type **t || (ret = type_add_deps (gv, t, type_info, type_map, kind, &n_match_upd, &gpe_match_upd)) || (ret = ddsi_xt_validate (gv, &t->xt))) { - GVWARNING ("local sertype with invalid top-level type %s\n", ddsi_make_typeid_str (&tistr, &t->xt.id)); + GVWARNING ("invalid top-level type %s\n", ddsi_make_typeid_str (&tistr, &t->xt.id)); ddsi_type_unref_locked (gv, t); ddsrt_mutex_unlock (&gv->typelib_lock); goto err; @@ -726,13 +713,44 @@ dds_return_t ddsi_type_ref_local (struct ddsi_domaingv *gv, struct ddsi_type **t *type = t; err: - ddsi_typemap_fini (type_map); - ddsrt_free (type_map); - ddsi_typeinfo_fini (type_info); - ddsrt_free (type_info); return ret; } +dds_return_t ddsi_type_add (struct ddsi_domaingv *gv, struct ddsi_type **type_minimal, struct ddsi_type **type_complete, const ddsi_typeinfo_t *type_info, const ddsi_typemap_t *type_map) +{ + dds_return_t ret; + if ((ret = type_add_ref_impl (gv, type_minimal, type_info, type_map, DDSI_TYPEID_KIND_MINIMAL)) == DDS_RETCODE_OK) + { + assert (*type_minimal != NULL); + ret = type_add_ref_impl (gv, type_complete, type_info, type_map, DDSI_TYPEID_KIND_COMPLETE); + } + return ret; +} + +dds_return_t ddsi_type_ref_local (struct ddsi_domaingv *gv, struct ddsi_type **type, const struct ddsi_sertype *sertype, ddsi_typeid_kind_t kind) +{ + dds_return_t ret = DDS_RETCODE_OK; + assert (sertype); + ddsi_typeinfo_t *type_info = ddsi_sertype_typeinfo (sertype); + if (!type_info) + { + if (type) + *type = NULL; + } + else + { + struct ddsi_typeid_str tistr; + ddsi_typemap_t *type_map = ddsi_sertype_typemap (sertype); + const struct DDS_XTypes_TypeIdentifier *type_id = (kind == DDSI_TYPEID_KIND_MINIMAL) ? &type_info->x.minimal.typeid_with_size.type_id : &type_info->x.complete.typeid_with_size.type_id; + GVTRACE ("ref ddsi_type local sertype %p id %s", sertype, ddsi_make_typeid_str_impl (&tistr, type_id)); + ret = type_add_ref_impl (gv, type, type_info, type_map, kind); + ddsi_typemap_fini (type_map); + ddsrt_free (type_map); + ddsi_typeinfo_fini (type_info); + ddsrt_free (type_info); + } + return ret; +} dds_return_t ddsi_type_ref_proxy (struct ddsi_domaingv *gv, struct ddsi_type **type, const ddsi_typeinfo_t *type_info, ddsi_typeid_kind_t kind, const ddsi_guid_t *proxy_guid) { dds_return_t ret = DDS_RETCODE_OK; From 9152aa47a468f6a544d1c36b4b5b8203e05fb900 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Tue, 6 Feb 2024 09:49:43 +0100 Subject: [PATCH 113/207] Export a set of internal functions Signed-off-by: Dennis Potman --- src/core/ddsc/src/dds__entity.h | 4 +- src/core/ddsi/include/dds/ddsi/ddsi_addrset.h | 16 ++++ .../ddsi/include/dds/ddsi/ddsi_entity_index.h | 2 +- src/core/ddsi/include/dds/ddsi/ddsi_guid.h | 4 +- src/core/ddsi/include/dds/ddsi/ddsi_plist.h | 4 +- .../ddsi/include/dds/ddsi/ddsi_portmapping.h | 10 +++ src/core/ddsi/include/dds/ddsi/ddsi_thread.h | 4 +- src/core/ddsi/include/dds/ddsi/ddsi_tkmap.h | 4 +- src/core/ddsi/include/dds/ddsi/ddsi_tran.h | 2 +- .../ddsi/include/dds/ddsi/ddsi_transmit.h | 2 +- src/core/ddsi/include/dds/ddsi/ddsi_xmsg.h | 6 +- src/core/ddsi/include/dds/ddsi/ddsi_xqos.h | 2 +- src/core/ddsi/src/ddsi__addrset.h | 14 ---- src/core/ddsi/src/ddsi__discovery_addrset.h | 4 +- src/core/ddsi/src/ddsi__ipaddr.h | 2 +- src/core/ddsi/src/ddsi__portmapping.h | 10 --- src/core/xtests/symbol_export/CMakeLists.txt | 1 + src/core/xtests/symbol_export/symbol_export.c | 73 ++++++++++++++++++- src/ddsrt/include/dds/ddsrt/log.h | 4 +- src/ddsrt/include/dds/ddsrt/sockets.h | 2 +- 20 files changed, 122 insertions(+), 48 deletions(-) diff --git a/src/core/ddsc/src/dds__entity.h b/src/core/ddsc/src/dds__entity.h index 10b57d8d6e..da79c684f0 100644 --- a/src/core/ddsc/src/dds__entity.h +++ b/src/core/ddsc/src/dds__entity.h @@ -192,7 +192,7 @@ enum delete_impl_state { dds_return_t dds_delete_impl_pinned (dds_entity *e, enum delete_impl_state delstate); /** @component generic_entity */ -dds_return_t dds_entity_pin (dds_entity_t hdl, dds_entity **eptr); +DDS_EXPORT dds_return_t dds_entity_pin (dds_entity_t hdl, dds_entity **eptr); /** @component generic_entity */ dds_return_t dds_entity_pin_with_origin (dds_entity_t hdl, bool from_user, dds_entity **eptr); @@ -201,7 +201,7 @@ dds_return_t dds_entity_pin_with_origin (dds_entity_t hdl, bool from_user, dds_e dds_return_t dds_entity_pin_for_delete (dds_entity_t hdl, bool explicit, bool from_user, dds_entity **eptr); /** @component generic_entity */ -void dds_entity_unpin (dds_entity *e); +DDS_EXPORT void dds_entity_unpin (dds_entity *e); /** @component generic_entity */ dds_return_t dds_entity_lock (dds_entity_t hdl, dds_entity_kind_t kind, dds_entity **eptr); diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_addrset.h b/src/core/ddsi/include/dds/ddsi/ddsi_addrset.h index 3dddd95adf..0e4ee91480 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_addrset.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_addrset.h @@ -21,6 +21,7 @@ extern "C" { #endif struct ddsi_addrset; +struct ddsi_domaingv; typedef void (*ddsi_addrset_forall_fun_t) (const ddsi_xlocator_t *loc, void *arg); @@ -32,6 +33,21 @@ bool ddsi_addrset_empty (const struct ddsi_addrset *as) void ddsi_addrset_forall (struct ddsi_addrset *as, ddsi_addrset_forall_fun_t f, void *arg) ddsrt_nonnull ((1,2)); +/** @component locators */ +DDS_EXPORT struct ddsi_addrset *ddsi_ref_addrset (struct ddsi_addrset *as); + +/** @component locators */ +DDS_EXPORT void ddsi_unref_addrset (struct ddsi_addrset *as); + +/** @component locators */ +DDS_EXPORT struct ddsi_addrset *ddsi_new_addrset (void) + ddsrt_attribute_warn_unused_result; + +/** @component locators */ +DDS_EXPORT void ddsi_add_locator_to_addrset (const struct ddsi_domaingv *gv, struct ddsi_addrset *as, const ddsi_locator_t *loc) + ddsrt_nonnull_all; + + #if defined (__cplusplus) } #endif diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_entity_index.h b/src/core/ddsi/include/dds/ddsi/ddsi_entity_index.h index 8d350c02ac..a60215b706 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_entity_index.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_entity_index.h @@ -64,7 +64,7 @@ void *ddsi_entidx_lookup_guid (const struct ddsi_entity_index *ei, const struct struct ddsi_participant *ddsi_entidx_lookup_participant_guid (const struct ddsi_entity_index *ei, const struct ddsi_guid *guid) ddsrt_nonnull_all; /** @component entity_index */ -struct ddsi_writer *ddsi_entidx_lookup_writer_guid (const struct ddsi_entity_index *ei, const struct ddsi_guid *guid) ddsrt_nonnull_all; +DDS_EXPORT struct ddsi_writer *ddsi_entidx_lookup_writer_guid (const struct ddsi_entity_index *ei, const struct ddsi_guid *guid) ddsrt_nonnull_all; /** @component entity_index */ struct ddsi_reader *ddsi_entidx_lookup_reader_guid (const struct ddsi_entity_index *ei, const struct ddsi_guid *guid) ddsrt_nonnull_all; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_guid.h b/src/core/ddsi/include/dds/ddsi/ddsi_guid.h index fce244282f..b5316de2fe 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_guid.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_guid.h @@ -32,10 +32,10 @@ typedef struct ddsi_guid { } ddsi_guid_t; /** @component misc */ -ddsi_guid_t ddsi_hton_guid (ddsi_guid_t g); +DDS_EXPORT ddsi_guid_t ddsi_hton_guid (ddsi_guid_t g); /** @component misc */ -ddsi_guid_t ddsi_ntoh_guid (ddsi_guid_t g); +DDS_EXPORT ddsi_guid_t ddsi_ntoh_guid (ddsi_guid_t g); /** @component misc */ ddsi_guid_prefix_t ddsi_hton_guid_prefix (ddsi_guid_prefix_t p); diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_plist.h b/src/core/ddsi/include/dds/ddsi/ddsi_plist.h index 09e223a404..0117def363 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_plist.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_plist.h @@ -160,7 +160,7 @@ typedef struct ddsi_plist { * * @param[out] dest plist_t to be initialized. */ -void ddsi_plist_init_empty (ddsi_plist_t *dest); +DDS_EXPORT void ddsi_plist_init_empty (ddsi_plist_t *dest); /** * @brief Free memory owned by "ps" @@ -174,7 +174,7 @@ void ddsi_plist_init_empty (ddsi_plist_t *dest); * * @param[in] ps ddsi_plist_t for which to free memory */ -void ddsi_plist_fini (ddsi_plist_t *ps); +DDS_EXPORT void ddsi_plist_fini (ddsi_plist_t *ps); #if defined (__cplusplus) } diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_portmapping.h b/src/core/ddsi/include/dds/ddsi/ddsi_portmapping.h index 2946622ae8..dac4f208b7 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_portmapping.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_portmapping.h @@ -19,6 +19,13 @@ extern "C" { #endif +enum ddsi_port { + DDSI_PORT_MULTI_DISC, + DDSI_PORT_MULTI_DATA, + DDSI_PORT_UNI_DISC, + DDSI_PORT_UNI_DATA +}; + struct ddsi_portmapping { uint32_t base; uint32_t dg; @@ -29,6 +36,9 @@ struct ddsi_portmapping { uint32_t d3; }; +/** @component port_mapping */ +DDS_EXPORT bool ddsi_get_port_int (uint32_t *port, const struct ddsi_portmapping *map, enum ddsi_port which, uint32_t domain_id, int32_t participant_index, char *str_if_overflow, size_t strsize); + #if defined (__cplusplus) } #endif diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_thread.h b/src/core/ddsi/include/dds/ddsi/ddsi_thread.h index 9c2f302557..198741bb0c 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_thread.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_thread.h @@ -187,7 +187,7 @@ inline bool ddsi_thread_is_asleep (void) } /** @component thread_support */ -inline void ddsi_thread_state_asleep (struct ddsi_thread_state *thrst) +DDS_INLINE_EXPORT inline void ddsi_thread_state_asleep (struct ddsi_thread_state *thrst) { ddsi_vtime_t vt = ddsrt_atomic_ld32 (&thrst->vtime); assert (ddsi_vtime_awake_p (vt)); @@ -202,7 +202,7 @@ inline void ddsi_thread_state_asleep (struct ddsi_thread_state *thrst) } /** @component thread_support */ -inline void ddsi_thread_state_awake (struct ddsi_thread_state *thrst, const struct ddsi_domaingv *gv) +DDS_INLINE_EXPORT inline void ddsi_thread_state_awake (struct ddsi_thread_state *thrst, const struct ddsi_domaingv *gv) { ddsi_vtime_t vt = ddsrt_atomic_ld32 (&thrst->vtime); assert ((vt & DDSI_VTIME_NEST_MASK) < DDSI_VTIME_NEST_MASK); diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_tkmap.h b/src/core/ddsi/include/dds/ddsi/ddsi_tkmap.h index 0fe45d17a8..53738f3100 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_tkmap.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_tkmap.h @@ -48,10 +48,10 @@ struct ddsi_tkmap_instance * ddsi_tkmap_find(struct ddsi_tkmap *map, struct ddsi struct ddsi_tkmap_instance * ddsi_tkmap_find_by_id (struct ddsi_tkmap *map, uint64_t iid); /** @component key_instance_map */ -struct ddsi_tkmap_instance * ddsi_tkmap_lookup_instance_ref (struct ddsi_tkmap *map, struct ddsi_serdata * sd); +DDS_EXPORT struct ddsi_tkmap_instance * ddsi_tkmap_lookup_instance_ref (struct ddsi_tkmap *map, struct ddsi_serdata * sd); /** @component key_instance_map */ -void ddsi_tkmap_instance_unref (struct ddsi_tkmap *map, struct ddsi_tkmap_instance *tk); +DDS_EXPORT void ddsi_tkmap_instance_unref (struct ddsi_tkmap *map, struct ddsi_tkmap_instance *tk); #if defined (__cplusplus) } diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_tran.h b/src/core/ddsi/include/dds/ddsi/ddsi_tran.h index 1424094c04..cc356db14f 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_tran.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_tran.h @@ -44,7 +44,7 @@ struct ddsi_tran_qos; char *ddsi_xlocator_to_string (char *dst, size_t sizeof_dst, const ddsi_xlocator_t *loc); /** @component locators */ -char *ddsi_locator_to_string (char *dst, size_t sizeof_dst, const ddsi_locator_t *loc); +DDS_EXPORT char *ddsi_locator_to_string (char *dst, size_t sizeof_dst, const ddsi_locator_t *loc); /** @component locators */ char *ddsi_xlocator_to_string_no_port (char *dst, size_t sizeof_dst, const ddsi_xlocator_t *loc); diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_transmit.h b/src/core/ddsi/include/dds/ddsi/ddsi_transmit.h index 577c6563eb..b4b7585aea 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_transmit.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_transmit.h @@ -35,7 +35,7 @@ struct ddsi_thread_state; * @param tk key-instance map instance * @return int */ -int ddsi_write_sample_gc (struct ddsi_thread_state * const thrst, struct ddsi_xpack *xp, struct ddsi_writer *wr, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk); +DDS_EXPORT int ddsi_write_sample_gc (struct ddsi_thread_state * const thrst, struct ddsi_xpack *xp, struct ddsi_writer *wr, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk); /** * @component outgoing_rtps diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_xmsg.h b/src/core/ddsi/include/dds/ddsi/ddsi_xmsg.h index 9f8834e723..23e0133162 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_xmsg.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_xmsg.h @@ -23,13 +23,13 @@ struct ddsi_domaingv; struct ddsi_xpack; /** @component rtps_msg */ -struct ddsi_xpack * ddsi_xpack_new (struct ddsi_domaingv *gv, bool async_mode); +DDS_EXPORT struct ddsi_xpack * ddsi_xpack_new (struct ddsi_domaingv *gv, bool async_mode); /** @component rtps_msg */ -void ddsi_xpack_free (struct ddsi_xpack *xp); +DDS_EXPORT void ddsi_xpack_free (struct ddsi_xpack *xp); /** @component rtps_msg */ -void ddsi_xpack_send (struct ddsi_xpack *xp, bool immediately /* unused */); +DDS_EXPORT void ddsi_xpack_send (struct ddsi_xpack *xp, bool immediately /* unused */); /** @component rtps_msg */ void ddsi_xpack_sendq_init (struct ddsi_domaingv *gv); diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_xqos.h b/src/core/ddsi/include/dds/ddsi/ddsi_xqos.h index e446bed9d4..fdc425650b 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_xqos.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_xqos.h @@ -384,7 +384,7 @@ void ddsi_xqos_mergein_missing (dds_qos_t *a, const dds_qos_t *b, uint64_t mask) * * @returns Bitmask of differences */ -uint64_t ddsi_xqos_delta (const dds_qos_t *a, const dds_qos_t *b, uint64_t mask); +DDS_EXPORT uint64_t ddsi_xqos_delta (const dds_qos_t *a, const dds_qos_t *b, uint64_t mask); /** * @brief Add a property 'name' to the properties of "xqos" if it does not exists diff --git a/src/core/ddsi/src/ddsi__addrset.h b/src/core/ddsi/src/ddsi__addrset.h index 5b23931615..426dd3db0b 100644 --- a/src/core/ddsi/src/ddsi__addrset.h +++ b/src/core/ddsi/src/ddsi__addrset.h @@ -34,20 +34,6 @@ struct ddsi_addrset { typedef ssize_t (*ddsi_addrset_forone_fun_t) (const ddsi_xlocator_t *loc, void *arg); -/** @component locators */ -struct ddsi_addrset *ddsi_new_addrset (void) - ddsrt_attribute_warn_unused_result; - -/** @component locators */ -struct ddsi_addrset *ddsi_ref_addrset (struct ddsi_addrset *as); - -/** @component locators */ -void ddsi_unref_addrset (struct ddsi_addrset *as); - -/** @component locators */ -void ddsi_add_locator_to_addrset (const struct ddsi_domaingv *gv, struct ddsi_addrset *as, const ddsi_locator_t *loc) - ddsrt_nonnull_all; - /** @component locators */ void ddsi_add_xlocator_to_addrset (const struct ddsi_domaingv *gv, struct ddsi_addrset *as, const ddsi_xlocator_t *loc) ddsrt_nonnull_all; diff --git a/src/core/ddsi/src/ddsi__discovery_addrset.h b/src/core/ddsi/src/ddsi__discovery_addrset.h index 47b81b61e4..63ee6cd4b5 100644 --- a/src/core/ddsi/src/ddsi__discovery_addrset.h +++ b/src/core/ddsi/src/ddsi__discovery_addrset.h @@ -25,7 +25,7 @@ typedef struct ddsi_interface_set { /** @brief Initializes an interface set to all-false * @component discovery - * + * * @param[out] intfs interface set to initialize */ void ddsi_interface_set_init (ddsi_interface_set_t *intfs) ddsrt_nonnull_all; @@ -35,7 +35,7 @@ void ddsi_interface_set_init (ddsi_interface_set_t *intfs) * * @param[in] gv domain * @return true iff multicast locators are to be included */ -bool ddsi_include_multicast_locator_in_discovery (const struct ddsi_domaingv *gv) +DDS_EXPORT bool ddsi_include_multicast_locator_in_discovery (const struct ddsi_domaingv *gv) ddsrt_nonnull_all; /** @brief Constructs a new address set from uni- and multicast locators received in SPDP or SEDP diff --git a/src/core/ddsi/src/ddsi__ipaddr.h b/src/core/ddsi/src/ddsi__ipaddr.h index 161853e659..77786a530b 100644 --- a/src/core/ddsi/src/ddsi__ipaddr.h +++ b/src/core/ddsi/src/ddsi__ipaddr.h @@ -31,7 +31,7 @@ int ddsi_ipaddr_compare (const struct sockaddr *const sa1, const struct sockaddr char *ddsi_ipaddr_to_string (char *dst, size_t sizeof_dst, const ddsi_locator_t *loc, int with_port, const struct ddsi_network_interface *interf); /** @component ip_address */ -void ddsi_ipaddr_to_loc (ddsi_locator_t *dst, const struct sockaddr *src, int32_t kind); +DDS_EXPORT void ddsi_ipaddr_to_loc (ddsi_locator_t *dst, const struct sockaddr *src, int32_t kind); /** @component ip_address */ void ddsi_ipaddr_from_loc (struct sockaddr_storage *dst, const ddsi_locator_t *src); diff --git a/src/core/ddsi/src/ddsi__portmapping.h b/src/core/ddsi/src/ddsi__portmapping.h index 47f4a93414..00af1ea952 100644 --- a/src/core/ddsi/src/ddsi__portmapping.h +++ b/src/core/ddsi/src/ddsi__portmapping.h @@ -20,13 +20,6 @@ extern "C" { #endif -enum ddsi_port { - DDSI_PORT_MULTI_DISC, - DDSI_PORT_MULTI_DATA, - DDSI_PORT_UNI_DISC, - DDSI_PORT_UNI_DATA -}; - struct ddsi_config; /** @component port_mapping */ @@ -35,9 +28,6 @@ bool ddsi_valid_portmapping (const struct ddsi_config *config, int32_t participa /** @component port_mapping */ uint32_t ddsi_get_port (const struct ddsi_config *config, enum ddsi_port which, int32_t participant_index); -/** @component port_mapping */ -bool ddsi_get_port_int (uint32_t *port, const struct ddsi_portmapping *map, enum ddsi_port which, uint32_t domain_id, int32_t participant_index, char *str_if_overflow, size_t strsize); - #if defined (__cplusplus) } #endif diff --git a/src/core/xtests/symbol_export/CMakeLists.txt b/src/core/xtests/symbol_export/CMakeLists.txt index 5d9aa40c4a..bccea7a021 100644 --- a/src/core/xtests/symbol_export/CMakeLists.txt +++ b/src/core/xtests/symbol_export/CMakeLists.txt @@ -17,6 +17,7 @@ target_include_directories(symbol_export_test PRIVATE "$>" "$" "$" + "$" "$" "$") diff --git a/src/core/xtests/symbol_export/symbol_export.c b/src/core/xtests/symbol_export/symbol_export.c index 2b1ea88b71..90445dfbba 100644 --- a/src/core/xtests/symbol_export/symbol_export.c +++ b/src/core/xtests/symbol_export/symbol_export.c @@ -37,6 +37,7 @@ #include "dds/ddsrt/xmlparser.h" #include "dds/ddsrt/io.h" #include "dds/ddsrt/ifaddrs.h" +#include "dds/ddsrt/sockets.h" #if DDSRT_HAVE_FILESYSTEM #include "dds/ddsrt/filesystem.h" #endif @@ -58,6 +59,17 @@ #endif #include "dds/ddsi/ddsi_proxy_participant.h" #include "dds/ddsi/ddsi_proxy_endpoint.h" +#include "dds/ddsi/ddsi_plist.h" +#include "dds/ddsi/ddsi_xmsg.h" +#include "dds/ddsi/ddsi_guid.h" +#include "dds/ddsi/ddsi_tkmap.h" +#include "dds/ddsi/ddsi_transmit.h" +#include "dds/ddsi/ddsi_entity_index.h" +#include "dds/ddsi/ddsi_addrset.h" +#include "dds/ddsi/ddsi_tran.h" +#include "dds/ddsi/ddsi_portmapping.h" +#include "ddsi__ipaddr.h" +#include "ddsi__discovery_addrset.h" #ifdef DDS_HAS_SECURITY #include "dds/security/core/dds_security_serialize.h" @@ -78,7 +90,8 @@ #include "dds/cdr/dds_cdrstream.h" -#include "dds__write.h" // dds_write_impl, dds_writecdr_impl +#include "dds__write.h" +#include "dds__entity.h" DDSRT_WARNING_DEPRECATED_OFF DDSRT_WARNING_GNUC_OFF (unused-result) @@ -716,6 +729,9 @@ int main (int argc, char **argv) ddsi_typemap_get_type_name (ptr, ptr2); ddsi_type_lookup (ptr, ptr); ddsi_type_compare (ptr, ptr); + ddsi_type_ref (ptr, ptr2, ptr3); + ddsi_type_unref (ptr, ptr2); + ddsi_type_add (ptr, ptr2, ptr3, ptr4, ptr5); ddsi_make_typeid_str (ptr, ptr); #endif @@ -729,6 +745,8 @@ int main (int argc, char **argv) // ddsi/ddsi_thread.h ddsi_lookup_thread_state (); ddsi_lookup_thread_state_real (); + ddsi_thread_state_asleep (ptr); + ddsi_thread_state_awake (ptr, ptr2); // ddsi/ddsi_gc.h ddsi_gcreq_new (ptr, ptr); @@ -754,6 +772,51 @@ int main (int argc, char **argv) // ddsi/ddsi_proxy_participant.h ddsi_new_proxy_participant (ptr, ptr2, ptr3, 0, ptr5, ptr6, ptr7, ptr8, 0, (ddsi_vendorid_t) { 0 }, 0, ddsrt_time_wallclock (), 0); + // ddsi/ddsi_plist.h + ddsi_plist_init_empty (ptr); + ddsi_plist_fini (ptr); + + // ddsi/ddsi_xqos.h + ddsi_xqos_delta (ptr, ptr2, 0); + + // ddsi/ddsi_xmsg.h + (void) ddsi_xpack_new (ptr, false); + ddsi_xpack_free (ptr); + ddsi_xpack_send (ptr, false); + + // ddsi/ddsi_guid.h + ddsi_hton_guid ((ddsi_guid_t) { 0 }); + ddsi_ntoh_guid ((ddsi_guid_t) { 0 }); + + // ddsi/ddsi_tkmap.h + (void) ddsi_tkmap_lookup_instance_ref (ptr, ptr2); + ddsi_tkmap_instance_unref (ptr, ptr2); + + // ddsi/ddsi_transmit.h + ddsi_write_sample_gc (ptr, ptr2, ptr3, ptr4, ptr5); + + // ddsi/ddsi_entity_index.h + (void) ddsi_entidx_lookup_writer_guid (ptr, ptr2); + + // ddsi/ddsi_addrset.h + (void) ddsi_ref_addrset (ptr); + ddsi_unref_addrset (ptr); + (void) ddsi_new_addrset (); + ddsi_add_locator_to_addrset (ptr, ptr2, ptr3); + + // ddsi/ddsi_tran.h + (void) ddsi_locator_to_string (ptr, 0, ptr2); + + // ddsi/ddsi_portmapping.h + ddsi_get_port_int (ptr, ptr2, 0, 0, 0, ptr3, 0); + + // ddsi__ipaddr.h + ddsi_ipaddr_to_loc (ptr, ptr2, 0); + + // ddsi__discovery_addrset.h + ddsi_include_multicast_locator_in_discovery (ptr); + + // ddsrt/atomics.h ddsrt_atomic_ld32 (ptr); ddsrt_atomic_ldptr (ptr); @@ -1028,6 +1091,7 @@ int main (int argc, char **argv) // ddsrt/log.h dds_log (0, ptr, 0, ptr, " "); dds_set_log_mask (0); // ROS 2 rmw_cyclonedds_cpp needs this, probably erroneously + dds_get_log_mask (); // ddsrt/sockets.h #if DDSRT_HAVE_GETHOSTNAME @@ -1092,10 +1156,17 @@ int main (int argc, char **argv) ddsrt_getifaddrs (ptr, ptr); ddsrt_freeifaddrs (ptr); + // ddsrt/sockets.h + ddsrt_sockaddrfromstr (0, ptr, ptr2); + // dds__write.h dds_write_impl (ptr, ptr, 0, (dds_write_action) 0); dds_writecdr_impl (ptr, ptr, ptr, false); + // dds__entity.h + dds_entity_pin (0, ptr); + dds_entity_unpin (ptr); + return 0; } diff --git a/src/ddsrt/include/dds/ddsrt/log.h b/src/ddsrt/include/dds/ddsrt/log.h index c4971b1f0a..a22d312927 100644 --- a/src/ddsrt/include/dds/ddsrt/log.h +++ b/src/ddsrt/include/dds/ddsrt/log.h @@ -151,14 +151,14 @@ typedef struct ddsrt_log_cfg { } u; } ddsrt_log_cfg_t; -extern uint32_t *const dds_log_mask; +DDS_EXPORT extern uint32_t *const dds_log_mask; /** * @brief Get currently enabled log and trace categories. * * @returns A uint32_t with enabled categories set. */ -inline uint32_t +DDS_INLINE_EXPORT inline uint32_t dds_get_log_mask(void) { return *dds_log_mask; diff --git a/src/ddsrt/include/dds/ddsrt/sockets.h b/src/ddsrt/include/dds/ddsrt/sockets.h index 8e885d3f6e..9c5e681988 100644 --- a/src/ddsrt/include/dds/ddsrt/sockets.h +++ b/src/ddsrt/include/dds/ddsrt/sockets.h @@ -495,7 +495,7 @@ ddsrt_nonnull_all; * * See @ref ddsrt_sockaddrtostr */ -dds_return_t +DDS_EXPORT dds_return_t ddsrt_sockaddrfromstr( int af, const char *str, void *sa); From 4c98862fbf48e5e033fbade7bc8e119f9549473b Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Thu, 28 Mar 2024 13:07:22 +0100 Subject: [PATCH 114/207] PSMX deliver samples for non-discovered writers This adds an option to the PSMX-IOX plugin to allow delivering data from writers that are not discovered by the receiving node and as a result are not matched with the reader. The plugin uses defaults for some relevant QoS settings when storing the sample, so the writers need to have these defaults in their QoS when this option is enabled. Signed-off-by: Dennis Potman --- src/psmx_iox/src/psmx_iox_impl.cpp | 52 +++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/src/psmx_iox/src/psmx_iox_impl.cpp b/src/psmx_iox/src/psmx_iox_impl.cpp index f0f2e152bf..e105a275cd 100644 --- a/src/psmx_iox/src/psmx_iox_impl.cpp +++ b/src/psmx_iox/src/psmx_iox_impl.cpp @@ -92,16 +92,17 @@ static bool is_wildcard_partition(const char *str) struct iox_psmx : public dds_psmx_t { - iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service_name, const dds_psmx_node_identifier_t& node_id, bool support_keyed_topics); + iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service_name, const dds_psmx_node_identifier_t& node_id, bool support_keyed_topics, bool allow_nondisc_wr); ~iox_psmx(); bool _support_keyed_topics; + bool _allow_nondisc_wr; iox::capro::IdString_t _service_name; std::unique_ptr _listener; //the listener needs to be created after iox runtime has been initialized dds_psmx_node_identifier_t _node_id = { 0 }; std::shared_ptr _node_id_publisher; }; -iox_psmx::iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service_name, const dds_psmx_node_identifier_t& node_id, bool support_keyed_topics) : +iox_psmx::iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service_name, const dds_psmx_node_identifier_t& node_id, bool support_keyed_topics, bool allow_nondisc_wr) : dds_psmx_t { .ops = psmx_ops, .instance_name = dds_string_dup ("CycloneDDS-IOX-PSMX"), @@ -111,6 +112,7 @@ iox_psmx::iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service .psmx_topics = nullptr }, _support_keyed_topics{support_keyed_topics}, + _allow_nondisc_wr{allow_nondisc_wr}, _service_name{iox::capro::IdString_t(iox::cxx::TruncateToCapacity, service_name)}, _listener{} { @@ -359,9 +361,9 @@ iox_loaned_sample::~iox_loaned_sample() static bool iox_type_qos_supported(struct dds_psmx * psmx, dds_psmx_endpoint_type_t forwhat, dds_data_type_properties_t data_type_props, const struct dds_qos * qos) { + auto iox_psmx = static_cast(psmx); if (data_type_props & DDS_DATA_TYPE_CONTAINS_KEY) { - auto iox_psmx = static_cast(psmx); if (!iox_psmx->_support_keyed_topics) return false; } @@ -409,6 +411,23 @@ static bool iox_type_qos_supported(struct dds_psmx * psmx, dds_psmx_endpoint_typ dds_duration_t deadline_duration; if (dds_qget_deadline(qos, &deadline_duration) && deadline_duration != DDS_INFINITY) return false; + + if (forwhat == DDS_PSMX_ENDPOINT_TYPE_WRITER && iox_psmx->_allow_nondisc_wr) + { + // In case this instance is configured to allow delivering data from non-discovered + // writers, it will use specific settings for these 3 QoS policies when storing the + // sample in the RHC, so a writer must have these policies set to these specific values. + dds_ownership_kind_t ownership_kind; + if (dds_qget_ownership (qos, &ownership_kind) && ownership_kind != DDS_OWNERSHIP_SHARED) + return false; + bool autodispose; + if (dds_qget_writer_data_lifecycle (qos, &autodispose) && autodispose) + return false; + dds_duration_t lifespan; + if (dds_qget_lifespan (qos, &lifespan) && lifespan != DDS_INFINITY) + return false; + } + return true; } @@ -529,7 +548,21 @@ static void on_incoming_data_callback(iox::popo::UntypedSubscriber * subscriber, subscriber->take().and_then([psmx_endpoint](auto& sample) { psmx_endpoint->lock.unlock(); auto data = incoming_sample_to_loan(psmx_endpoint, sample); - (void) dds_reader_store_loaned_sample(psmx_endpoint->cdds_endpoint, data); + if (psmx_endpoint->_parent._parent._allow_nondisc_wr) + { + // By using dds_reader_store_loaned_sample_wr_metadata, Cyclone will accept data + // from writers that are not discovered and use the provided defaults for the + // relevant QoS settings. + int32_t ownership_strength = 0; + bool autodispose_unregistered_instances = false; + dds_duration_t lifespan_duration = DDS_INFINITY; + (void) dds_reader_store_loaned_sample_wr_metadata(psmx_endpoint->cdds_endpoint, data, ownership_strength, autodispose_unregistered_instances, lifespan_duration); + } + else + { + (void) dds_reader_store_loaned_sample(psmx_endpoint->cdds_endpoint, data); + } + dds_loaned_sample_unref(data); psmx_endpoint->lock.lock(); }); @@ -666,6 +699,15 @@ dds_return_t iox_create_psmx(struct dds_psmx **psmx, dds_psmx_instance_id_t inst return DDS_RETCODE_ERROR; } - *psmx = new iox_psmx::iox_psmx(instance_id, service_name, node_id.value(), keyed_topics); + auto opt_allow_nondisc_wr = get_config_option_value(config, "ALLOW_NONDISCOVERED_WRITERS", true); + bool allow_nondisc_wr = false; + if (opt_allow_nondisc_wr.has_value()) { + if (opt_allow_nondisc_wr.value() == "true") + allow_nondisc_wr = true; + else if (opt_allow_nondisc_wr.value() != "false") + return DDS_RETCODE_ERROR; + } + + *psmx = new iox_psmx::iox_psmx(instance_id, service_name, node_id.value(), keyed_topics, allow_nondisc_wr); return *psmx ? DDS_RETCODE_OK : DDS_RETCODE_ERROR; } From dc96465eaa9e579d349b5845c536f72312c0cb33 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Wed, 10 Apr 2024 15:56:10 +0200 Subject: [PATCH 115/207] Include internal API header is dds_participant Signed-off-by: Dennis Potman --- src/core/ddsc/src/dds_participant.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/ddsc/src/dds_participant.c b/src/core/ddsc/src/dds_participant.c index cdcdde81f0..a3551d1b6f 100644 --- a/src/core/ddsc/src/dds_participant.c +++ b/src/core/ddsc/src/dds_participant.c @@ -20,6 +20,7 @@ #include "dds/ddsi/ddsi_plist.h" #include "dds/ddsi/ddsi_domaingv.h" #include "dds/ddsi/ddsi_entity_index.h" +#include "dds/ddsc/dds_internal_api.h" #include "dds/version.h" #include "dds__init.h" #include "dds__domain.h" From c62b471f89e1408d9afe69b4c3c67dddbd4774ab Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Wed, 10 Apr 2024 17:48:58 +0200 Subject: [PATCH 116/207] Fix incorrect CU_ASSERTS in test utils Signed-off-by: Dennis Potman --- src/security/core/tests/common/test_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/security/core/tests/common/test_utils.c b/src/security/core/tests/common/test_utils.c index 605de1eba7..7940abedad 100644 --- a/src/security/core/tests/common/test_utils.c +++ b/src/security/core/tests/common/test_utils.c @@ -633,8 +633,8 @@ DDS_Security_DatawriterCryptoHandle get_builtin_writer_crypto_handle(dds_entity_ ddsi_thread_state_awake(ddsi_lookup_thread_state(), &pp_entity->m_domain->gv); pp = ddsi_entidx_lookup_participant_guid(pp_entity->m_domain->gv.entity_index, &pp_entity->m_guid); dds_return_t ret = ddsi_get_builtin_writer (pp, entityid, &wr); - CU_ASSERT_FATAL(ret, DDS_RETCODE_OK); - CU_ASSERT_EQUAL_FATAL(wr != NULL); + CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK); + CU_ASSERT_FATAL(wr != NULL); crypto_handle = wr->sec_attr->crypto_handle; ddsi_thread_state_asleep(ddsi_lookup_thread_state()); dds_entity_unpin(pp_entity); From 15b3a09b6346c5adc3599bc19aad269f6eb5fd6f Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Thu, 11 Apr 2024 15:27:51 +0200 Subject: [PATCH 117/207] Export dds_entity_lock/unlock Signed-off-by: Dennis Potman --- src/core/ddsc/src/dds__entity.h | 4 ++-- src/core/xtests/symbol_export/symbol_export.c | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/ddsc/src/dds__entity.h b/src/core/ddsc/src/dds__entity.h index da79c684f0..0759f7c7af 100644 --- a/src/core/ddsc/src/dds__entity.h +++ b/src/core/ddsc/src/dds__entity.h @@ -204,10 +204,10 @@ dds_return_t dds_entity_pin_for_delete (dds_entity_t hdl, bool explicit, bool fr DDS_EXPORT void dds_entity_unpin (dds_entity *e); /** @component generic_entity */ -dds_return_t dds_entity_lock (dds_entity_t hdl, dds_entity_kind_t kind, dds_entity **eptr); +DDS_EXPORT dds_return_t dds_entity_lock (dds_entity_t hdl, dds_entity_kind_t kind, dds_entity **eptr); /** @component generic_entity */ -void dds_entity_unlock (dds_entity *e); +DDS_EXPORT void dds_entity_unlock (dds_entity *e); /** @component generic_entity */ dds_return_t dds_entity_observer_register ( diff --git a/src/core/xtests/symbol_export/symbol_export.c b/src/core/xtests/symbol_export/symbol_export.c index 90445dfbba..aa1ffa7988 100644 --- a/src/core/xtests/symbol_export/symbol_export.c +++ b/src/core/xtests/symbol_export/symbol_export.c @@ -1166,6 +1166,8 @@ int main (int argc, char **argv) // dds__entity.h dds_entity_pin (0, ptr); dds_entity_unpin (ptr); + dds_entity_lock (0, 0, ptr); + dds_entity_unlock (ptr); return 0; } From a16a718598b8d59ef43fc555dc6e60bfe9229c9a Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 10 Jun 2024 15:51:20 +0200 Subject: [PATCH 118/207] Check for sync delivery for filtered proxy writers Creating a proxy writer with the "filtered" flag set is not currently possible via the API and the only ones that are created are built-in ones. Since all built-in ones are using the asynchronous path anyway the absence of a synchronous path is not actually a bug, but the undocumented deviation of the pattern is. Not deviating from the patter is the better option here, especially because it is constitutes a significant fraction of performing content filtering at the writer and so its use is likely to be extended. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_receive.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/ddsi/src/ddsi_receive.c b/src/core/ddsi/src/ddsi_receive.c index d4e46219b4..ba49c22ef3 100644 --- a/src/core/ddsi/src/ddsi_receive.c +++ b/src/core/ddsi/src/ddsi_receive.c @@ -1352,7 +1352,12 @@ static int handle_Heartbeat (struct ddsi_receiver_state *rst, ddsrt_etime_t tnow // use the advertised first sequence number in the WHC struct ddsi_reorder *ro = wn->u.not_in_sync.reorder; if ((res = ddsi_reorder_gap (&sc, ro, gap, 1, firstseq, &refc_adjust)) > 0) - ddsi_dqueue_enqueue1 (pwr->dqueue, &wn->rd_guid, &sc, res); + { + if (pwr->deliver_synchronously) + deliver_user_data_synchronously (&sc, &wn->rd_guid); + else + ddsi_dqueue_enqueue1 (pwr->dqueue, &wn->rd_guid, &sc, res); + } if (ddsi_from_seqno (msg->lastSN) > wn->last_seq) { wn->last_seq = ddsi_from_seqno (msg->lastSN); From 845ae76d27402c3eb61f70da4de40c5e8d08f35d Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 10 Jun 2024 14:51:23 +0200 Subject: [PATCH 119/207] Partial support for building on macOS Snow Leopard * Skip use of ip_mreqn if on macOS < 10.7 * Define MAXTHREADNAMESIZE on macOS if not already defined * Avoid pthread_threadid_np on macOS < 10.6 or macOS + PowerPC * Parenthesize compound literal argument in memcpy Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_udp.c | 8 +++++++- src/ddsrt/src/threads/posix/threads.c | 10 +++++++--- .../cryptographic/src/crypto_transform.c | 9 +++++++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/core/ddsi/src/ddsi_udp.c b/src/core/ddsi/src/ddsi_udp.c index 6a68f398e7..cc0d4539f3 100644 --- a/src/core/ddsi/src/ddsi_udp.c +++ b/src/core/ddsi/src/ddsi_udp.c @@ -12,6 +12,10 @@ #define __APPLE_USE_RFC_3542 #define _GNU_SOURCE +#ifdef __APPLE__ +#include +#endif + #include #include #include "dds/ddsrt/atomics.h" @@ -500,7 +504,9 @@ static dds_return_t set_mc_options_transmit_ipv6 (struct ddsi_domaingv const * c static dds_return_t set_mc_options_transmit_ipv4_if (struct ddsi_domaingv const * const gv, struct ddsi_network_interface const * const intf, ddsrt_socket_t sock) { -#if (defined(__linux) || defined(__APPLE__)) && !LWIP_SOCKET +/* ip_mreqn is available on macOS 10.7+ */ +#if ((defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7)) \ + || defined(__linux)) && !LWIP_SOCKET if (gv->config.use_multicast_if_mreqn) { struct ip_mreqn mreqn; diff --git a/src/ddsrt/src/threads/posix/threads.c b/src/ddsrt/src/threads/posix/threads.c index f61a4f6ed4..466a0a646e 100644 --- a/src/ddsrt/src/threads/posix/threads.c +++ b/src/ddsrt/src/threads/posix/threads.c @@ -49,6 +49,10 @@ typedef struct { #include #include #include +#include +#ifndef MAXTHREADNAMESIZE +#define MAXTHREADNAMESIZE (64) +#endif /* MAXTHREADNAMESIZE */ #elif defined(__sun) #define MAXTHREADNAMESIZE (31) #elif defined(__FreeBSD__) @@ -455,9 +459,9 @@ ddsrt_gettid(void) #elif defined(__FreeBSD__) && (__FreeBSD__ >= 9) /* FreeBSD >= 9.0 */ tid = pthread_getthreadid_np(); -#elif defined(__APPLE__) && !(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \ - __MAC_OS_X_VERSION_MIN_REQUIRED < 1060) - /* macOS >= 10.6 */ +#elif defined(__APPLE__) && !defined(__POWERPC__) && \ + !(defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060) + /* macOS >= 10.6, but for ppc this symbol is unavailable */ pthread_threadid_np(NULL, &tid); #elif defined(__VXWORKS__) tid = taskIdSelf(); diff --git a/src/security/builtin_plugins/cryptographic/src/crypto_transform.c b/src/security/builtin_plugins/cryptographic/src/crypto_transform.c index 08a8136ce7..9149edef2a 100644 --- a/src/security/builtin_plugins/cryptographic/src/crypto_transform.c +++ b/src/security/builtin_plugins/cryptographic/src/crypto_transform.c @@ -328,10 +328,15 @@ static bool read_submsg_header (tainted_input_buffer_t *input, uint8_t smid, dds if (hdr->octetsToNextHeader > (size_t) (input->endp - input->ptr)) return false; - // silly C can't deal with assignment to *submsg_view in any way because of endp + // Silly C can't deal with assignment to *submsg_view in any way because of endp // memcpy to the rescue! + // + // Using the address of the literal directly in the argument to memcpy causes a compilation error + // on ancient macOS, presumably memcpy is defined as a macro. The extra pair of parentheses fixes + // it. + // // coverity[store_writes_const_field] - memcpy (submsg_view, &(tainted_input_buffer_t){ .ptr = input->ptr, .endp = input->ptr + hdr->octetsToNextHeader }, sizeof (*submsg_view)); + memcpy (submsg_view, (&(tainted_input_buffer_t){ .ptr = input->ptr, .endp = input->ptr + hdr->octetsToNextHeader }), sizeof (*submsg_view)); input->ptr += hdr->octetsToNextHeader; return true; } From 6aeb7ca7a224a97e3a744416a3e24441d0438f34 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 10 Jun 2024 17:04:56 +0200 Subject: [PATCH 120/207] Avoid IP_PKTINFO on Snow Leopard Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_udp.c | 40 ++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/core/ddsi/src/ddsi_udp.c b/src/core/ddsi/src/ddsi_udp.c index cc0d4539f3..2a5823bff9 100644 --- a/src/core/ddsi/src/ddsi_udp.c +++ b/src/core/ddsi/src/ddsi_udp.c @@ -39,6 +39,22 @@ #define UDP_MC_ADDRESS_PREFIX_BITS 4 DDSRT_STATIC_ASSERT (DDSI_LOCATOR_UDPv4MCGEN_INDEX_MASK_BITS <= 32 - UDP_MC_ADDRESS_PREFIX_BITS); +// At some point, macOS added "struct in_pktinfo", but I don't know exactly when. Snow Leopard doesn't have it +// so let's set the cutoff at 10.7 +// +// The remaining logic seems to work well for the supported platforms +#if defined __APPLE__ +# if defined MAC_OS_X_VERSION_MIN_REQUIRED && MAC_OS_X_VERSION_MIN_REQUIRED < 1070 +# define PACKET_DESTINATION_INFO 0 +# endif +#endif +#ifndef PACKET_DESTINATION_INFO +# if defined CMSG_SPACE && (defined IP_PKTINFO || (DDSRT_HAVE_IPV6 && defined IPV6_PKTINFO)) +# define PACKET_DESTINATION_INFO 1 +# else +# define PACKET_DESTINATION_INFO 0 +# endif +#endif union addr { struct sockaddr_storage x; @@ -75,6 +91,7 @@ static void addr_to_loc (const struct ddsi_tran_factory *tran, ddsi_locator_t *d static void translate_pktinfo (struct ddsi_network_packet_info *pktinfo, ddsrt_msghdr_t *msghdr_in, uint32_t port, bool ipv6) { +#if PACKET_DESTINATION_INFO // msghdr_in is not const .... because ... Linux ... // for the rest: I hate Windows, with good reason. #ifndef _WIN32 @@ -87,7 +104,6 @@ static void translate_pktinfo (struct ddsi_network_packet_info *pktinfo, ddsrt_m #endif #endif // in_addr / in6_addr, so the conversion functions that deal with sockaddr are not applicable -#ifdef CMSG_SPACE // skip everything if control message supported not defined #if DDSRT_HAVE_IPV6 && defined IPV6_PKTINFO if (ipv6) { @@ -106,7 +122,7 @@ static void translate_pktinfo (struct ddsi_network_packet_info *pktinfo, ddsrt_m } #else (void) ipv6; -#endif // HAVE_IPV6 && IPV6_PKTINFO +#endif // DDSRT_HAVE_IPV6 && defined IPV6_PKTINFO #if defined IP_PKTINFO for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (msghdr); cmsg != NULL; cmsg = CMSG_NXTHDR (msghdr, cmsg)) { @@ -121,8 +137,12 @@ static void translate_pktinfo (struct ddsi_network_packet_info *pktinfo, ddsrt_m return; } } -#endif -#endif // CMSG_SPACE +#endif // defined IP_PKTINFO +#else // PACKET_DESTINATION_INFO + (void) ipv6; + (void) msghdr_in; + (void) port; +#endif // PACKET_DESTINATION_INFO // early outs as soon as packet info has been set, so if we get here, we don't know anything pktinfo->dst.kind = DDSI_LOCATOR_KIND_INVALID; pktinfo->if_index = 0; @@ -133,15 +153,17 @@ static ssize_t ddsi_udp_conn_read (struct ddsi_tran_conn * conn_cmn, unsigned ch ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn; struct ddsi_domaingv * const gv = conn->m_base.m_base.gv; union addr src; -#ifdef CMSG_SPACE +#if PACKET_DESTINATION_INFO union in_pktinfo_4_6 { +#if defined IP_PKTINFO struct in_pktinfo ip4; -#if DDSRT_HAVE_IPV6 +#endif +#if DDSRT_HAVE_IPV6 && defined IPV6_PKTINFO struct in6_pktinfo ip6; #endif }; char incmsg[CMSG_SPACE (sizeof (union in_pktinfo_4_6))]; -#endif +#endif // PACKET_DESTINATION_INFO ddsrt_iovec_t msg_iov = { .iov_base = (void *) buf, .iov_len = (ddsrt_iov_len_t) len /* Windows uses unsigned, POSIX (except Linux) int */ @@ -151,11 +173,11 @@ static ssize_t ddsi_udp_conn_read (struct ddsi_tran_conn * conn_cmn, unsigned ch .msg_namelen = (socklen_t) sizeof (src), .msg_iov = &msg_iov, .msg_iovlen = 1 -#ifdef CMSG_SPACE +#if PACKET_DESTINATION_INFO , .msg_controllen = sizeof (incmsg), .msg_control = incmsg -#endif +#endif // PACKET_DESTINATION_INFO // accrights/control implicitly initialised to 0 // msg_flags is an out parameter anyway }; From dbba39b3771954204f621b6b03039725deed27aa Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 7 Jun 2024 10:03:17 +0200 Subject: [PATCH 121/207] Rename cdrstream parts from .part.c to .part.h This way they can be listed in CMakeLists.txt without causing trouble, that makes them show up in Xcode projects, and that in turn makes Xcode search them when doing full text search. Signed-off-by: Erik Boasson --- src/core/cdr/CMakeLists.txt | 4 +++- src/core/cdr/src/dds_cdrstream.c | 10 +++++----- ...cdrstream_keys.part.c => dds_cdrstream_keys.part.h} | 0 ...rstream_write.part.c => dds_cdrstream_write.part.h} | 0 4 files changed, 8 insertions(+), 6 deletions(-) rename src/core/cdr/src/{dds_cdrstream_keys.part.c => dds_cdrstream_keys.part.h} (100%) rename src/core/cdr/src/{dds_cdrstream_write.part.c => dds_cdrstream_write.part.h} (100%) diff --git a/src/core/cdr/CMakeLists.txt b/src/core/cdr/CMakeLists.txt index 284a01b4c6..c79a450463 100644 --- a/src/core/cdr/CMakeLists.txt +++ b/src/core/cdr/CMakeLists.txt @@ -16,7 +16,9 @@ if(NOT ${CMAKE_PROJECT_NAME} STREQUAL "CycloneDDS") endif() set(srcs_cdr - "${CMAKE_CURRENT_LIST_DIR}/src/dds_cdrstream.c") + "${CMAKE_CURRENT_LIST_DIR}/src/dds_cdrstream.c" + "${CMAKE_CURRENT_LIST_DIR}/src/dds_cdrstream_keys.part.h" + "${CMAKE_CURRENT_LIST_DIR}/src/dds_cdrstream_write.part.h") set(hdrs_private_cdr "${CMAKE_CURRENT_LIST_DIR}/include/dds/cdr/dds_cdrstream.h") diff --git a/src/core/cdr/src/dds_cdrstream.c b/src/core/cdr/src/dds_cdrstream.c index 8367f3e1aa..a7e460e4bd 100644 --- a/src/core/cdr/src/dds_cdrstream.c +++ b/src/core/cdr/src/dds_cdrstream.c @@ -1422,17 +1422,17 @@ static inline void dds_stream_to_LE_insitu (void * __restrict vbuf, uint32_t siz // Little-endian #define NAME_BYTE_ORDER_EXT LE -#include "dds_cdrstream_write.part.c" +#include "dds_cdrstream_write.part.h" #undef NAME_BYTE_ORDER_EXT // Big-endian #define NAME_BYTE_ORDER_EXT BE -#include "dds_cdrstream_write.part.c" +#include "dds_cdrstream_write.part.h" #undef NAME_BYTE_ORDER_EXT // Native-endian #define NAME_BYTE_ORDER_EXT -#include "dds_cdrstream_write.part.c" +#include "dds_cdrstream_write.part.h" #undef NAME_BYTE_ORDER_EXT #if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN @@ -3963,7 +3963,7 @@ static inline void dds_stream_swap_if_needed_insitu (void * __restrict vbuf, uin // Native endianness #define NAME_BYTE_ORDER_EXT -#include "dds_cdrstream_keys.part.c" +#include "dds_cdrstream_keys.part.h" #undef NAME_BYTE_ORDER_EXT #if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN @@ -3975,7 +3975,7 @@ static void dds_stream_swap_if_needed_insituBE (void * __restrict vbuf, uint32_t // Big-endian implementation #define NAME_BYTE_ORDER_EXT BE -#include "dds_cdrstream_keys.part.c" +#include "dds_cdrstream_keys.part.h" #undef NAME_BYTE_ORDER_EXT #else /* if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN */ diff --git a/src/core/cdr/src/dds_cdrstream_keys.part.c b/src/core/cdr/src/dds_cdrstream_keys.part.h similarity index 100% rename from src/core/cdr/src/dds_cdrstream_keys.part.c rename to src/core/cdr/src/dds_cdrstream_keys.part.h diff --git a/src/core/cdr/src/dds_cdrstream_write.part.c b/src/core/cdr/src/dds_cdrstream_write.part.h similarity index 100% rename from src/core/cdr/src/dds_cdrstream_write.part.c rename to src/core/cdr/src/dds_cdrstream_write.part.h From f1a2945e8d119e59487a4de63b8f5d320a87d270 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 7 Jun 2024 10:05:44 +0200 Subject: [PATCH 122/207] Fix trivial compilation issues on BE machines This eliminates some issues flagged by the compiler when compiling for a big-endian machine: * warnings in MD5 that would not ultimately cause problems; * warnings in hand-crafted CDR that would result in incorrect data used in test cases; * erors in security tests due to a typo in a byte-order selection constant. Signed-off-by: Erik Boasson Eliminate warnings on big-endian machines Signed-off-by: Erik Boasson Fix typo in endianness selection in big-endian machines Signed-off-by: Erik Boasson --- src/core/cdr/test/mem_ser.h | 16 ++++++++-------- src/ddsrt/src/md5.c | 5 ++++- .../src/decode_datawriter_submessage_utests.c | 2 +- .../src/decode_rtps_message_utests.c | 2 +- .../src/encode_datawriter_submessage_utests.c | 2 +- .../src/encode_rtps_message_utests.c | 2 +- .../src/preprocess_secure_submsg_utests.c | 2 +- 7 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/core/cdr/test/mem_ser.h b/src/core/cdr/test/mem_ser.h index c457a6bf83..316e722fe7 100644 --- a/src/core/cdr/test/mem_ser.h +++ b/src/core/cdr/test/mem_ser.h @@ -25,14 +25,14 @@ (unsigned char)( (uint32_t)(v) & 0xff) #define SER32BE(v) SER32(v) #define SER64(v) \ - (unsigned char)( (uint32_t)(v) >> 56), \ - (unsigned char)(((uint32_t)(v) >> 48) & 0xff), \ - (unsigned char)(((uint32_t)(v) >> 40) & 0xff), \ - (unsigned char)(((uint32_t)(v) >> 32) & 0xff), \ - (unsigned char)(((uint32_t)(v) >> 24) & 0xff), \ - (unsigned char)(((uint32_t)(v) >> 16) & 0xff), \ - (unsigned char)(((uint32_t)(v) >> 8) & 0xff), \ - (unsigned char)( (uint32_t)(v) & 0xff) + (unsigned char)( (uint64_t)(v) >> 56), \ + (unsigned char)(((uint64_t)(v) >> 48) & 0xff), \ + (unsigned char)(((uint64_t)(v) >> 40) & 0xff), \ + (unsigned char)(((uint64_t)(v) >> 32) & 0xff), \ + (unsigned char)(((uint64_t)(v) >> 24) & 0xff), \ + (unsigned char)(((uint64_t)(v) >> 16) & 0xff), \ + (unsigned char)(((uint64_t)(v) >> 8) & 0xff), \ + (unsigned char)( (uint64_t)(v) & 0xff) #define SER64BE(v) SER64(v) #else #define SER16(v) \ diff --git a/src/ddsrt/src/md5.c b/src/ddsrt/src/md5.c index eaf867ae54..16af2c49ba 100644 --- a/src/ddsrt/src/md5.c +++ b/src/ddsrt/src/md5.c @@ -202,7 +202,10 @@ md5_process(ddsrt_md5_state_t *pms, const ddsrt_md5_byte_t *data /*[64]*/) # define xbuf X /* (static only) */ # endif for (i = 0; i < 16; ++i, xp += 4) - xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + { + xbuf[i] = (ddsrt_md5_word_t)xp[0] + ((ddsrt_md5_word_t)xp[1] << 8) + + ((ddsrt_md5_word_t)xp[2] << 16) + ((ddsrt_md5_word_t)xp[3] << 24); + } } #endif } diff --git a/src/security/builtin_plugins/tests/decode_datawriter_submessage/src/decode_datawriter_submessage_utests.c b/src/security/builtin_plugins/tests/decode_datawriter_submessage/src/decode_datawriter_submessage_utests.c index 07cbc5e40d..f7177afb93 100644 --- a/src/security/builtin_plugins/tests/decode_datawriter_submessage/src/decode_datawriter_submessage_utests.c +++ b/src/security/builtin_plugins/tests/decode_datawriter_submessage/src/decode_datawriter_submessage_utests.c @@ -427,7 +427,7 @@ static unsigned char submsg_header_endianness_flag (enum ddsrt_byte_order_select #if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN return (unsigned char) ((bo == DDSRT_BOSEL_BE) ? 0 : DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS); #else - return (unsigned char) ((bo == DDSRT_BO_LE) ? DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS : 0); + return (unsigned char) ((bo == DDSRT_BOSEL_LE) ? DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS : 0); #endif } diff --git a/src/security/builtin_plugins/tests/decode_rtps_message/src/decode_rtps_message_utests.c b/src/security/builtin_plugins/tests/decode_rtps_message/src/decode_rtps_message_utests.c index c69621e6a9..5f4f39e54e 100644 --- a/src/security/builtin_plugins/tests/decode_rtps_message/src/decode_rtps_message_utests.c +++ b/src/security/builtin_plugins/tests/decode_rtps_message/src/decode_rtps_message_utests.c @@ -385,7 +385,7 @@ static unsigned char submsg_header_endianness_flag (enum ddsrt_byte_order_select #if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN return (unsigned char) ((bo == DDSRT_BOSEL_BE) ? 0 : DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS); #else - return (unsigned char) ((bo == DDSRT_BO_LE) ? DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS : 0); + return (unsigned char) ((bo == DDSRT_BOSEL_LE) ? DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS : 0); #endif } diff --git a/src/security/builtin_plugins/tests/encode_datawriter_submessage/src/encode_datawriter_submessage_utests.c b/src/security/builtin_plugins/tests/encode_datawriter_submessage/src/encode_datawriter_submessage_utests.c index 7c267d4ae4..23c2ef6dd1 100644 --- a/src/security/builtin_plugins/tests/encode_datawriter_submessage/src/encode_datawriter_submessage_utests.c +++ b/src/security/builtin_plugins/tests/encode_datawriter_submessage/src/encode_datawriter_submessage_utests.c @@ -649,7 +649,7 @@ static unsigned char submsg_header_endianness_flag (enum ddsrt_byte_order_select #if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN return (unsigned char) ((bo == DDSRT_BOSEL_BE) ? 0 : DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS); #else - return (unsigned char) ((bo == DDSRT_BO_LE) ? DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS : 0); + return (unsigned char) ((bo == DDSRT_BOSEL_LE) ? DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS : 0); #endif } diff --git a/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c b/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c index ce4430adcd..8ed704f76c 100644 --- a/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c +++ b/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c @@ -606,7 +606,7 @@ static unsigned char submsg_header_endianness_flag (enum ddsrt_byte_order_select #if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN return (unsigned char) ((bo == DDSRT_BOSEL_BE) ? 0 : DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS); #else - return (unsigned char) ((bo == DDSRT_BO_LE) ? DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS : 0); + return (unsigned char) ((bo == DDSRT_BOSEL_LE) ? DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS : 0); #endif } diff --git a/src/security/builtin_plugins/tests/preprocess_secure_submsg/src/preprocess_secure_submsg_utests.c b/src/security/builtin_plugins/tests/preprocess_secure_submsg/src/preprocess_secure_submsg_utests.c index 260dc46304..dba12b4beb 100644 --- a/src/security/builtin_plugins/tests/preprocess_secure_submsg/src/preprocess_secure_submsg_utests.c +++ b/src/security/builtin_plugins/tests/preprocess_secure_submsg/src/preprocess_secure_submsg_utests.c @@ -412,7 +412,7 @@ static unsigned char submsg_header_endianness_flag (enum ddsrt_byte_order_select #if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN return (unsigned char) ((bo == DDSRT_BOSEL_BE) ? 0 : DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS); #else - return (unsigned char) ((bo == DDSRT_BO_LE) ? DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS : 0); + return (unsigned char) ((bo == DDSRT_BOSEL_LE) ? DDSI_RTPS_SUBMESSAGE_FLAG_ENDIANNESS : 0); #endif } From 48ac8f4ee44725e9d0d7687fe087ae2f406e08ad Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 7 Jun 2024 10:08:35 +0200 Subject: [PATCH 123/207] Fix CDR stream compilation issues on BE machines Signed-off-by: Erik Boasson --- src/core/cdr/src/dds_cdrstream.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/core/cdr/src/dds_cdrstream.c b/src/core/cdr/src/dds_cdrstream.c index a7e460e4bd..d76ece544c 100644 --- a/src/core/cdr/src/dds_cdrstream.c +++ b/src/core/cdr/src/dds_cdrstream.c @@ -139,9 +139,11 @@ static const uint32_t *dds_stream_skip_default (char * __restrict data, const st static const uint32_t *dds_stream_extract_key_from_data1 (dds_istream_t * __restrict is, dds_ostream_t * __restrict os, const struct dds_cdrstream_allocator * __restrict allocator, const uint32_t * const __restrict op0, const uint32_t * __restrict ops, bool mutable_member, bool mutable_member_or_parent, uint32_t n_keys, uint32_t * __restrict keys_remaining); +#if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN static const uint32_t *dds_stream_extract_keyBE_from_data1 (dds_istream_t * __restrict is, dds_ostreamBE_t * __restrict os, const struct dds_cdrstream_allocator * __restrict allocator, const uint32_t * const __restrict op0, const uint32_t * __restrict ops, bool mutable_member, bool mutable_member_or_parent, uint32_t n_keys, uint32_t * __restrict keys_remaining); +#endif static const uint32_t *stream_normalize_data_impl (char * __restrict data, uint32_t * __restrict off, uint32_t size, bool bswap, uint32_t xcdr_version, const uint32_t * __restrict ops, bool is_mutable_member, enum cdr_data_kind cdr_kind) ddsrt_attribute_warn_unused_result ddsrt_nonnull_all; static const uint32_t *dds_stream_read_impl (dds_istream_t * __restrict is, char * __restrict data, const struct dds_cdrstream_allocator * __restrict allocator, const uint32_t * __restrict ops, bool is_mutable_member, enum cdr_data_kind cdr_kind, enum sample_data_state sample_state); static const uint32_t *stream_free_sample_adr (uint32_t insn, void * __restrict data, const struct dds_cdrstream_allocator * __restrict allocator, const uint32_t * __restrict ops); @@ -274,10 +276,12 @@ static uint32_t dds_cdr_alignto_clear_and_resize (dds_ostream_t * __restrict os, } } +#if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN static uint32_t dds_cdr_alignto_clear_and_resizeBE (dds_ostreamBE_t * __restrict os, const struct dds_cdrstream_allocator * __restrict allocator, align_t a, uint32_t extra) { return dds_cdr_alignto_clear_and_resize (&os->x, allocator, a, extra); } +#endif uint32_t dds_cdr_alignto4_clear_and_resize (dds_ostream_t * __restrict os, const struct dds_cdrstream_allocator * __restrict allocator, uint32_t xcdr_version) { @@ -1461,6 +1465,11 @@ bool dds_stream_write_sampleBE (dds_ostreamBE_t * __restrict os, const struct dd #else /* if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN */ +bool dds_stream_write_sample (dds_ostream_t * __restrict os, const struct dds_cdrstream_allocator * __restrict allocator, const void * __restrict data, const struct dds_cdrstream_desc * __restrict desc) +{ + return dds_stream_write_sampleBE ((dds_ostreamBE_t *) os, allocator, data, desc); +} + bool dds_stream_write_sampleLE (dds_ostreamLE_t * __restrict os, const struct dds_cdrstream_allocator * __restrict allocator, const void * __restrict data, const struct dds_cdrstream_desc * __restrict desc) { return dds_stream_writeLE (os, allocator, data, desc->ops.ops) != NULL; @@ -1471,7 +1480,7 @@ bool dds_stream_write_sampleBE (dds_ostreamBE_t * __restrict os, const struct dd size_t opt_size = os->x.m_xcdr_version == DDSI_RTPS_CDR_ENC_VERSION_1 ? desc->opt_size_xcdr1 : desc->opt_size_xcdr2; if (opt_size && desc->align && (((struct dds_ostream *)os)->m_index % desc->align) == 0) { - dds_os_put_bytes ((struct dds_ostream *)os, data, (uint32_t) opt_size); + dds_os_put_bytes ((struct dds_ostream *)os, allocator, data, (uint32_t) opt_size); return true; } else @@ -3604,7 +3613,6 @@ static void dds_stream_swap_copy (void * __restrict vdst, const void * __restric } } } -#endif static void dds_stream_extract_keyBE_from_key_prim_op (dds_istream_t * __restrict is, dds_ostreamBE_t * __restrict os, const struct dds_cdrstream_allocator * __restrict allocator, const uint32_t * __restrict ops, uint16_t key_offset_count, const uint32_t * key_offset_insn) { @@ -3682,6 +3690,7 @@ static void dds_stream_extract_keyBE_from_key_prim_op (dds_istream_t * __restric } } } +#endif static void dds_stream_extract_key_from_data_skip_subtype (dds_istream_t * __restrict is, uint32_t num, uint32_t insn, uint32_t subtype, const uint32_t * __restrict subops) { @@ -3980,9 +3989,19 @@ static void dds_stream_swap_if_needed_insituBE (void * __restrict vbuf, uint32_t #else /* if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN */ -void dds_stream_write_keyBE (dds_ostreamBE_t * __restrict os, const char * __restrict sample, const struct dds_cdrstream_allocator * __restrict allocator, const struct dds_cdrstream_desc * __restrict desc) +void dds_stream_write_keyBE (dds_ostreamBE_t * __restrict os, enum dds_cdr_key_serialization_kind ser_kind, const struct dds_cdrstream_allocator * __restrict allocator, const char * __restrict sample, const struct dds_cdrstream_desc * __restrict desc) +{ + dds_stream_write_key (&os->x, ser_kind, allocator, sample, desc); +} + +bool dds_stream_extract_keyBE_from_data (dds_istream_t * __restrict is, dds_ostreamBE_t * __restrict os, const struct dds_cdrstream_allocator * __restrict allocator, const struct dds_cdrstream_desc * __restrict desc) +{ + return dds_stream_extract_key_from_data (is, &os->x, allocator, desc); +} + +void dds_stream_extract_keyBE_from_key (dds_istream_t * __restrict is, dds_ostreamBE_t * __restrict os, enum dds_cdr_key_serialization_kind ser_kind, const struct dds_cdrstream_allocator * __restrict allocator, const struct dds_cdrstream_desc * __restrict desc) { - dds_stream_write_key (&os->x, allocator, sample, desc); + dds_stream_extract_key_from_key (is, &os->x, ser_kind, allocator, desc); } #endif /* if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN */ From c8659b2c02786c8c244a88b35f9a4e454f0ca439 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 10 Jun 2024 14:54:49 +0200 Subject: [PATCH 124/207] Fix bool/int confusion in struct ddsi_config The DDSI stack of Cyclone originates in a code base where C99 was not to be used, and there are still remnants of this to be found. One of them is that the functions for manipulating boolean settings in the configuration assume that these fields are declared as "int"s, rather than as "bool"s. One accidental use of boolean slipped through. It is harmless on little-endian machines thanks to some padding, but it did trigger a test failure with raw configs on a big-endian machine. Signed-off-by: Erik Boasson --- docs/manual/config/config_file_reference.rst | 2 +- docs/manual/options.md | 2 +- etc/cyclonedds.rnc | 2 +- etc/cyclonedds.xsd | 2 +- src/core/ddsi/defconfig.c | 2 +- src/core/ddsi/include/dds/ddsi/ddsi_config.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index a87911336c..393bb758d6 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -2704,7 +2704,7 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: ``none`` .. - generated from ddsi_config.h[007a7968df8cbc42a122109bd139ac85bab0f6c9] + generated from ddsi_config.h[bb5b5a6f7cc86cd0d96b56753213ecfaeaca430c] generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] generated from ddsi__cfgelems.h[194217161977869610495a7889bbc1e6bc976ce1] generated from ddsi_config.c[8c7ad90526d135063496f4a55e4e5992fa7bc72a] diff --git a/docs/manual/options.md b/docs/manual/options.md index e1d4778154..ad402b4399 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -1898,7 +1898,7 @@ While none prevents any message from being written to a DDSI2 log file. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest. The default value is: `none` - + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index bb887862b5..6e54b8da4d 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -1313,7 +1313,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
    duration_inf = xsd:token { pattern = "inf|0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)" } memsize = xsd:token { pattern = "0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B" } } -# generated from ddsi_config.h[007a7968df8cbc42a122109bd139ac85bab0f6c9] +# generated from ddsi_config.h[bb5b5a6f7cc86cd0d96b56753213ecfaeaca430c] # generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] # generated from ddsi__cfgelems.h[194217161977869610495a7889bbc1e6bc976ce1] # generated from ddsi_config.c[8c7ad90526d135063496f4a55e4e5992fa7bc72a] diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index 121b51cdd9..1465bcb498 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -1971,7 +1971,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - + diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index 655cc6a61c..c5c4beca4e 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -99,7 +99,7 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->ssl_min_version.minor = 3; #endif /* DDS_HAS_TCP_TLS */ } -/* generated from ddsi_config.h[007a7968df8cbc42a122109bd139ac85bab0f6c9] */ +/* generated from ddsi_config.h[bb5b5a6f7cc86cd0d96b56753213ecfaeaca430c] */ /* generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] */ /* generated from ddsi__cfgelems.h[194217161977869610495a7889bbc1e6bc976ce1] */ /* generated from ddsi_config.c[8c7ad90526d135063496f4a55e4e5992fa7bc72a] */ diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_config.h b/src/core/ddsi/include/dds/ddsi/ddsi_config.h index dad2180000..738f5331e8 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_config.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_config.h @@ -400,7 +400,7 @@ struct ddsi_config int retry_on_reject_besteffort; int generate_keyhash; uint32_t max_sample_size; - bool extended_packet_info; + int extended_packet_info; /* compability options */ enum ddsi_standards_conformance standards_conformance; From 77a2fd465f410759c85684d3145e719727c6a29f Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 10 Jun 2024 15:03:19 +0200 Subject: [PATCH 125/207] Fix IDLC 32/64-bit confusion for data repr Not a problem on little-endian machines, deadly on a big-endian machine. Signed-off-by: Erik Boasson --- src/idl/src/annotation.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/idl/src/annotation.c b/src/idl/src/annotation.c index f83004ab3d..3ee2b3d65a 100644 --- a/src/idl/src/annotation.c +++ b/src/idl/src/annotation.c @@ -828,7 +828,10 @@ annotate_datarepresentation( assert(annotation_appl->parameters); idl_literal_t *literal = annotation_appl->parameters->const_expr; assert(idl_type(literal) == IDL_BITMASK); - allowable_data_representations_t val = (allowable_data_representations_t)literal->value.uint32; //native type of datarepresentation is uint32_t + //native type of datarepresentation is uint32_t + //idlc internally represents all bitmask constants as 64-bits + assert (literal->value.uint64 <= UINT32_MAX); + allowable_data_representations_t val = (allowable_data_representations_t)literal->value.uint64; if (0 == val) { idl_error(pstate, idl_location(annotation_appl), From a964e66091655e87ba1d99c92404fc683da1825f Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 10 Jun 2024 15:04:25 +0200 Subject: [PATCH 126/207] Fix IDLC 8/32/64-bit confusion for array bounds Not a problem on little-endian machines, deadly on a big-endian machine. Signed-off-by: Erik Boasson --- src/idl/src/descriptor_type_meta.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/idl/src/descriptor_type_meta.c b/src/idl/src/descriptor_type_meta.c index a1f6b58d7d..9818d4e8dc 100644 --- a/src/idl/src/descriptor_type_meta.c +++ b/src/idl/src/descriptor_type_meta.c @@ -230,8 +230,8 @@ get_plain_typeid (const idl_pstate_t *pstate, struct descriptor_type_meta *dtm, if (idl_array_size (type_spec) <= UINT8_MAX) { ti->_d = DDS_XTypes_TI_PLAIN_ARRAY_SMALL; for (; literal; literal = idl_next (literal)) { - assert (literal->value.uint32 < UINT8_MAX); - uint8_t val = literal->value.uint8; + assert (literal->value.uint32 <= UINT8_MAX); + uint8_t val = (uint8_t) literal->value.uint32; if ((ret = add_to_seq_DDS_XTypes_SBound (&ti->_u.array_sdefn.array_bound_seq, &val)) < 0) return ret; } @@ -248,7 +248,6 @@ get_plain_typeid (const idl_pstate_t *pstate, struct descriptor_type_meta *dtm, ti->_u.array_ldefn.element_identifier = idl_calloc (1, sizeof (*ti->_u.array_ldefn.element_identifier)); ti->_u.array_ldefn.header.element_flags = get_array_element_flags (type_spec); for (; literal; literal = idl_next (literal)) { - assert (literal->value.uint64 < UINT32_MAX); uint32_t val = literal->value.uint32; if ((ret = add_to_seq_DDS_XTypes_LBound (&ti->_u.array_ldefn.array_bound_seq, &val)) < 0) return ret; From 2c515a5d858b712685ad396b8b04fe7092d485f4 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 10 Jun 2024 15:05:20 +0200 Subject: [PATCH 127/207] Fix type/descriptor mismatch in CDR tests Union discriminat in type declared as 32-bit, in descriptor as 8-bit. The union cases require alignment to 32-bit and so this works fine on a little-endian machine and only breaks on a big-endian one. Signed-off-by: Erik Boasson --- src/core/ddsc/tests/cdrstream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ddsc/tests/cdrstream.c b/src/core/ddsc/tests/cdrstream.c index 652821d6d3..0f5ee45136 100644 --- a/src/core/ddsc/tests/cdrstream.c +++ b/src/core/ddsc/tests/cdrstream.c @@ -634,7 +634,7 @@ static void sample_free_opt (void *s) /* @appendable */ typedef struct TestIdl_AppendableUnion0 { - int32_t _d; + int8_t _d; union { uint32_t field1; From e88924d0aafff6aca7455f0a8914ab177364b1f5 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 10 Jun 2024 15:06:49 +0200 Subject: [PATCH 128/207] CDR test needs to be consistent in endianness Signed-off-by: Erik Boasson --- src/core/ddsc/tests/cdrstream.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/ddsc/tests/cdrstream.c b/src/core/ddsc/tests/cdrstream.c index 0f5ee45136..a322c69732 100644 --- a/src/core/ddsc/tests/cdrstream.c +++ b/src/core/ddsc/tests/cdrstream.c @@ -2073,21 +2073,21 @@ CU_Test (ddsc_cdrstream, skip_default) dds_cdrstream_desc_from_topic_desc (&desc_sub, tests[i].desc_sub); assert (desc_sub.ops.ops); - dds_ostreamLE_t os = { .x.m_xcdr_version = DDSI_RTPS_CDR_ENC_VERSION_2 }; + dds_ostream_t os = { .m_xcdr_version = DDSI_RTPS_CDR_ENC_VERSION_2 }; uint8_t *sample_pub = ddsrt_malloc (desc_pub.size); memset (sample_pub, 0xef, desc_pub.size); // assumes no pointers (strings, sequences, @external, @optional) in pub type - bool ret = dds_stream_write_sampleLE (&os, &dds_cdrstream_default_allocator, sample_pub, &desc_pub); + bool ret = dds_stream_write_sample (&os, &dds_cdrstream_default_allocator, sample_pub, &desc_pub); CU_ASSERT_FATAL (ret); uint8_t *sample_sub = ddsrt_malloc (desc_sub.size); memset (sample_sub, 0xbe, desc_sub.size); tests[i].init_sub (sample_sub); - dds_istream_t is = { .m_buffer = os.x.m_buffer, .m_index = 0, .m_size = os.x.m_size, .m_xcdr_version = os.x.m_xcdr_version }; + dds_istream_t is = { .m_buffer = os.m_buffer, .m_index = 0, .m_size = os.m_size, .m_xcdr_version = os.m_xcdr_version }; dds_stream_read_sample (&is, sample_sub, &dds_cdrstream_default_allocator, &desc_sub); tests[i].check_sub (sample_sub); // clean-up - dds_ostream_fini (&os.x, &dds_cdrstream_default_allocator); + dds_ostream_fini (&os, &dds_cdrstream_default_allocator); ddsrt_free (sample_pub); dds_stream_free_sample (sample_sub, &dds_cdrstream_default_allocator, desc_sub.ops.ops); ddsrt_free (sample_sub); From f2f4894937bce5dd8a9a2ec9298d6ef5c55e631f Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 10 Jun 2024 15:07:26 +0200 Subject: [PATCH 129/207] Support key serialization test on big-endian hosts Signed-off-by: Erik Boasson --- src/core/ddsc/tests/serdata_keys.c | 64 ++++++++++++++++-------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/src/core/ddsc/tests/serdata_keys.c b/src/core/ddsc/tests/serdata_keys.c index d353deb499..0f17d53ebf 100644 --- a/src/core/ddsc/tests/serdata_keys.c +++ b/src/core/ddsc/tests/serdata_keys.c @@ -336,7 +336,11 @@ static void check_key_keyhash (struct dds_serdata_default *sd, CU_ASSERT_FATAL (cmp == 0); } -// FIXME: the CDR used in this test assumes running on a little-endian machine +#if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN +#define MAKE_ENCHDR(what) DDSI_RTPS_##what##_LE +#else +#define MAKE_ENCHDR(what) DDSI_RTPS_##what##_BE +#endif CU_Test(ddsc_serdata, key_serialization) { struct expected_key { @@ -356,7 +360,7 @@ CU_Test(ddsc_serdata, key_serialization) } tests[] = { { &SerdataKeyOrder_desc, init_SerdataKeyOrder, { { - DDSI_RTPS_CDR_LE, + MAKE_ENCHDR(CDR), (raw){ 1,2,0,0,0,0,0,0,SER64(3) }, 16, @@ -367,7 +371,7 @@ CU_Test(ddsc_serdata, key_serialization) 1,0,0,0,0,0,0,0,SER64BE(3) }, 16 }, { - DDSI_RTPS_CDR2_LE, + MAKE_ENCHDR(CDR2), (raw){ 1,2,0,0,SER64(3) }, 12, @@ -381,7 +385,7 @@ CU_Test(ddsc_serdata, key_serialization) }, { &SerdataKeyOrderId_desc, init_SerdataKeyOrderId, { { - DDSI_RTPS_CDR_LE, + MAKE_ENCHDR(CDR), (raw){ 1,2,0,0,0,0,0,0,SER64(3) }, 16, @@ -392,7 +396,7 @@ CU_Test(ddsc_serdata, key_serialization) 1,0,0,0,0,0,0,0,SER64BE(3) }, 16 }, { - DDSI_RTPS_CDR2_LE, + MAKE_ENCHDR(CDR2), (raw){ 1,2,0,0,SER64(3) }, 12, @@ -407,7 +411,7 @@ CU_Test(ddsc_serdata, key_serialization) }, { &SerdataKeyOrderHashId_desc, init_SerdataKeyOrderHashId, { { - DDSI_RTPS_CDR_LE, + MAKE_ENCHDR(CDR), (raw){ 1,2,0,0,0,0,0,0,SER64(3) }, 16, @@ -418,7 +422,7 @@ CU_Test(ddsc_serdata, key_serialization) 1,0,0,0,0,0,0,0,SER64BE(3) }, 16 }, { - DDSI_RTPS_CDR2_LE, + MAKE_ENCHDR(CDR2), (raw){ 1,2,0,0,SER64(3) }, 12, @@ -435,7 +439,7 @@ CU_Test(ddsc_serdata, key_serialization) { { 0 // not supported }, { - DDSI_RTPS_D_CDR2_LE, + MAKE_ENCHDR(D_CDR2), (raw){ SER_DHEADER(12),1,2,0,0, SER64(3) @@ -454,7 +458,7 @@ CU_Test(ddsc_serdata, key_serialization) { { 0 // not supported }, { - DDSI_RTPS_PL_CDR2_LE, + MAKE_ENCHDR(PL_CDR2), (raw){ SER_DHEADER(28), SER_EMHEADER(1,0,3),1,0,0,0, @@ -476,7 +480,7 @@ CU_Test(ddsc_serdata, key_serialization) { { 0 // not supported }, { - DDSI_RTPS_CDR2_LE, + MAKE_ENCHDR(CDR2), (raw){ 10,20,0,0, SER_DHEADER(28), @@ -501,7 +505,7 @@ CU_Test(ddsc_serdata, key_serialization) { { 0 // not supported }, { - DDSI_RTPS_D_CDR2_LE, + MAKE_ENCHDR(D_CDR2), (raw){ SER_DHEADER(36),10,20,0,0, SER_DHEADER(28), @@ -526,7 +530,7 @@ CU_Test(ddsc_serdata, key_serialization) { { 0 // not supported }, { - DDSI_RTPS_PL_CDR2_LE, + MAKE_ENCHDR(PL_CDR2), (raw){ SER_DHEADER(56), SER_EMHEADER(1,0,3),10,0,0,0, @@ -556,7 +560,7 @@ CU_Test(ddsc_serdata, key_serialization) { { 0 // not supported }, { - DDSI_RTPS_PL_CDR2_LE, + MAKE_ENCHDR(PL_CDR2), (raw){ SER_DHEADER(40), SER_EMHEADER(1,0,3),10,0,0,0, @@ -583,7 +587,7 @@ CU_Test(ddsc_serdata, key_serialization) { { 0 // not supported }, { - DDSI_RTPS_PL_CDR2_LE, + MAKE_ENCHDR(PL_CDR2), (raw){ SER_DHEADER(36), SER_EMHEADER(1,0,3),10,0,0,0, @@ -608,7 +612,7 @@ CU_Test(ddsc_serdata, key_serialization) }, { &SerdataKeyString_desc, init_SerdataKeyString, { { - DDSI_RTPS_CDR_LE, + MAKE_ENCHDR(CDR), (raw){ 1,0,0,0, SER32(5),'t','e','s','t','\0', @@ -625,7 +629,7 @@ CU_Test(ddsc_serdata, key_serialization) 0,0,0 // padding }, 13 }, { - DDSI_RTPS_CDR2_LE, + MAKE_ENCHDR(CDR2), (raw){ 1,0,0,0, SER32(5),'t','e','s','t','\0', @@ -645,7 +649,7 @@ CU_Test(ddsc_serdata, key_serialization) }, { &SerdataKeyStringBounded_desc, init_SerdataKeyStringBounded, { { - DDSI_RTPS_CDR_LE, + MAKE_ENCHDR(CDR), (raw){ 1,0,0,0, SER32(3),'t','s','\0', @@ -662,7 +666,7 @@ CU_Test(ddsc_serdata, key_serialization) 0 // padding }, 11 }, { - DDSI_RTPS_CDR2_LE, + MAKE_ENCHDR(CDR2), (raw){ 1,0,0,0, SER32(3),'t','s','\0', @@ -684,7 +688,7 @@ CU_Test(ddsc_serdata, key_serialization) { { 0 // not supported }, { - DDSI_RTPS_D_CDR2_LE, + MAKE_ENCHDR(D_CDR2), (raw){ SER_DHEADER(13), 1,0,0,0, @@ -707,7 +711,7 @@ CU_Test(ddsc_serdata, key_serialization) { { 0 // not supported }, { - DDSI_RTPS_D_CDR2_LE, + MAKE_ENCHDR(D_CDR2), (raw){ SER_DHEADER(12), 1,0,0,0, @@ -726,7 +730,7 @@ CU_Test(ddsc_serdata, key_serialization) }, { &SerdataKeyArr_desc, init_SerdataKeyArr, { { - DDSI_RTPS_CDR_LE, + MAKE_ENCHDR(CDR), (raw){ 0,1,2,3,4,5,6,7,8,9,10,11 }, 12, @@ -737,7 +741,7 @@ CU_Test(ddsc_serdata, key_serialization) 0,1,2,3,4,5,6,7,8,9,10,11 }, 12 }, { - DDSI_RTPS_CDR2_LE, + MAKE_ENCHDR(CDR2), (raw){ 0,1,2,3,4,5,6,7,8,9,10,11 }, 12, @@ -752,7 +756,7 @@ CU_Test(ddsc_serdata, key_serialization) // TODO: not supported // { &SerdataKeyArrStrBounded_desc, init_SerdataKeyArrStrBounded, // { { - // DDSI_RTPS_CDR_LE, + // MAKE_ENCHDR(CDR), // (raw){ // SER32(3),'t','s','\0', // SER32(3),'t','s','\0' @@ -766,7 +770,7 @@ CU_Test(ddsc_serdata, key_serialization) // SER32BE(3),'t','s','\0' // }, 14 // }, { - // DDSI_RTPS_CDR2_LE, + // MAKE_ENCHDR(CDR2), // (raw){ // SER32(3),'t','s','\0', // SER32(3),'t','s','\0' @@ -783,7 +787,7 @@ CU_Test(ddsc_serdata, key_serialization) // } { &SerdataKeyNestedFinalImplicit_desc, init_SerdataKeyNestedFinalImplicit, { { - DDSI_RTPS_CDR_LE, + MAKE_ENCHDR(CDR), (raw){ // d 1,2, @@ -809,7 +813,7 @@ CU_Test(ddsc_serdata, key_serialization) SER32BE(20) }, 20 }, { - DDSI_RTPS_CDR2_LE, + MAKE_ENCHDR(CDR2), (raw){ // d 1,2, @@ -839,7 +843,7 @@ CU_Test(ddsc_serdata, key_serialization) }, { &SerdataKeyNestedFinalImplicit2_desc, init_SerdataKeyNestedFinalImplicit2, { { - DDSI_RTPS_CDR_LE, + MAKE_ENCHDR(CDR), (raw){ // a 1,2,3,4, @@ -859,7 +863,7 @@ CU_Test(ddsc_serdata, key_serialization) 5,6 }, 4 }, { - DDSI_RTPS_CDR2_LE, + MAKE_ENCHDR(CDR2), (raw){ // a 1,2,3,4, @@ -884,7 +888,7 @@ CU_Test(ddsc_serdata, key_serialization) { { 0 // not supported }, { - DDSI_RTPS_D_CDR2_LE, + MAKE_ENCHDR(D_CDR2), (raw){ SER_DHEADER(84), // d @@ -932,7 +936,7 @@ CU_Test(ddsc_serdata, key_serialization) { { 0 // not supported }, { - DDSI_RTPS_PL_CDR2_LE, + MAKE_ENCHDR(PL_CDR2), (raw){ SER_DHEADER(70), // bx, by, bz From 2b8b86ec4e741e1e3e95b7c451e8dd56a0a316b4 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 10 Jun 2024 15:08:03 +0200 Subject: [PATCH 130/207] Fix reading of min/max annotation value in test Signed-off-by: Erik Boasson --- src/idl/tests/annotation.c | 61 +++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/src/idl/tests/annotation.c b/src/idl/tests/annotation.c index 469805e2b5..362950bf48 100644 --- a/src/idl/tests/annotation.c +++ b/src/idl/tests/annotation.c @@ -1236,28 +1236,49 @@ static void validate_limit(const idl_literal_t *lit, double to_test, double gran { assert(lit); double fval = 0; - idl_type_t type = idl_type(lit); - if (type & IDL_INTEGER_TYPE) { - if (type & IDL_UNSIGNED) - fval = (double)lit->value.uint64; - else + switch (idl_type(lit)) { + case IDL_INT8: + fval = (double)lit->value.int8; + break; + case IDL_INT16: + case IDL_SHORT: + fval = (double)lit->value.int16; + break; + case IDL_INT32: + case IDL_LONG: + fval = (double)lit->value.int32; + break; + case IDL_INT64: + case IDL_LLONG: fval = (double)lit->value.int64; - } else { - switch (type) { - case IDL_FLOAT: - fval = (double)lit->value.flt; - break; - case IDL_DOUBLE: - fval = (double)lit->value.dbl; - break; - case IDL_LDOUBLE: - fval = (double)lit->value.ldbl; - break; - default: - CU_ASSERT(false); - } + break; + case IDL_UINT8: + fval = (double)lit->value.uint8; + break; + case IDL_UINT16: + case IDL_USHORT: + fval = (double)lit->value.uint16; + break; + case IDL_UINT32: + case IDL_ULONG: + fval = (double)lit->value.uint32; + break; + case IDL_UINT64: + case IDL_ULLONG: + fval = (double)lit->value.uint64; + break; + case IDL_FLOAT: + fval = (double)lit->value.flt; + break; + case IDL_DOUBLE: + fval = (double)lit->value.dbl; + break; + case IDL_LDOUBLE: + fval = (double)lit->value.ldbl; + break; + default: + CU_ASSERT(false); } - CU_ASSERT_DOUBLE_EQUAL(fval, to_test, granularity); } From 2951b1419e0a81bc6b2d0c4287776c6fdcd2a010 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 10 Jun 2024 17:15:12 +0200 Subject: [PATCH 131/207] Remove dead compile-time conditional Signed-off-by: Erik Boasson --- src/core/cdr/src/dds_cdrstream.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/core/cdr/src/dds_cdrstream.c b/src/core/cdr/src/dds_cdrstream.c index d76ece544c..c875e7b335 100644 --- a/src/core/cdr/src/dds_cdrstream.c +++ b/src/core/cdr/src/dds_cdrstream.c @@ -3665,11 +3665,7 @@ static void dds_stream_extract_keyBE_from_key_prim_op (dds_istream_t * __restric dds_cdr_alignto_clear_and_resizeBE (os, allocator, cdr_align, num * elem_size); void const * const src = is->m_buffer + is->m_index; void * const dst = os->x.m_buffer + os->x.m_index; -#if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN dds_stream_swap_copy (dst, src, elem_size, num); -#else - memcpy (dst, src, num * elem_size); -#endif os->x.m_index += num * elem_size; is->m_index += num * elem_size; From 1deaa93b2019e6e23cb34d73594fc25327d6966c Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 10 Jun 2024 20:08:56 +0200 Subject: [PATCH 132/207] Fix ENABLE_IPV6/ENABLE_SOURCE_SPECIFIC_MULTICAST This fixes these two CMake options in the sense that: * It now does AUTO/ON/OFF, with ON requiring the platform to support it, OFF not caring in the slightest and AUTO enabling it only if the platform supports it; * It now does both entirely in the ddsrt CMakeLists.txt and puts the result in ddsrt/config.h; * There is no more a DDS_HAS_SSM flag in dds/features.h; * There are no more defines of DDSRT_HAVE_SSM in ddsrt/sockets/{posix,windows}.h (that were never used in the past); * All code uses the same definitions. The CMake bits seem to work fine on the CI platforms. Signed-off-by: Erik Boasson --- docs/manual/config/config_file_reference.rst | 4 +- docs/manual/options.md | 4 +- etc/cyclonedds.rnc | 4 +- etc/cyclonedds.xsd | 4 +- src/CMakeLists.txt | 10 ++-- src/core/ddsc/tests/xtypes_common.c | 2 +- src/core/ddsi/defconfig.c | 4 +- src/core/ddsi/include/dds/ddsi/ddsi_config.h | 4 +- .../ddsi/include/dds/ddsi/ddsi_endpoint.h | 4 +- .../include/dds/ddsi/ddsi_feature_check.h | 4 +- src/core/ddsi/include/dds/ddsi/ddsi_guid.h | 1 + src/core/ddsi/include/dds/ddsi/ddsi_plist.h | 6 +-- .../include/dds/ddsi/ddsi_proxy_endpoint.h | 6 +-- src/core/ddsi/src/ddsi__addrset.h | 4 +- src/core/ddsi/src/ddsi__endpoint_match.h | 2 +- src/core/ddsi/src/ddsi__plist.h | 2 +- src/core/ddsi/src/ddsi__protocol.h | 2 +- src/core/ddsi/src/ddsi_addrset.c | 4 +- src/core/ddsi/src/ddsi_config.c | 4 +- src/core/ddsi/src/ddsi_discovery_addrset.c | 2 +- src/core/ddsi/src/ddsi_discovery_endpoint.c | 10 ++-- src/core/ddsi/src/ddsi_endpoint.c | 14 ++--- src/core/ddsi/src/ddsi_endpoint_match.c | 6 +-- src/core/ddsi/src/ddsi_init.c | 6 +-- src/core/ddsi/src/ddsi_mcgroup.c | 2 +- src/core/ddsi/src/ddsi_nwinterfaces.c | 2 +- src/core/ddsi/src/ddsi_nwpart.c | 10 ++-- src/core/ddsi/src/ddsi_plist.c | 4 +- src/core/ddsi/src/ddsi_proxy_endpoint.c | 10 ++-- src/core/ddsi/src/ddsi_proxy_participant.c | 2 +- src/core/ddsi/src/ddsi_udp.c | 10 ++-- src/core/ddsi/src/ddsi_wraddrset.c | 6 +-- src/core/ddsi/tests/wraddrset.c | 2 +- src/core/xtests/symbol_export/symbol_export.c | 2 +- src/ddsrt/CMakeLists.txt | 51 +++++++++++++++++-- src/ddsrt/include/dds/config.h.in | 1 + src/ddsrt/include/dds/ddsrt/sockets/posix.h | 8 ++- src/ddsrt/include/dds/ddsrt/sockets/windows.h | 8 --- src/ddsrt/include/dds/features.h.in | 3 -- 39 files changed, 133 insertions(+), 101 deletions(-) diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index 393bb758d6..ffe85c57b5 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -2704,10 +2704,10 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: ``none`` .. - generated from ddsi_config.h[bb5b5a6f7cc86cd0d96b56753213ecfaeaca430c] + generated from ddsi_config.h[83ad19f1a665710b0c82b3ac6b861e6c8e83913f] generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] generated from ddsi__cfgelems.h[194217161977869610495a7889bbc1e6bc976ce1] - generated from ddsi_config.c[8c7ad90526d135063496f4a55e4e5992fa7bc72a] + generated from ddsi_config.c[a439a20e32fe327db26f2f10028d0056e46c1a0b] generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] diff --git a/docs/manual/options.md b/docs/manual/options.md index ad402b4399..217bb09790 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -1898,10 +1898,10 @@ While none prevents any message from being written to a DDSI2 log file. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest. The default value is: `none` - + - + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index 6e54b8da4d..f1d4c36265 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -1313,10 +1313,10 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
    duration_inf = xsd:token { pattern = "inf|0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)" } memsize = xsd:token { pattern = "0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B" } } -# generated from ddsi_config.h[bb5b5a6f7cc86cd0d96b56753213ecfaeaca430c] +# generated from ddsi_config.h[83ad19f1a665710b0c82b3ac6b861e6c8e83913f] # generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] # generated from ddsi__cfgelems.h[194217161977869610495a7889bbc1e6bc976ce1] -# generated from ddsi_config.c[8c7ad90526d135063496f4a55e4e5992fa7bc72a] +# generated from ddsi_config.c[a439a20e32fe327db26f2f10028d0056e46c1a0b] # generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] # generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] # generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index 1465bcb498..c314d2fdb2 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -1971,10 +1971,10 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - + - + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9240255504..00b0a19206 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,8 +27,10 @@ option(ENABLE_LIFESPAN "Enable Lifespan QoS support" ON) option(ENABLE_DEADLINE_MISSED "Enable Deadline Missed QoS support" ON) option(SKIP_DEADLINE_UPDATE "Skip deadline update test" OFF) option(ENABLE_NETWORK_PARTITIONS "Enable network partition support" ON) -option(ENABLE_SOURCE_SPECIFIC_MULTICAST "Enable support for source-specific multicast" ON) -option(ENABLE_IPV6 "Enable ipv6 support" ON) +set(ENABLE_SOURCE_SPECIFIC_MULTICAST "AUTO" CACHE STRING "Enable support for source-specific multicast") +set_property(CACHE ENABLE_SOURCE_SPECIFIC_MULTICAST PROPERTY STRINGS ON OFF AUTO) +set(ENABLE_IPV6 "AUTO" CACHE STRING "Enable ipv6 support") +set_property(CACHE ENABLE_IPV6 PROPERTY STRINGS ON OFF AUTO) option(ENABLE_TYPELIB "Enable Type Library support" ON) option(ENABLE_TYPE_DISCOVERY "Enable Type Discovery support" ON) option(ENABLE_TOPIC_DISCOVERY "Enable Topic Discovery support" ON) @@ -44,10 +46,6 @@ if(ENABLE_TOPIC_DISCOVERY) endif() endif() -if(ENABLE_SOURCE_SPECIFIC_MULTICAST) - set(ENABLE_SSM ON) -endif() - # OpenSSL is huge, raising the RSS by 1MB or so, and moreover find_package(OpenSSL) causes # trouble on some older CMake versions that otherwise work fine, so provide an option to avoid # all OpenSSL related things. diff --git a/src/core/ddsc/tests/xtypes_common.c b/src/core/ddsc/tests/xtypes_common.c index 7644939055..9a9eba52e1 100644 --- a/src/core/ddsc/tests/xtypes_common.c +++ b/src/core/ddsc/tests/xtypes_common.c @@ -77,7 +77,7 @@ void test_proxy_rd_create (struct ddsi_domaingv *gv, const char *topic_name, DDS ddsi_xqos_mergein_missing (&plist->qos, &ddsi_default_qos_reader, ~(uint64_t)0); struct ddsi_proxy_reader *proxy_reader; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM rc = ddsi_new_proxy_reader (&proxy_reader, gv, pp_guid, rd_guid, as, plist, ddsrt_time_wallclock (), 1, 0); #else rc = ddsi_new_proxy_reader (&proxy_reader, gv, pp_guid, rd_guid, as, plist, ddsrt_time_wallclock (), 1); diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index c5c4beca4e..b84a164347 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -99,10 +99,10 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->ssl_min_version.minor = 3; #endif /* DDS_HAS_TCP_TLS */ } -/* generated from ddsi_config.h[bb5b5a6f7cc86cd0d96b56753213ecfaeaca430c] */ +/* generated from ddsi_config.h[83ad19f1a665710b0c82b3ac6b861e6c8e83913f] */ /* generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] */ /* generated from ddsi__cfgelems.h[194217161977869610495a7889bbc1e6bc976ce1] */ -/* generated from ddsi_config.c[8c7ad90526d135063496f4a55e4e5992fa7bc72a] */ +/* generated from ddsi_config.c[a439a20e32fe327db26f2f10028d0056e46c1a0b] */ /* generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] */ /* generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] */ /* generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] */ diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_config.h b/src/core/ddsi/include/dds/ddsi/ddsi_config.h index 738f5331e8..0abc6fe808 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_config.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_config.h @@ -87,7 +87,7 @@ struct ddsi_config_networkpartition_listelem { char *interface_names; struct ddsi_networkpartition_address *uc_addresses; struct ddsi_networkpartition_address *asm_addresses; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM struct ddsi_networkpartition_address *ssm_addresses; #endif }; @@ -143,7 +143,7 @@ struct ddsi_config_prune_deleted_ppant { #define DDSI_AMC_FALSE 0u #define DDSI_AMC_SPDP 1u #define DDSI_AMC_ASM 2u -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM #define DDSI_AMC_SSM 4u #define DDSI_AMC_TRUE (DDSI_AMC_SPDP | DDSI_AMC_ASM | DDSI_AMC_SSM) #else diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_endpoint.h b/src/core/ddsi/include/dds/ddsi/ddsi_endpoint.h index b37325c2c8..e51bf5c756 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_endpoint.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_endpoint.h @@ -92,7 +92,7 @@ struct ddsi_writer unsigned test_suppress_heartbeat : 1; /* iff 1, the writer suppresses all periodic heartbeats */ unsigned test_suppress_flush_on_sync_heartbeat : 1; /* iff 1, the writer never flushes because of a piggy-backed heartbeat */ unsigned test_drop_outgoing_data : 1; /* iff 1, the writer drops outgoing data, forcing the readers to request a retransmit */ -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM unsigned supports_ssm: 1; struct ddsi_addrset *ssm_as; #endif @@ -148,7 +148,7 @@ struct ddsi_reader unsigned reliable: 1; /* 1 iff reader is reliable */ unsigned handle_as_transient_local: 1; /* 1 iff reader wants historical data from proxy writers */ unsigned request_keyhash: 1; /* really controlled by the sertype */ -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM unsigned favours_ssm: 1; /* iff 1, this reader favours SSM */ #endif ddsi_count_t init_acknack_count; /* initial value for "count" (i.e. ACK seq num) for newly matched proxy writers */ diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_feature_check.h b/src/core/ddsi/include/dds/ddsi/ddsi_feature_check.h index 5f783df18c..1e7bf25380 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_feature_check.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_feature_check.h @@ -23,7 +23,7 @@ */ #include "dds/features.h" -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM #ifndef DDS_HAS_NETWORK_PARTITIONS #error "SSM requires NETWORK_PARTITIONS" #endif @@ -32,6 +32,6 @@ #ifndef DDSRT_HAVE_SSM #error "DDSRT_HAVE_SSM should be defined" #elif ! DDSRT_HAVE_SSM - #undef DDS_HAS_SSM + #undef DDSRT_HAVE_SSM #endif #endif diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_guid.h b/src/core/ddsi/include/dds/ddsi/ddsi_guid.h index b5316de2fe..08790e5b65 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_guid.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_guid.h @@ -12,6 +12,7 @@ #define DDSI_GUID_H #include +#include "dds/export.h" #if defined (__cplusplus) extern "C" { diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_plist.h b/src/core/ddsi/include/dds/ddsi/ddsi_plist.h index 0117def363..cee85ff540 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_plist.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_plist.h @@ -84,13 +84,13 @@ typedef struct ddsi_security_info ddsi_security_info_t; #endif /* DDS_HAS_SECURITY */ -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM typedef struct ddsi_reader_favours_ssm { uint32_t state; /* default is false */ } ddsi_reader_favours_ssm_t; -#endif /* DDS_HAS_SSM */ +#endif /* DDSRT_HAVE_SSM */ typedef struct ddsi_adlink_participant_version_info @@ -141,7 +141,7 @@ typedef struct ddsi_plist { ddsi_token_t identity_status_token; ddsi_datatags_t data_tags; #endif -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM ddsi_reader_favours_ssm_t reader_favours_ssm; #endif uint32_t domain_id; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_proxy_endpoint.h b/src/core/ddsi/include/dds/ddsi/ddsi_proxy_endpoint.h index efef7ab994..b16b37ac8a 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_proxy_endpoint.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_proxy_endpoint.h @@ -69,7 +69,7 @@ struct ddsi_proxy_writer { unsigned alive: 1; /* iff 1, the proxy writer is alive (lease for this proxy writer is not expired); field may be modified only when holding both pwr->e.lock and pwr->c.proxypp->e.lock */ unsigned filtered: 1; /* iff 1, builtin proxy writer uses content filter, which affects heartbeats and gaps. */ unsigned redundant_networking: 1; /* 1 iff requests receiving data on all advertised interfaces */ -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM unsigned supports_ssm: 1; /* iff 1, this proxy writer supports SSM */ #endif unsigned local_psmx: 1; /* whether this is a proxy writer for a local PSMX */ @@ -92,7 +92,7 @@ struct ddsi_proxy_reader { unsigned is_fict_trans_reader: 1; /* only true when it is certain that is a fictitious transient data reader (affects built-in topic generation) */ unsigned requests_keyhash: 1; /* 1 iff this reader would like to receive keyhashes */ unsigned redundant_networking: 1; /* 1 iff requests receiving data on all advertised interfaces */ -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM unsigned favours_ssm: 1; /* iff 1, this proxy reader favours SSM when available */ #endif unsigned local_psmx: 1; /*whether this is a proxy reader for a local PSMX*/ @@ -138,7 +138,7 @@ DDS_EXPORT int ddsi_new_proxy_writer (struct ddsi_proxy_writer **proxy_writer, s */ DDS_EXPORT int ddsi_new_proxy_reader (struct ddsi_proxy_reader **proxy_reader, struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct ddsi_addrset *as, const struct ddsi_plist *plist, ddsrt_wctime_t timestamp, ddsi_seqno_t seq -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM , int favours_ssm #endif ); diff --git a/src/core/ddsi/src/ddsi__addrset.h b/src/core/ddsi/src/ddsi__addrset.h index 426dd3db0b..1405777645 100644 --- a/src/core/ddsi/src/ddsi__addrset.h +++ b/src/core/ddsi/src/ddsi__addrset.h @@ -146,7 +146,7 @@ void ddsi_set_unspec_xlocator (ddsi_xlocator_t *loc) ddsrt_nonnull_all; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM /** @component locators */ bool ddsi_addrset_contains_ssm (const struct ddsi_domaingv *gv, const struct ddsi_addrset *as) @@ -168,7 +168,7 @@ void ddsi_copy_addrset_into_addrset_no_ssm_mc (const struct ddsi_domaingv *gv, s void ddsi_copy_addrset_into_addrset_no_ssm (const struct ddsi_domaingv *gv, struct ddsi_addrset *as, const struct ddsi_addrset *asadd) ddsrt_nonnull_all; -#endif /* DDS_HAS_SSM */ +#endif /* DDSRT_HAVE_SSM */ #if defined (__cplusplus) } diff --git a/src/core/ddsi/src/ddsi__endpoint_match.h b/src/core/ddsi/src/ddsi__endpoint_match.h index de647c2152..d7991113a9 100644 --- a/src/core/ddsi/src/ddsi__endpoint_match.h +++ b/src/core/ddsi/src/ddsi__endpoint_match.h @@ -64,7 +64,7 @@ struct ddsi_rd_pwr_match { unsigned pwr_alive: 1; /* tracks pwr's alive state */ unsigned via_psmx: 1; /* true iff there is a common psmx locator */ uint32_t pwr_alive_vclock; /* used to ensure progress */ -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM ddsi_xlocator_t ssm_mc_loc; ddsi_xlocator_t ssm_src_loc; #endif diff --git a/src/core/ddsi/src/ddsi__plist.h b/src/core/ddsi/src/ddsi__plist.h index f6c2310e4c..9b21081799 100644 --- a/src/core/ddsi/src/ddsi__plist.h +++ b/src/core/ddsi/src/ddsi__plist.h @@ -54,7 +54,7 @@ struct ddsi_xmsg; #define PP_ADLINK_PARTICIPANT_VERSION_INFO ((uint64_t)1 << 26) #define PP_ADLINK_TYPE_DESCRIPTION ((uint64_t)1 << 27) // ((uint64_t)1 << 28) is available -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM #define PP_READER_FAVOURS_SSM ((uint64_t)1 << 29) #endif #define PP_DOMAIN_ID ((uint64_t)1 << 30) diff --git a/src/core/ddsi/src/ddsi__protocol.h b/src/core/ddsi/src/ddsi__protocol.h index 82f02feb45..b3c0b5c9ca 100644 --- a/src/core/ddsi/src/ddsi__protocol.h +++ b/src/core/ddsi/src/ddsi__protocol.h @@ -309,7 +309,7 @@ typedef union ddsi_rtps_submessage { #define DDSI_PID_PARTICIPANT_SECURITY_INFO 0x1005u #define DDSI_PID_IDENTITY_STATUS_TOKEN 0x1006u -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM /* To indicate whether a reader favours the use of SSM. Iff the reader favours SSM, it will use SSM if available. */ #define DDSI_PID_READER_FAVOURS_SSM 0x72u diff --git a/src/core/ddsi/src/ddsi_addrset.c b/src/core/ddsi/src/ddsi_addrset.c index c68d678794..a884cb23ae 100644 --- a/src/core/ddsi/src/ddsi_addrset.c +++ b/src/core/ddsi/src/ddsi_addrset.c @@ -135,7 +135,7 @@ bool ddsi_is_unspec_xlocator (const ddsi_xlocator_t *loc) return ddsi_is_unspec_locator (&loc->c); } -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM bool ddsi_addrset_contains_ssm (const struct ddsi_domaingv *gv, const struct ddsi_addrset *as) { struct ddsi_addrset_node *n; @@ -301,7 +301,7 @@ void ddsi_copy_addrset_into_addrset (const struct ddsi_domaingv *gv, struct ddsi ddsi_copy_addrset_into_addrset_mc (gv, as, asadd); } -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM void ddsi_copy_addrset_into_addrset_no_ssm_mc (const struct ddsi_domaingv *gv, struct ddsi_addrset *as, const struct ddsi_addrset *asadd) { struct ddsi_addrset_node *n; diff --git a/src/core/ddsi/src/ddsi_config.c b/src/core/ddsi/src/ddsi_config.c index 4c72227619..4db60cf602 100644 --- a/src/core/ddsi/src/ddsi_config.c +++ b/src/core/ddsi/src/ddsi_config.c @@ -696,7 +696,7 @@ static int if_network_partition (struct ddsi_cfgst *cfgst, void *parent, struct new->interface_names = NULL; new->uc_addresses = NULL; new->asm_addresses = NULL; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM new->ssm_addresses = NULL; #endif new->name = NULL; @@ -1279,7 +1279,7 @@ static void ff_networkAddresses (struct ddsi_cfgst *cfgst, void *parent, struct ddsrt_free (*elem); } -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM static const char *allow_multicast_names[] = { "false", "spdp", "asm", "ssm", "true", NULL }; static const uint32_t allow_multicast_codes[] = { DDSI_AMC_FALSE, DDSI_AMC_SPDP, DDSI_AMC_ASM, DDSI_AMC_SSM, DDSI_AMC_TRUE }; #else diff --git a/src/core/ddsi/src/ddsi_discovery_addrset.c b/src/core/ddsi/src/ddsi_discovery_addrset.c index da43d45b17..3459d493d4 100644 --- a/src/core/ddsi/src/ddsi_discovery_addrset.c +++ b/src/core/ddsi/src/ddsi_discovery_addrset.c @@ -31,7 +31,7 @@ void ddsi_interface_set_init (ddsi_interface_set_t *intfs) static uint32_t allow_multicast_mask_from_locator (const struct ddsi_domaingv *gv, const ddsi_locator_t *loc) { uint32_t mask = 0; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM if (ddsi_is_ssm_mcaddr (gv, loc)) mask |= DDSI_AMC_SSM; else if (ddsi_is_mcaddr (gv, loc)) diff --git a/src/core/ddsi/src/ddsi_discovery_endpoint.c b/src/core/ddsi/src/ddsi_discovery_endpoint.c index fa842e2ea8..8c47b959f6 100644 --- a/src/core/ddsi/src/ddsi_discovery_endpoint.c +++ b/src/core/ddsi/src/ddsi_discovery_endpoint.c @@ -184,7 +184,7 @@ static int sedp_write_endpoint_impl } } -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM /* A bit of a hack -- the easy alternative would be to make it yet another parameter. We only set "reader favours SSM" if we really do: no point in telling the world that everything is at @@ -271,7 +271,7 @@ int ddsi_sedp_write_writer (struct ddsi_writer *wr) if (sedp_wr == NULL) return 0; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM struct ddsi_addrset *as = wr->ssm_as; #else struct ddsi_addrset *as = NULL; @@ -451,7 +451,7 @@ void ddsi_handle_sedp_alive_endpoint (const struct ddsi_receiver_state *rst, dds dds_qos_t *xqos; int reliable; struct ddsi_addrset *as; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM int ssm; #endif @@ -538,7 +538,7 @@ void ddsi_handle_sedp_alive_endpoint (const struct ddsi_receiver_state *rst, dds E (": no (unicast) address)", err); } -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM ssm = 0; if (sedp_kind == SEDP_KIND_WRITER) ssm = ddsi_addrset_contains_ssm (gv, as); @@ -575,7 +575,7 @@ void ddsi_handle_sedp_alive_endpoint (const struct ddsi_receiver_state *rst, dds else { struct ddsi_proxy_reader *proxy_reader; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM ddsi_new_proxy_reader (&proxy_reader, gv, &ppguid, &datap->endpoint_guid, as, datap, timestamp, seq, ssm); #else ddsi_new_proxy_reader (&proxy_reader, gv, &ppguid, &datap->endpoint_guid, as, datap, timestamp, seq); diff --git a/src/core/ddsi/src/ddsi_endpoint.c b/src/core/ddsi/src/ddsi_endpoint.c index 2b66387b47..9fc0ed072f 100644 --- a/src/core/ddsi/src/ddsi_endpoint.c +++ b/src/core/ddsi/src/ddsi_endpoint.c @@ -219,7 +219,7 @@ void ddsi_rebuild_writer_addrset (struct ddsi_writer *wr) ELOGDISC (wr, " (burst size %"PRIu32" rexmit %"PRIu32")\n", wr->init_burst_size_limit, wr->rexmit_burst_size_limit); } -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM static bool nwpart_includes_ssm_enabled_interfaces (const struct ddsi_domaingv *gv, const struct ddsi_config_networkpartition_listelem *np) ddsrt_nonnull ((1)); @@ -869,7 +869,7 @@ static void ddsi_new_writer_guid_common_init (struct ddsi_writer *wr, const char wr->network_partition = ddsi_get_nwpart_from_mapping (&gv->logconfig, &gv->config, wr->xqos, wr->xqos->topic_name); #endif /* DDS_HAS_NETWORK_PARTITIONS */ -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM /* Writer supports SSM if it is mapped to a network partition for which the address set includes an SSM address. If it supports SSM, it arbitrarily selects one SSM address from the address set @@ -1144,7 +1144,7 @@ static void gc_delete_writer (struct ddsi_gcreq *gcreq) #ifdef DDS_HAS_SECURITY ddsi_omg_security_deregister_writer (wr); #endif -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM if (wr->ssm_as) ddsi_unref_addrset (wr->ssm_as); #endif @@ -1431,7 +1431,7 @@ static void reader_init_network_partition (struct ddsi_reader *rd) { rd->uc_as = np->uc_addresses; rd->mc_as = np->asm_addresses; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM if (np->ssm_addresses != NULL && nwpart_includes_ssm_enabled_interfaces (gv, np)) rd->favours_ssm = 1; #endif @@ -1445,7 +1445,7 @@ static void reader_init_network_partition (struct ddsi_reader *rd) for (const struct ddsi_networkpartition_address *a = rd->mc_as; a != NULL; a = a->next) join_mcast_helper (gv, gv->data_conn_mc, &a->loc); } -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM else { /* Note: SSM requires NETWORK_PARTITIONS; if network partitions @@ -1456,7 +1456,7 @@ static void reader_init_network_partition (struct ddsi_reader *rd) } #endif } -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM if (rd->favours_ssm) ELOGDISC (rd, "READER "PGUIDFMT" ssm=%d\n", PGUID (rd->e.guid), rd->favours_ssm); #endif @@ -1521,7 +1521,7 @@ dds_return_t ddsi_new_reader (struct ddsi_reader **rd_out, const struct ddsi_gui rd->request_keyhash = rd->type->request_keyhash; rd->init_acknack_count = 1; rd->num_writers = 0; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM rd->favours_ssm = 0; #endif #ifdef DDS_HAS_SECURITY diff --git a/src/core/ddsi/src/ddsi_endpoint_match.c b/src/core/ddsi/src/ddsi_endpoint_match.c index bba60f4c22..7aeaa1645f 100644 --- a/src/core/ddsi/src/ddsi_endpoint_match.c +++ b/src/core/ddsi/src/ddsi_endpoint_match.c @@ -627,7 +627,7 @@ void ddsi_free_rd_pwr_match (struct ddsi_domaingv *gv, const ddsi_guid_t *rd_gui #else (void) rd_guid; #endif -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM if (!ddsi_is_unspec_xlocator (&m->ssm_mc_loc)) { assert (ddsi_is_mcaddr (gv, &m->ssm_mc_loc.c)); @@ -636,7 +636,7 @@ void ddsi_free_rd_pwr_match (struct ddsi_domaingv *gv, const ddsi_guid_t *rd_gui GVWARNING ("failed to leave network partition ssm group\n"); } #endif -#if !(defined DDS_HAS_SECURITY || defined DDS_HAS_SSM) +#if !(defined DDS_HAS_SECURITY || defined DDSRT_HAVE_SSM) (void) gv; #endif ddsrt_free (m); @@ -936,7 +936,7 @@ void ddsi_reader_add_connection (struct ddsi_reader *rd, struct ddsi_proxy_write rd->num_writers++; ddsrt_mutex_unlock (&rd->e.lock); -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM if (rd->favours_ssm && pwr->supports_ssm) { /* pwr->supports_ssm is set if ddsi_addrset_contains_ssm(pwr->ssm), so diff --git a/src/core/ddsi/src/ddsi_init.c b/src/core/ddsi/src/ddsi_init.c index fcf9d42760..c69610fc30 100644 --- a/src/core/ddsi/src/ddsi_init.c +++ b/src/core/ddsi/src/ddsi_init.c @@ -394,7 +394,7 @@ static int set_spdp_address (struct ddsi_domaingv *gv) rc = string_to_default_locator (gv, &gv->loc_spdp_mc, gv->m_factory->m_default_spdp_address, port, 1, "SPDP address"); assert (rc > 0); } -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM if (gv->loc_spdp_mc.kind != DDSI_LOCATOR_KIND_INVALID && ddsi_is_ssm_mcaddr (gv, &gv->loc_spdp_mc)) { GVERROR ("%s: SPDP address may not be an SSM address\n", gv->config.spdpMulticastAddressString); @@ -669,7 +669,7 @@ static void joinleave_spdp_defmcip_helper (const ddsi_xlocator_t *loc, void *var struct joinleave_spdp_defmcip_helper_arg *arg = varg; if (!ddsi_is_mcaddr (arg->gv, &loc->c)) return; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM /* Can't join SSM until we actually have a source */ if (ddsi_is_ssm_mcaddr (arg->gv, &loc->c)) return; @@ -1367,7 +1367,7 @@ int ddsi_init (struct ddsi_domaingv *gv, struct ddsi_psmx_instance_locators *psm GVLOG (DDS_LC_CONFIG, "extmask: %s%s\n", ddsi_locator_to_string_no_port (buf, sizeof(buf), &gv->extmask), gv->extmask.kind != DDSI_LOCATOR_KIND_UDPv4 ? " (not applicable)" : ""); GVLOG (DDS_LC_CONFIG, "SPDP MC: %s\n", ddsi_locator_to_string_no_port (buf, sizeof(buf), &gv->loc_spdp_mc)); GVLOG (DDS_LC_CONFIG, "default MC: %s\n", ddsi_locator_to_string_no_port (buf, sizeof(buf), &gv->loc_default_mc)); -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM GVLOG (DDS_LC_CONFIG, "SSM support included\n"); #endif } diff --git a/src/core/ddsi/src/ddsi_mcgroup.c b/src/core/ddsi/src/ddsi_mcgroup.c index dd49c72ff9..d45d476872 100644 --- a/src/core/ddsi/src/ddsi_mcgroup.c +++ b/src/core/ddsi/src/ddsi_mcgroup.c @@ -135,7 +135,7 @@ static char *make_joinleave_msg (char *buf, size_t bufsz, struct ddsi_tran_conn char mcstr[DDSI_LOCSTRLEN], interfstr[DDSI_LOCSTRLEN]; char srcstr[DDSI_LOCSTRLEN] = { '*', '\0' }; int n; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM if (srcloc) { ddsi_locator_to_string_no_port(srcstr, sizeof(srcstr), srcloc); } diff --git a/src/core/ddsi/src/ddsi_nwinterfaces.c b/src/core/ddsi/src/ddsi_nwinterfaces.c index 5e8b8a06dd..64197ba220 100644 --- a/src/core/ddsi/src/ddsi_nwinterfaces.c +++ b/src/core/ddsi/src/ddsi_nwinterfaces.c @@ -573,7 +573,7 @@ int ddsi_gather_network_interfaces (struct ddsi_domaingv *gv) flagpos += snprintf (flagstr + flagpos, sizeof (flagstr) - (size_t) flagpos, "%sspdp", (flagpos > 0) ? "," : ""); if (gv->interfaces[i].allow_multicast & DDSI_AMC_ASM) flagpos += snprintf (flagstr + flagpos, sizeof (flagstr) - (size_t) flagpos, "%sasm", (flagpos > 0) ? "," : ""); -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM if (gv->interfaces[i].allow_multicast & DDSI_AMC_SSM) flagpos += snprintf (flagstr + flagpos, sizeof (flagstr) - (size_t) flagpos, "%sssm", (flagpos > 0) ? "," : ""); #endif diff --git a/src/core/ddsi/src/ddsi_nwpart.c b/src/core/ddsi/src/ddsi_nwpart.c index 80e4800d2d..c81cf79c7e 100644 --- a/src/core/ddsi/src/ddsi_nwpart.c +++ b/src/core/ddsi/src/ddsi_nwpart.c @@ -31,7 +31,7 @@ struct nwpart_iter { bool ok; struct ddsi_networkpartition_address **nextp_uc; struct ddsi_networkpartition_address **nextp_asm; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM struct ddsi_networkpartition_address **nextp_ssm; #endif }; @@ -154,7 +154,7 @@ static void ddsi_free_config_nwpart_addresses_one (struct ddsi_config_networkpar struct ddsi_networkpartition_address **ps[] = { &np->uc_addresses, &np->asm_addresses -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM , &np->ssm_addresses #endif }; @@ -199,7 +199,7 @@ static struct ddsi_config_networkpartition_listelem *nwpart_iter_next (struct nw it->next_nwp = nwp->next; it->nextp_uc = &nwp->uc_addresses; it->nextp_asm = &nwp->asm_addresses; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM it->nextp_ssm = &nwp->ssm_addresses; #endif return nwp; @@ -222,7 +222,7 @@ static void nwpart_iter_append_address (struct nwpart_iter *it, const char *tok, if (ddsi_is_mcaddr (it->gv, loc)) { -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM nextpp = ddsi_is_ssm_mcaddr (it->gv, loc) ? &it->nextp_ssm : &it->nextp_asm; #else nextpp = &it->nextp_asm; @@ -353,7 +353,7 @@ static bool nwpart_has_multicast (const struct ddsi_config_networkpartition_list { if (np->asm_addresses) return true; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM if (np->ssm_addresses) return true; #endif diff --git a/src/core/ddsi/src/ddsi_plist.c b/src/core/ddsi/src/ddsi_plist.c index dd5c80f5d4..e83cc96678 100644 --- a/src/core/ddsi/src/ddsi_plist.c +++ b/src/core/ddsi/src/ddsi_plist.c @@ -1984,7 +1984,7 @@ static dds_return_t dvx_endpoint_guid (void * __restrict dst, const struct dd * } } -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM static dds_return_t dvx_reader_favours_ssm (void * __restrict dst, const struct dd * __restrict dd) { uint32_t * const favours_ssm = dst; @@ -2055,7 +2055,7 @@ static const struct piddesc piddesc_omg[] = { PP (BUILTIN_ENDPOINT_SET, builtin_endpoint_set, Xu), PP (KEYHASH, keyhash, XK), PPV (ENDPOINT_GUID, endpoint_guid, XG), -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM PPV (READER_FAVOURS_SSM, reader_favours_ssm, Xu), #endif #ifdef DDS_HAS_SECURITY diff --git a/src/core/ddsi/src/ddsi_proxy_endpoint.c b/src/core/ddsi/src/ddsi_proxy_endpoint.c index df4b131a95..033feebc14 100644 --- a/src/core/ddsi/src/ddsi_proxy_endpoint.c +++ b/src/core/ddsi/src/ddsi_proxy_endpoint.c @@ -160,7 +160,7 @@ static void proxy_endpoint_common_fini (struct ddsi_entity_common *e, struct dds ddsi_entity_common_fini (e); } -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM static void addrset_interfaces_allow_ssm_helper (const ddsi_xlocator_t *xloc, void *vssm_allowed) { bool *ssm_allowed = vssm_allowed; @@ -280,7 +280,7 @@ int ddsi_new_proxy_writer (struct ddsi_proxy_writer **proxy_writer, struct ddsi_ isreliable = (pwr->c.xqos->reliability.kind != DDS_RELIABILITY_BEST_EFFORT); pwr->have_seen_heartbeat = !isreliable; pwr->local_matching_inprogress = 1; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM pwr->supports_ssm = (ddsi_addrset_contains_ssm (gv, as) && addrset_interfaces_allow_ssm (as)) ? 1 : 0; #endif pwr->local_psmx = proxy_is_local_psmx(gv, as); @@ -368,7 +368,7 @@ void ddsi_update_proxy_writer (struct ddsi_proxy_writer *pwr, ddsi_seqno_t seq, pwr->c.seq = seq; if (! ddsi_addrset_eq_onesidederr (pwr->c.as, as)) { -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM pwr->supports_ssm = (ddsi_addrset_contains_ssm (pwr->e.gv, as) && addrset_interfaces_allow_ssm (as)) ? 1 : 0; #endif ddsi_unref_addrset (pwr->c.as); @@ -572,7 +572,7 @@ int ddsi_proxy_writer_set_notalive (struct ddsi_proxy_writer *pwr, bool notify) /* PROXY-READER ----------------------------------------------------- */ int ddsi_new_proxy_reader (struct ddsi_proxy_reader **proxy_reader, struct ddsi_domaingv *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct ddsi_addrset *as, const ddsi_plist_t *plist, ddsrt_wctime_t timestamp, ddsi_seqno_t seq -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM , int favours_ssm #endif ) @@ -600,7 +600,7 @@ int ddsi_new_proxy_reader (struct ddsi_proxy_reader **proxy_reader, struct ddsi_ } prd->deleting = 0; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM prd->favours_ssm = (favours_ssm && addrset_interfaces_allow_ssm (as)) ? 1 : 0; #endif prd->local_psmx = proxy_is_local_psmx (gv, as); diff --git a/src/core/ddsi/src/ddsi_proxy_participant.c b/src/core/ddsi/src/ddsi_proxy_participant.c index 9be68fe30a..ea1143706f 100644 --- a/src/core/ddsi/src/ddsi_proxy_participant.c +++ b/src/core/ddsi/src/ddsi_proxy_participant.c @@ -122,7 +122,7 @@ static void create_proxy_builtin_endpoint_impl (struct ddsi_domaingv *gv, ddsrt_ else { struct ddsi_proxy_reader *proxy_reader; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM const int ssm = ddsi_addrset_contains_ssm (gv, proxypp->as_meta); ddsi_new_proxy_reader (&proxy_reader, gv, ppguid, ep_guid, proxypp->as_meta, plist, timestamp, 0, ssm); #else diff --git a/src/core/ddsi/src/ddsi_udp.c b/src/core/ddsi/src/ddsi_udp.c index 2a5823bff9..5efd60b4a1 100644 --- a/src/core/ddsi/src/ddsi_udp.c +++ b/src/core/ddsi/src/ddsi_udp.c @@ -777,7 +777,7 @@ static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const ddsi_lo return (rc == DDS_RETCODE_OK) ? 0 : -1; } -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM static int joinleave_ssm_mcgroup (ddsrt_socket_t socket, int join, const ddsi_locator_t *srcloc, const ddsi_locator_t *mcloc, const struct ddsi_network_interface *interf) { dds_return_t rc; @@ -815,7 +815,7 @@ static int ddsi_udp_join_mc (struct ddsi_tran_conn * conn_cmn, const ddsi_locato { ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn; (void) srcloc; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM if (srcloc) return joinleave_ssm_mcgroup (conn->m_sockext.sock, 1, srcloc, mcloc, interf); else @@ -827,7 +827,7 @@ static int ddsi_udp_leave_mc (struct ddsi_tran_conn * conn_cmn, const ddsi_locat { ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn; (void) srcloc; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM if (srcloc) return joinleave_ssm_mcgroup (conn->m_sockext.sock, 0, srcloc, mcloc, interf); else @@ -902,7 +902,7 @@ static int ddsi_udp_is_mcaddr (const struct ddsi_tran_factory *tran, const ddsi_ } } -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM static int ddsi_udp_is_ssm_mcaddr (const struct ddsi_tran_factory *tran, const ddsi_locator_t *loc) { (void) tran; @@ -1068,7 +1068,7 @@ int ddsi_udp_init (struct ddsi_domaingv*gv) fact->fact.m_leave_mc_fn = ddsi_udp_leave_mc; fact->fact.m_is_loopbackaddr_fn = ddsi_udp_is_loopbackaddr; fact->fact.m_is_mcaddr_fn = ddsi_udp_is_mcaddr; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM fact->fact.m_is_ssm_mcaddr_fn = ddsi_udp_is_ssm_mcaddr; #endif fact->fact.m_is_nearby_address_fn = ddsi_ipaddr_is_nearby_address; diff --git a/src/core/ddsi/src/ddsi_wraddrset.c b/src/core/ddsi/src/ddsi_wraddrset.c index 3805e76d43..27e7de87fe 100644 --- a/src/core/ddsi/src/ddsi_wraddrset.c +++ b/src/core/ddsi/src/ddsi_wraddrset.c @@ -207,7 +207,7 @@ static struct ddsi_addrset *wras_collect_all_locs (const struct ddsi_writer *wr) } if (!ddsi_addrset_empty (all_addrs)) { -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM if (wr->supports_ssm && wr->ssm_as) ddsi_copy_addrset_into_addrset_mc (wr->e.gv, all_addrs, wr->ssm_as); #endif @@ -439,7 +439,7 @@ static int move_loopback_forward (struct ddsi_domaingv const * const gv, struct static unsigned multicast_indicator (struct ddsi_domaingv const * const gv, const ddsi_xlocator_t *l) { -#if DDS_HAS_SSM +#if DDSRT_HAVE_SSM if (ddsi_is_ssm_mcaddr (gv, &l->c)) return CI_MULTICAST_SSM; #endif @@ -509,7 +509,7 @@ static bool wras_calc_cover (const struct ddsi_writer *wr, const struct locset * if ((prd = ddsi_entidx_lookup_proxy_reader_guid (gh, &m->prd_guid)) == NULL) continue; ass[0] = prd->c.as; -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM if (prd->favours_ssm && wr->supports_ssm) ass[1] = wr->ssm_as; #endif diff --git a/src/core/ddsi/tests/wraddrset.c b/src/core/ddsi/tests/wraddrset.c index 6e34f98675..c8fa953a2a 100644 --- a/src/core/ddsi/tests/wraddrset.c +++ b/src/core/ddsi/tests/wraddrset.c @@ -226,7 +226,7 @@ static void ddsi_wraddrset_some_cases (int casenumber, int cost, bool wr_psmx, c ddsi_add_xlocator_to_addrset (&gv, rd_as, &(ddsi_xlocator_t){ .conn = &fake_conn, .c = psmxloc[i] }); } struct ddsi_proxy_reader *proxy_reader; -#if DDS_HAS_SSM +#if DDSRT_HAVE_SSM ddsi_new_proxy_reader (&proxy_reader, &gv, &rdppguid[i][j], &rdguid, rd_as, &plist_rd, ddsrt_time_wallclock (), 1, false); #else ddsi_new_proxy_reader (&proxy_reader, &gv, &rdppguid[i][j], &rdguid, rd_as, &plist_rd, ddsrt_time_wallclock (), 1); diff --git a/src/core/xtests/symbol_export/symbol_export.c b/src/core/xtests/symbol_export/symbol_export.c index aa1ffa7988..2b8e107c79 100644 --- a/src/core/xtests/symbol_export/symbol_export.c +++ b/src/core/xtests/symbol_export/symbol_export.c @@ -763,7 +763,7 @@ int main (int argc, char **argv) // ddsi/ddsi_proxy_endpoint.h ddsi_new_proxy_writer (ptr, ptr2, ptr3, ptr4, ptr5, ptr6, ptr7, ptr8, ddsrt_time_wallclock(), 0); -#ifdef DDS_HAS_SSM +#ifdef DDSRT_HAVE_SSM ddsi_new_proxy_reader (ptr, ptr2, ptr3, ptr4, ptr5, ptr6, ddsrt_time_wallclock(), 0, 0); #else ddsi_new_proxy_reader (ptr, ptr2, ptr3, ptr4, ptr5, ptr6, ddsrt_time_wallclock(), 0); diff --git a/src/ddsrt/CMakeLists.txt b/src/ddsrt/CMakeLists.txt index 441a5fbfdb..3a2d5169e3 100644 --- a/src/ddsrt/CMakeLists.txt +++ b/src/ddsrt/CMakeLists.txt @@ -117,6 +117,7 @@ if(WITH_LWIP) set(hostname_header "unistd.h") set(inet_header "lwip/sockets.h") set(netdb_header "lwip/netdb.h") + set(sockopt_header "lwip/sockets.h") list(APPEND headers "${source_dir}/include/dds/ddsrt/sockets/posix.h") list(APPEND sources @@ -135,6 +136,7 @@ else() set(hostname_header "winsock2.h") set(inet_header "ws2tcpip.h") set(netdb_header "ws2tcpip.h") + set(sockopt_header "ws2tcpip.h") list(APPEND headers "${source_dir}/include/dds/ddsrt/sockets/windows.h") list(APPEND sources @@ -146,6 +148,7 @@ else() set(hostname_header "unistd.h") set(inet_header "arpa/inet.h") set(netdb_header "netdb.h") + set(sockopt_header "netinet/in.h") list(APPEND headers "${source_dir}/include/dds/ddsrt/sockets/posix.h") list(APPEND sources @@ -169,11 +172,53 @@ check_symbol_exists("gethostbyname_r" ${netdb_header} DDSRT_HAVE_GETHOSTBYNAME_R if(DDSRT_HAVE_GETADDRINFO OR DDSRT_HAVE_GETHOSTBYNAME_R) set(DDSRT_HAVE_DNS TRUE) endif() -check_type_size("struct sockaddr_in6" SIZEOF_SOCKADDR_IN6) +set(DDSRT_HAVE_IPV6 FALSE) if(ENABLE_IPV6) - if(SIZEOF_SOCKADDR_IN6) + check_type_size("struct sockaddr_in6" SIZEOF_SOCKADDR_IN6) + if(NOT ENABLE_IPV6 STREQUAL "AUTO") + if(SIZEOF_SOCKADDR_IN6) + set(DDSRT_HAVE_IPV6 TRUE) + else() + message(FATAL_ERROR "ENABLE_IPV6 requires IPv6 to be supported by the platform") + endif() + elseif(SIZEOF_SOCKADDR_IN6) set(DDSRT_HAVE_IPV6 TRUE) + set(ENABLE_IPV6 ON) + else() + set(ENABLE_IPV6 OFF) + endif() +endif() +if(DDSRT_HAVE_IPV6) + message(STATUS "Building with IPv6 support") +else() + message(STATUS "Building without IPv6 support") +endif() +set(DDSRT_HAVE_SSM FALSE) +if(ENABLE_SOURCE_SPECIFIC_MULTICAST) + check_symbol_exists("IP_ADD_SOURCE_MEMBERSHIP" ${sockopt_header} DDSRT_HAVE_IP_ADD_SOURCE_MEMBERSHIP) + if(DDSRT_HAVE_IPV6) + check_symbol_exists("MCAST_JOIN_SOURCE_GROUP" ${sockopt_header} DDSRT_HAVE_MCAST_JOIN_SOURCE_GROUP) + else() + # Set MCAST_JOIN_SOURCE_GROUP if IPv6 is disabled to simplify the logic here + set(DDSRT_HAVE_MCAST_JOIN_SOURCE_GROUP TRUE) endif() + if(NOT ENABLE_SOURCE_SPECIFIC_MULTICAST STREQUAL "AUTO") + if(DDSRT_HAVE_IP_ADD_SOURCE_MEMBERSHIP AND DDSRT_HAVE_MCAST_JOIN_SOURCE_GROUP) + set(DDSRT_HAVE_SSM TRUE) + else() + message(FATAL_ERROR "ENABLE_SOURCE_SPECIFIC_MULTICAST requires SSM to be supported by the platform") + endif() + elseif(DDSRT_HAVE_IP_ADD_SOURCE_MEMBERSHIP AND DDSRT_HAVE_MCAST_JOIN_SOURCE_GROUP) + set(DDSRT_HAVE_SSM TRUE) + set(ENABLE_SOURCE_SPECIFIC_MULTICAST ON) + else() + set(ENABLE_SOURCE_SPECIFIC_MULTICAST OFF) + endif() +endif() +if(DDSRT_HAVE_SSM) + message(STATUS "Building with source-specific multicast support") +else() + message(STATUS "Building without source-specific multicast support") endif() if(WITH_FREERTOS) @@ -311,7 +356,7 @@ set(DDSRT_WITH_LWIP ${WITH_LWIP}) set(DDSRT_WITH_FREERTOS ${WITH_FREERTOS}) foreach(feature TCP_TLS SECURITY LIFESPAN DEADLINE_MISSED NETWORK_PARTITIONS - SSM TYPELIB TYPE_DISCOVERY TOPIC_DISCOVERY QOS_PROVIDER) + TYPELIB TYPE_DISCOVERY TOPIC_DISCOVERY QOS_PROVIDER) set(DDS_HAS_${feature} ${ENABLE_${feature}}) endforeach() diff --git a/src/ddsrt/include/dds/config.h.in b/src/ddsrt/include/dds/config.h.in index 86c1f6c12c..3d2ef710f0 100644 --- a/src/ddsrt/include/dds/config.h.in +++ b/src/ddsrt/include/dds/config.h.in @@ -20,6 +20,7 @@ #cmakedefine DDSRT_HAVE_RUSAGE 1 #cmakedefine DDSRT_HAVE_IPV6 1 +#cmakedefine DDSRT_HAVE_SSM 1 #cmakedefine DDSRT_HAVE_DNS 1 #cmakedefine DDSRT_HAVE_GETADDRINFO 1 #cmakedefine DDSRT_HAVE_GETHOSTBYNAME_R 1 diff --git a/src/ddsrt/include/dds/ddsrt/sockets/posix.h b/src/ddsrt/include/dds/ddsrt/sockets/posix.h index d8d49dc419..17836fa02f 100644 --- a/src/ddsrt/include/dds/ddsrt/sockets/posix.h +++ b/src/ddsrt/include/dds/ddsrt/sockets/posix.h @@ -42,21 +42,19 @@ typedef struct ddsrt_socket_ext { } ddsrt_socket_ext_t; #if LWIP_SOCKET -# define DDSRT_HAVE_SSM 0 # define IFF_UP 0x1 # define IFF_BROADCAST 0x2 # define IFF_LOOPBACK 0x8 # define IFF_POINTOPOINT 0x10 # define IFF_MULTICAST 0x1000 #elif __SunOS_5_6 -# define DDSRT_HAVE_SSM 0 +// nothing needed so far #elif __ZEPHYR__ /* In Zephyr, a network interface can join a multi-cast group only once. So setsockopt is called only for the first socket to join a group, other sockets for the same group will be skipped */ #define DDSRT_MCGROUP_JOIN_ONCE 1 -# define DDSRT_HAVE_SSM 0 # define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */ # define IN_MULTICAST(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000) @@ -85,8 +83,8 @@ typedef struct ddsrt_socket_ext { # define IPV6_MULTICAST_LOOP 96 #endif -#else -# define DDSRT_HAVE_SSM 1 +#else // Unix/Windows/... +// nothing needed so far #endif /* LWIP_SOCKET */ typedef struct msghdr ddsrt_msghdr_t; diff --git a/src/ddsrt/include/dds/ddsrt/sockets/windows.h b/src/ddsrt/include/dds/ddsrt/sockets/windows.h index 218a2ef44f..0f12619486 100644 --- a/src/ddsrt/include/dds/ddsrt/sockets/windows.h +++ b/src/ddsrt/include/dds/ddsrt/sockets/windows.h @@ -19,14 +19,6 @@ typedef struct ddsrt_socket_ext_t { LPFN_WSARECVMSG wsarecvmsg; } ddsrt_socket_ext_t; -#if defined(NTDDI_VERSION) && \ - defined(_WIN32_WINNT_WS03) && \ - (NTDDI_VERSION >= _WIN32_WINNT_WS03) -#define DDSRT_HAVE_SSM 1 -#else -#define DDSRT_HAVE_SSM 0 -#endif - #define IFF_POINTOPOINT IFF_POINTTOPOINT // Required when compiling with mingw-w64. diff --git a/src/ddsrt/include/dds/features.h.in b/src/ddsrt/include/dds/features.h.in index 1320863aaf..a294df19bf 100644 --- a/src/ddsrt/include/dds/features.h.in +++ b/src/ddsrt/include/dds/features.h.in @@ -23,9 +23,6 @@ /* Whether or not support for network partitions is included */ #cmakedefine DDS_HAS_NETWORK_PARTITIONS 1 -/* Whether or not support for source-specific multicast is included */ -#cmakedefine DDS_HAS_SSM 1 - /* Whether or not features dependent on OpenSSL are included */ #cmakedefine DDS_HAS_TCP_TLS 1 From d54189dd460c8ba6442b16d5e7574b8e980d7ba1 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 19 Apr 2024 08:33:51 +0200 Subject: [PATCH 133/207] oneliner "hearing!" wait for proxypp to be deleted If we don't wait for the proxy participant to be deleted before triggering the publishing of SPDP samples, these samples may be discarded because the stack isn't yet ready to handle the rediscovery. That in turn causes some spurious test failures. --- src/core/ddsc/tests/test_oneliner.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/core/ddsc/tests/test_oneliner.c b/src/core/ddsc/tests/test_oneliner.c index b77e8b04c8..d4f0537b6d 100644 --- a/src/core/ddsc/tests/test_oneliner.c +++ b/src/core/ddsc/tests/test_oneliner.c @@ -26,7 +26,9 @@ #include "dds/ddsi/ddsi_xevent.h" #include "dds/ddsi/ddsi_entity_index.h" #include "dds/ddsi/ddsi_participant.h" +#include "dds/ddsi/ddsi_gc.h" #include "ddsi__lease.h" +#include "ddsi__participant.h" #include "ddsi__proxy_participant.h" #include "dds/dds.h" #include "dds__types.h" @@ -1807,6 +1809,18 @@ static void dodeaf (struct oneliner_ctx *ctx) dodeaf_maybe_imm (ctx, immediate); } +static void wait_for_cleanup (struct oneliner_ctx *ctx, dds_entity_t recovering_participant_handle, const ddsi_guid_t *guid) +{ + dds_entity *xprime; + dds_return_t ret; + if ((ret = dds_entity_pin (recovering_participant_handle, &xprime)) < 0) + error_dds (ctx, ret, "wait_for_cleanup: pin participant failed %"PRId32, recovering_participant_handle); + struct ddsi_domaingv * const gv = &xprime->m_domain->gv; + while (ddsi_is_deleted_participant_guid (gv->deleted_participants, guid, DDSI_DELETED_PPGUID_LOCAL | DDSI_DELETED_PPGUID_REMOTE)) + dds_sleepfor (DDS_MSECS (10)); + dds_entity_unpin (xprime); +} + static void dohearing_maybe_imm (struct oneliner_ctx *ctx, bool immediate) { char const * const mode = immediate ? "hearing!" : "hearing"; @@ -1823,6 +1837,9 @@ static void dohearing_maybe_imm (struct oneliner_ctx *ctx, bool immediate) if (immediate) { // speed up the process by forcing SPDP publication on the remote + // better wait until our local GC completed because we block + // rediscovery of the remote participant while we're still cleaning + // up after it for (int i = 0; i < (int) (sizeof (ctx->doms) / sizeof (ctx->doms[0])); i++) { if (i == ent / 9 || ctx->es[9*i] == 0) @@ -1831,6 +1848,7 @@ static void dohearing_maybe_imm (struct oneliner_ctx *ctx, bool immediate) struct ddsi_participant *pp; if ((ret = dds_entity_pin (ctx->es[9*i], &xprime)) < 0) error_dds (ctx, ret, "%s: pin counterpart participant failed %"PRId32, mode, ctx->es[9*i]); + wait_for_cleanup (ctx, ctx->es[ent], &xprime->m_guid); ddsi_thread_state_awake (ddsi_lookup_thread_state (), &xprime->m_domain->gv); if ((pp = ddsi_entidx_lookup_participant_guid (xprime->m_domain->gv.entity_index, &xprime->m_guid)) != NULL) ddsi_resched_xevent_if_earlier (pp->spdp_xevent, ddsrt_mtime_add_duration (ddsrt_time_monotonic (), DDS_MSECS (100))); From 3dea06d4ca1e71f86f9e44ac9de5208643d0448d Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 14 Jun 2024 07:38:42 +0200 Subject: [PATCH 134/207] Refactor ddsi_type_add_typeobj This should be easier to follow, set breakpoints on and step through in the debugger. --- src/core/ddsi/src/ddsi_typelib.c | 62 ++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/core/ddsi/src/ddsi_typelib.c b/src/core/ddsi/src/ddsi_typelib.c index d7f62d05fe..7a6c1c7e63 100644 --- a/src/core/ddsi/src/ddsi_typelib.c +++ b/src/core/ddsi/src/ddsi_typelib.c @@ -469,35 +469,43 @@ static void set_type_invalid (struct ddsi_domaingv *gv, struct ddsi_type *type) dds_return_t ddsi_type_add_typeobj (struct ddsi_domaingv *gv, struct ddsi_type *type, const struct DDS_XTypes_TypeObject *type_obj) { - dds_return_t ret = DDS_RETCODE_OK; - if (type->state != DDSI_TYPE_RESOLVED) + if (type->state == DDSI_TYPE_RESOLVED) + return DDS_RETCODE_OK; + + dds_return_t ret; + ddsi_typeid_t type_id; + ret = ddsi_typeobj_get_hash_id (type_obj, &type_id); + if (ret != DDS_RETCODE_OK) { - ddsi_typeid_t type_id; - int cmp = -1; - if ((ret = ddsi_typeobj_get_hash_id (type_obj, &type_id)) - || (ret = (cmp = ddsi_typeid_compare (&type->xt.id, &type_id)) ? DDS_RETCODE_BAD_PARAMETER : DDS_RETCODE_OK) - || (ret = ddsi_xt_type_add_typeobj (gv, &type->xt, type_obj)) - ) { - if (cmp == 0) - { - /* Mark this type and all types that (indirectly) depend on this type - invalid, because at this point we know that the type object that matches - the type id for this type is invalid (except in case of a hash collision - and a different valid type object exists with the same id) */ - set_type_invalid (gv, type); - } - else - { - /* In case the object does not match the type id, reset the type's state to - unresolved so that it can de resolved in case the correct type object - is received */ - type->state = DDSI_TYPE_UNRESOLVED; - } - } - else - type->state = DDSI_TYPE_RESOLVED; + /* In case the object does not match the type id, reset the type's state to + unresolved so that it can de resolved in case the correct type object + is received */ + type->state = DDSI_TYPE_UNRESOLVED; + return ret; } - return ret; + + if (ddsi_typeid_compare (&type->xt.id, &type_id) != 0) + { + /* In case the object does not match the type id, reset the type's state to + unresolved so that it can de resolved in case the correct type object + is received */ + type->state = DDSI_TYPE_UNRESOLVED; + return DDS_RETCODE_BAD_PARAMETER; + } + + ret = ddsi_xt_type_add_typeobj (gv, &type->xt, type_obj); + if (ret != DDS_RETCODE_OK) + { + /* Mark this type and all types that (indirectly) depend on this type + invalid, because at this point we know that the type object that matches + the type id for this type is invalid (except in case of a hash collision + and a different valid type object exists with the same id) */ + set_type_invalid (gv, type); + return ret; + } + + type->state = DDSI_TYPE_RESOLVED; + return DDS_RETCODE_OK; } static dds_return_t ddsi_type_register_dep_impl (struct ddsi_domaingv *gv, const ddsi_typeid_t *src_type_id, struct ddsi_type **dst_dep_type, const struct DDS_XTypes_TypeIdentifier *dep_tid, bool from_type_info) From e1853ef7944f7b4145f243f3f7ce3ac934c7eff0 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 14 Jun 2024 07:12:44 +0200 Subject: [PATCH 135/207] Do not change type in typelib making key holder Type assignability for structs can require constructing a key holder type, which in turn involves marking all fields as key fields for a struct that has no key fields defined, e.g., when: struct Inner { long a, b; }; struct Outer { @key Inner k; }; the key holder type will constructing a type where "a" and "b" are annotated as keys. The code for doing this incorrectly modified the input type already in the library, rather than setting the flag on the new key holder type. Obviously, silently changing the type in the library is bad. It was observed because the change affects the type identifier (without changing where the type is in the index) and the mismatch got flagged while processing a type lookup reply. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_typewrap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ddsi/src/ddsi_typewrap.c b/src/core/ddsi/src/ddsi_typewrap.c index edd3e24d74..9dc842168f 100644 --- a/src/core/ddsi/src/ddsi_typewrap.c +++ b/src/core/ddsi/src/ddsi_typewrap.c @@ -2161,7 +2161,7 @@ static struct xt_type *xt_type_keyholder (struct ddsi_domaingv *gv, const struct { /* Rule: If T is a structure with no key members, then KeyHolder(T) adds a key designator to each member. */ for (uint32_t i = 0; i < t->_u.structure.members.length; i++) - t->_u.structure.members.seq[i].flags |= DDS_XTypes_IS_KEY; + tkh->_u.structure.members.seq[i].flags |= DDS_XTypes_IS_KEY; } return tkh; } From 34eef7e7bf6695cf15afcf78139cae915cc9d636 Mon Sep 17 00:00:00 2001 From: eboasson Date: Mon, 17 Jun 2024 13:16:58 +0200 Subject: [PATCH 136/207] Skip optionals completely when deserializing a key (#2040) * Skip optionals completely when deserializing a key The serialized key only contains the key fields and when deserializing a key one must skip everything else. The deserialization (and printing) code incorrectly read the boolean indicating presence of an optional field in cases like: struct S { @optional long x; @key long y; }; This commit fixes it by first checking whether a key is being deserialized, skipping the checks for the presence of an optional field if it is. (Note that optional fields can not be key fields.) Signed-off-by: Erik Boasson * Overlooked the "normalize" case Signed-off-by: Erik Boasson --------- Signed-off-by: Erik Boasson --- src/core/cdr/src/dds_cdrstream.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/core/cdr/src/dds_cdrstream.c b/src/core/cdr/src/dds_cdrstream.c index c875e7b335..189bfa65a1 100644 --- a/src/core/cdr/src/dds_cdrstream.c +++ b/src/core/cdr/src/dds_cdrstream.c @@ -1837,13 +1837,14 @@ static inline const uint32_t *stream_skip_member (uint32_t insn, char * __restri static inline const uint32_t *dds_stream_read_adr (uint32_t insn, dds_istream_t * __restrict is, char * __restrict data, const struct dds_cdrstream_allocator * __restrict allocator, const uint32_t * __restrict ops, bool is_mutable_member, enum cdr_data_kind cdr_kind, enum sample_data_state sample_state) { void *addr = data + ops[1]; - if (!stream_is_member_present (insn, is, is_mutable_member)) - return stream_skip_member (insn, data, addr, allocator, ops, sample_state); const bool is_key = (insn & DDS_OP_FLAG_KEY); if (cdr_kind == CDR_KIND_KEY && !is_key) return dds_stream_skip_adr (insn, ops); + if (!stream_is_member_present (insn, is, is_mutable_member)) + return stream_skip_member (insn, data, addr, allocator, ops, sample_state); + if (op_type_external (insn)) dds_stream_alloc_external (ops, insn, &addr, allocator, &sample_state); @@ -2869,6 +2870,10 @@ static const uint32_t *normalize_uni (char * __restrict data, uint32_t * __restr static const uint32_t *stream_normalize_adr (uint32_t insn, char * __restrict data, uint32_t * __restrict off, uint32_t size, bool bswap, uint32_t xcdr_version, const uint32_t * __restrict ops, bool is_mutable_member, enum cdr_data_kind cdr_kind) ddsrt_attribute_warn_unused_result ddsrt_nonnull_all; static const uint32_t *stream_normalize_adr (uint32_t insn, char * __restrict data, uint32_t * __restrict off, uint32_t size, bool bswap, uint32_t xcdr_version, const uint32_t * __restrict ops, bool is_mutable_member, enum cdr_data_kind cdr_kind) { + const bool is_key = (insn & DDS_OP_FLAG_KEY); + if (cdr_kind == CDR_KIND_KEY && !is_key) + return dds_stream_skip_adr (insn, ops); + if (op_type_optional (insn)) { bool present = true; @@ -2881,10 +2886,6 @@ static const uint32_t *stream_normalize_adr (uint32_t insn, char * __restrict da return dds_stream_skip_adr (insn, ops); } - const bool is_key = (insn & DDS_OP_FLAG_KEY); - if (cdr_kind == CDR_KIND_KEY && !is_key) - return dds_stream_skip_adr (insn, ops); - switch (DDS_OP_TYPE (insn)) { case DDS_OP_VAL_BLN: if (!normalize_bool (data, off, size)) return NULL; ops += 2; break; @@ -4300,15 +4301,16 @@ static const uint32_t *prtf_uni (char * __restrict *buf, size_t *bufsize, dds_is static const uint32_t * dds_stream_print_adr (char * __restrict *buf, size_t * __restrict bufsize, uint32_t insn, dds_istream_t * __restrict is, const uint32_t * __restrict ops, bool is_mutable_member, enum cdr_data_kind cdr_kind) { + const bool is_key = (insn & DDS_OP_FLAG_KEY); + if (cdr_kind == CDR_KIND_KEY && !is_key) + return dds_stream_skip_adr (insn, ops); + if (!stream_is_member_present (insn, is, is_mutable_member)) { (void) prtf (buf, bufsize, "NULL"); return dds_stream_skip_adr (insn, ops); } - const bool is_key = (insn & DDS_OP_FLAG_KEY); - if (cdr_kind == CDR_KIND_KEY && !is_key) - return dds_stream_skip_adr (insn, ops); switch (DDS_OP_TYPE (insn)) { case DDS_OP_VAL_BLN: case DDS_OP_VAL_1BY: case DDS_OP_VAL_2BY: case DDS_OP_VAL_4BY: case DDS_OP_VAL_8BY: From a27ebfd50997167da43778bdb01cc5f1b1ee77b0 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 14 Jun 2024 07:32:21 +0200 Subject: [PATCH 137/207] dynsub example: also respond to DCPSSubscription This is the easiest way to extend the example to also work when there is no writer yet. Signed-off-by: Erik Boasson --- examples/dynsub/dynsub.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/examples/dynsub/dynsub.c b/examples/dynsub/dynsub.c index a224209c52..97ec61b951 100644 --- a/examples/dynsub/dynsub.c +++ b/examples/dynsub/dynsub.c @@ -36,22 +36,30 @@ static dds_entity_t participant; -// Helper function to wait for a DCPSPublication to show up with the desired topic name, then calls -// dds_find_topic to create a topic for that data writer's type up the retrieves the type object. +// Helper function to wait for a DCPSPublication/DCPSSubscription to show up with the desired topic name, +// then calls dds_find_topic to create a topic for that data writer's/reader's type up the retrieves the +// type object. static dds_return_t get_topic_and_typeobj (const char *topic_name, dds_duration_t timeout, dds_entity_t *topic, DDS_XTypes_TypeObject **xtypeobj) { const dds_entity_t waitset = dds_create_waitset (participant); const dds_entity_t dcpspublication_reader = dds_create_reader (participant, DDS_BUILTIN_TOPIC_DCPSPUBLICATION, NULL, NULL); const dds_entity_t dcpspublication_readcond = dds_create_readcondition (dcpspublication_reader, DDS_ANY_STATE); - (void) dds_waitset_attach (waitset, dcpspublication_readcond, 0); + const dds_entity_t dcpssubscription_reader = dds_create_reader (participant, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL); + const dds_entity_t dcpssubscription_readcond = dds_create_readcondition (dcpssubscription_reader, DDS_ANY_STATE); + (void) dds_waitset_attach (waitset, dcpspublication_readcond, dcpspublication_reader); + (void) dds_waitset_attach (waitset, dcpssubscription_readcond, dcpssubscription_reader); const dds_time_t abstimeout = (timeout == DDS_INFINITY) ? DDS_NEVER : dds_time () + timeout; dds_return_t ret = DDS_RETCODE_OK; *xtypeobj = NULL; - while (*xtypeobj == NULL && dds_waitset_wait_until (waitset, NULL, 0, abstimeout) > 0) + struct ppc ppc; + ppc_init (&ppc); + dds_attach_t triggered_reader_x; + while (*xtypeobj == NULL && dds_waitset_wait_until (waitset, &triggered_reader_x, 1, abstimeout) > 0) { void *epraw = NULL; dds_sample_info_t si; - if (dds_take (dcpspublication_reader, &epraw, &si, 1, 1) <= 0) + dds_entity_t triggered_reader = (dds_entity_t) triggered_reader_x; + if (dds_take (triggered_reader, &epraw, &si, 1, 1) <= 0) continue; dds_builtintopic_endpoint_t *ep = epraw; const dds_typeinfo_t *typeinfo = NULL; @@ -77,27 +85,27 @@ static dds_return_t get_topic_and_typeobj (const char *topic_name, dds_duration_ if ((ret = dds_create_topic_descriptor(DDS_FIND_SCOPE_GLOBAL, participant, typeinfo, DDS_SECS (10), &descriptor)) < 0) { fprintf (stderr, "dds_create_topic_descriptor: %s\n", dds_strretcode (ret)); - dds_return_loan (dcpspublication_reader, &epraw, 1); + dds_return_loan (triggered_reader, &epraw, 1); goto error; } if ((*topic = dds_create_topic (participant, descriptor, ep->topic_name, ep->qos, NULL)) < 0) { fprintf (stderr, "dds_create_topic_descriptor: %s (be sure to enable topic discovery in the configuration)\n", dds_strretcode (*topic)); dds_delete_topic_descriptor (descriptor); - dds_return_loan (dcpspublication_reader, &epraw, 1); + dds_return_loan (triggered_reader, &epraw, 1); goto error; } dds_delete_topic_descriptor (descriptor); } // The topic suffices for creating a reader, but we also need the TypeObject to make sense of the data - if ((*xtypeobj = load_type_with_deps (participant, typeinfo)) == NULL) + if ((*xtypeobj = load_type_with_deps (participant, typeinfo, &ppc)) == NULL) { fprintf (stderr, "loading type with all dependencies failed\n"); - dds_return_loan (dcpspublication_reader, &epraw, 1); + dds_return_loan (triggered_reader, &epraw, 1); goto error; } } - dds_return_loan (dcpspublication_reader, &epraw, 1); + dds_return_loan (triggered_reader, &epraw, 1); } if (*xtypeobj) { @@ -128,6 +136,7 @@ static dds_return_t get_topic_and_typeobj (const char *topic_name, dds_duration_ } error: dds_delete (dcpspublication_reader); + dds_delete (dcpssubscription_reader); dds_delete (waitset); return (*xtypeobj != NULL) ? DDS_RETCODE_OK : DDS_RETCODE_TIMEOUT; } From 841cd253b6884bd592d58ee0986537ad34caf8e2 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 14 Jun 2024 07:34:20 +0200 Subject: [PATCH 138/207] dynsub example: fix printing of bitmasks It used to print ENUM instead of BITMASK for bitmask types. Signed-off-by: Erik Boasson --- examples/dynsub/print_type.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/dynsub/print_type.c b/examples/dynsub/print_type.c index e86085f9a4..373e0e5333 100644 --- a/examples/dynsub/print_type.c +++ b/examples/dynsub/print_type.c @@ -385,7 +385,7 @@ void ppc_print_to (struct ppc *ppc, const DDS_XTypes_CompleteTypeObject *typeobj } case DDS_XTypes_TK_BITMASK: { const DDS_XTypes_CompleteBitmaskType *x = &typeobj->_u.bitmask_type; - ppc_print (ppc, "ENUM typename=%s bit_bound=%"PRIu32" ", x->header.detail.type_name, x->header.common.bit_bound); + ppc_print (ppc, "BITMASK typename=%s bit_bound=%"PRIu32" ", x->header.detail.type_name, x->header.common.bit_bound); ppc_print_typeflags (ppc, x->bitmask_flags); ppc_print_typedetail_sans_name (ppc, &x->header.detail); ppc_print (ppc, "\n"); From 3adfa6c039ee2beae99f292797256c3b981bb0e6 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 14 Jun 2024 07:35:04 +0200 Subject: [PATCH 139/207] dynsub example: also print the minimal typeobject Signed-off-by: Erik Boasson --- examples/dynsub/dynsub.c | 12 +-- examples/dynsub/dynsub.h | 6 +- examples/dynsub/print_type.c | 146 ++++++++++++++++++++++++++++++++++- examples/dynsub/type_cache.c | 88 ++++++++++++++++++++- 4 files changed, 243 insertions(+), 9 deletions(-) diff --git a/examples/dynsub/dynsub.c b/examples/dynsub/dynsub.c index 97ec61b951..d6fe30a4e9 100644 --- a/examples/dynsub/dynsub.c +++ b/examples/dynsub/dynsub.c @@ -104,17 +104,17 @@ static dds_return_t get_topic_and_typeobj (const char *topic_name, dds_duration_ dds_return_loan (triggered_reader, &epraw, 1); goto error; } + if (load_type_with_deps_min (participant, typeinfo, &ppc) == NULL) + { + fprintf (stderr, "loading minimal type with all dependencies failed\n"); + dds_return_loan (triggered_reader, &epraw, 1); + goto error; + } } dds_return_loan (triggered_reader, &epraw, 1); } if (*xtypeobj) { - { - struct ppc ppc; - ppc_init (&ppc); - ppc_print_to (&ppc, &(*xtypeobj)->_u.complete); - } - // If we got the type object, populate the type cache size_t align, size; build_typecache_to (&(*xtypeobj)->_u.complete, &align, &size); diff --git a/examples/dynsub/dynsub.h b/examples/dynsub/dynsub.h index a36ea1b628..4cc6373955 100644 --- a/examples/dynsub/dynsub.h +++ b/examples/dynsub/dynsub.h @@ -54,11 +54,15 @@ void type_cache_free (void); struct type_hashid_map *lookup_hashid (const DDS_XTypes_EquivalenceHash hashid); const DDS_XTypes_CompleteTypeObject *get_complete_typeobj_for_hashid (const DDS_XTypes_EquivalenceHash hashid); +const DDS_XTypes_MinimalTypeObject *get_minimal_typeobj_for_hashid (const DDS_XTypes_EquivalenceHash hashid); void build_typecache_to (const DDS_XTypes_CompleteTypeObject *typeobj, size_t *align, size_t *size); -DDS_XTypes_TypeObject *load_type_with_deps (dds_entity_t participant, const dds_typeinfo_t *typeinfo); +DDS_XTypes_TypeObject *load_type_with_deps (dds_entity_t participant, const dds_typeinfo_t *typeinfo, struct ppc *ppc); +DDS_XTypes_TypeObject *load_type_with_deps_min (dds_entity_t participant, const dds_typeinfo_t *typeinfo, struct ppc *ppc); void ppc_init (struct ppc *ppc); +void ppc_print_ti (struct ppc *ppc, const DDS_XTypes_TypeIdentifier *typeid); void ppc_print_to (struct ppc *ppc, const DDS_XTypes_CompleteTypeObject *typeobj); +void ppc_print_to_min (struct ppc *ppc, const DDS_XTypes_MinimalTypeObject *typeobj); void print_sample (bool valid_data, const void *sample, const DDS_XTypes_CompleteTypeObject *typeobj); diff --git a/examples/dynsub/print_type.c b/examples/dynsub/print_type.c index 373e0e5333..fad78e590f 100644 --- a/examples/dynsub/print_type.c +++ b/examples/dynsub/print_type.c @@ -247,7 +247,7 @@ static bool ppc_print_simple (struct ppc *ppc, const uint8_t disc) return false; } -static void ppc_print_ti (struct ppc *ppc, const DDS_XTypes_TypeIdentifier *typeid) +void ppc_print_ti (struct ppc *ppc, const DDS_XTypes_TypeIdentifier *typeid) { if (ppc_print_simple (ppc, typeid->_d)) return; @@ -337,6 +337,22 @@ static void ppc_print_ti (struct ppc *ppc, const DDS_XTypes_TypeIdentifier *type ppc_outdent (ppc); break; } + case DDS_XTypes_EK_MINIMAL: { + ppc_print (ppc, "MINIMAL id="); + ppc_print_equivhash (ppc, typeid->_u.equivalence_hash); + ppc_indent (ppc); + struct type_hashid_map *info = lookup_hashid (typeid->_u.equivalence_hash); + if (info->lineno) + ppc_print (ppc, ": See line %d\n", info->lineno); + else + { + ppc_print (ppc, "\n"); + info->lineno = ppc_lineno (ppc); + ppc_print_to_min (ppc, get_minimal_typeobj_for_hashid (typeid->_u.equivalence_hash)); + } + ppc_outdent (ppc); + break; + } default: { printf ("type id discriminant %u encountered, sorry\n", (unsigned) typeid->_d); abort (); @@ -487,3 +503,131 @@ void ppc_print_to (struct ppc *ppc, const DDS_XTypes_CompleteTypeObject *typeobj } } } + +void ppc_print_to_min (struct ppc *ppc, const DDS_XTypes_MinimalTypeObject *typeobj) +{ + if (ppc_print_simple (ppc, typeobj->_d)) + return; + switch (typeobj->_d) + { + case DDS_XTypes_TK_ALIAS: { + const DDS_XTypes_MinimalAliasType *x = &typeobj->_u.alias_type; + ppc_print (ppc, "ALIAS "); + ppc_print_typeflags (ppc, x->alias_flags); + ppc_print (ppc, "\n"); + ppc_indent (ppc); + ppc_print_memberflags (ppc, x->body.common.related_flags); + ppc_print (ppc, "\n"); + ppc_print_ti (ppc, &x->body.common.related_type); + ppc_outdent (ppc); + break; + } + case DDS_XTypes_TK_ENUM: { + const DDS_XTypes_MinimalEnumeratedType *x = &typeobj->_u.enumerated_type; + ppc_print (ppc, "ENUM bit_bound=%"PRIu32" ", x->header.common.bit_bound); + ppc_print_typeflags (ppc, x->enum_flags); + ppc_print (ppc, "\n"); + ppc_indent (ppc); + for (uint32_t i = 0; i < x->literal_seq._length; i++) + { + const DDS_XTypes_MinimalEnumeratedLiteral *l = &x->literal_seq._buffer[i]; + ppc_print (ppc, "%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8" = %"PRId32" ", l->detail.name_hash[0], l->detail.name_hash[1], l->detail.name_hash[2], l->detail.name_hash[3], l->common.value); + ppc_print_memberflags (ppc, l->common.flags); + ppc_print (ppc, "\n"); + } + ppc_outdent (ppc); + break; + } + case DDS_XTypes_TK_BITMASK: { + const DDS_XTypes_MinimalBitmaskType *x = &typeobj->_u.bitmask_type; + ppc_print (ppc, "BITMASK bit_bound=%"PRIu32" ", x->header.common.bit_bound); + ppc_print_typeflags (ppc, x->bitmask_flags); + ppc_print (ppc, "\n"); + ppc_indent (ppc); + for (uint32_t i = 0; i < x->flag_seq._length; i++) + { + const DDS_XTypes_MinimalBitflag *l = &x->flag_seq._buffer[i]; + ppc_print (ppc, "%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8" = %"PRId32" ", l->detail.name_hash[0], l->detail.name_hash[1], l->detail.name_hash[2], l->detail.name_hash[3], l->common.position); + ppc_print_memberflags (ppc, l->common.flags); + ppc_print (ppc, "\n"); + } + ppc_outdent (ppc); + break; + } + case DDS_XTypes_TK_SEQUENCE: { + const DDS_XTypes_MinimalSequenceType *x = &typeobj->_u.sequence_type; + ppc_print (ppc, "SEQUENCE bound=%"PRIu32" ", x->header.common.bound); + ppc_print_typeflags (ppc, x->collection_flag); + ppc_print_memberflags (ppc, x->element.common.element_flags); + ppc_print (ppc, "\n"); + ppc_indent (ppc); + ppc_print_ti (ppc, &x->element.common.type); + ppc_outdent (ppc); + break; + } + case DDS_XTypes_TK_STRUCTURE: { + const DDS_XTypes_MinimalStructType *t = &typeobj->_u.struct_type; + ppc_print (ppc, "STRUCTURE "); + ppc_print_typeflags (ppc, t->struct_flags); + ppc_print (ppc, "\n"); + ppc_indent (ppc); + if (t->header.base_type._d != DDS_XTypes_TK_NONE) + { + ppc_print (ppc, "basetype=\n"); + ppc_indent (ppc); + ppc_print_ti (ppc, &t->header.base_type); + ppc_outdent (ppc); + } + for (uint32_t i = 0; i < t->member_seq._length; i++) + { + const DDS_XTypes_MinimalStructMember *m = &t->member_seq._buffer[i]; + ppc_print (ppc, "name_hash=%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8" ", m->detail.name_hash[0], m->detail.name_hash[1], m->detail.name_hash[2], m->detail.name_hash[3]); + ppc_print (ppc, "memberid=0x%"PRIx32" ", m->common.member_id); + ppc_print_memberflags (ppc, m->common.member_flags); + ppc_print (ppc, "\n"); + ppc_indent (ppc); + ppc_print_ti (ppc, &m->common.member_type_id); + ppc_outdent (ppc); + } + ppc_outdent (ppc); + break; + } + case DDS_XTypes_TK_UNION: { + const DDS_XTypes_MinimalUnionType *t = &typeobj->_u.union_type; + ppc_print (ppc, "UNION "); + ppc_print_typeflags (ppc, t->union_flags); + ppc_print (ppc, "\n"); + ppc_indent (ppc); + ppc_print (ppc, "discriminator="); + ppc_indent (ppc); + const DDS_XTypes_MinimalDiscriminatorMember *disc = &t->discriminator; + ppc_print_memberflags (ppc, disc->common.member_flags); + ppc_print (ppc, " "); + ppc_print_ti (ppc, &disc->common.type_id); + ppc_outdent (ppc); + for (uint32_t i = 0; i < t->member_seq._length; i++) + { + const DDS_XTypes_MinimalUnionMember *m = &t->member_seq._buffer[i]; + if (m->common.label_seq._length == 0) + ppc_print (ppc, "default:\n"); + for (uint32_t j = 0; j < m->common.label_seq._length; j++) + ppc_print (ppc, "case %"PRIu32":\n", m->common.label_seq._buffer[j]); + ppc_indent (ppc); + ppc_print (ppc, "name_hash=%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8" ", m->detail.name_hash[0], m->detail.name_hash[1], m->detail.name_hash[2], m->detail.name_hash[3]); + ppc_print (ppc, "memberid=0x%"PRIx32" ", m->common.member_id); + ppc_print_memberflags (ppc, m->common.member_flags); + ppc_print (ppc, "\n"); + ppc_indent (ppc); + ppc_print_ti (ppc, &m->common.type_id); + ppc_outdent (ppc); + ppc_outdent (ppc); + } + ppc_outdent (ppc); + break; + } + default: { + printf ("type object discriminant %u encountered, sorry\n", (unsigned) typeobj->_d); + abort (); + } + } +} diff --git a/examples/dynsub/type_cache.c b/examples/dynsub/type_cache.c index 43c3eca1fc..5612129ac5 100644 --- a/examples/dynsub/type_cache.c +++ b/examples/dynsub/type_cache.c @@ -187,6 +187,14 @@ const DDS_XTypes_CompleteTypeObject *get_complete_typeobj_for_hashid (const DDS_ return &info->typeobj->_u.complete; } +const DDS_XTypes_MinimalTypeObject *get_minimal_typeobj_for_hashid (const DDS_XTypes_EquivalenceHash hashid) +{ + struct type_hashid_map *info; + if ((info = lookup_hashid (hashid)) == NULL) + abort (); + return &info->typeobj->_u.minimal; +} + static void build_typecache_ti (const DDS_XTypes_TypeIdentifier *typeid, size_t *align, size_t *size) { if (build_typecache_simple (typeid->_d, align, size)) @@ -447,6 +455,7 @@ static bool load_deps_simple (uint8_t disc) } static bool load_deps_to (dds_entity_t participant, const DDS_XTypes_CompleteTypeObject *typeobj); +static bool load_deps_to_min (dds_entity_t participant, const DDS_XTypes_MinimalTypeObject *typeobj); static bool load_deps_ti (dds_entity_t participant, const DDS_XTypes_TypeIdentifier *typeid) { @@ -485,6 +494,26 @@ static bool load_deps_ti (dds_entity_t participant, const DDS_XTypes_TypeIdentif return load_deps_to (participant, &xtypeobj->_u.complete); } } + case DDS_XTypes_EK_MINIMAL: { + struct type_hashid_map templ, *info; + memcpy (templ.id, typeid->_u.equivalence_hash, sizeof (templ.id)); + if (type_hashid_map_lookup (&templ) != NULL) + return true; + else + { + dds_typeobj_t *typeobj; + if (dds_get_typeobj (participant, (const dds_typeid_t *) typeid, 0, &typeobj) < 0) + return load_deps_failed (); + DDS_XTypes_TypeObject * const xtypeobj = (DDS_XTypes_TypeObject *) typeobj; + info = malloc (sizeof (*info)); + assert (info); + memcpy (info->id, typeid->_u.equivalence_hash, sizeof (info->id)); + info->typeobj = xtypeobj; + info->lineno = 0; + type_hashid_map_add (info); + return load_deps_to_min (participant, &xtypeobj->_u.minimal); + } + } default: { printf ("type id discriminant %u encountered, sorry\n", (unsigned) typeid->_d); abort (); @@ -534,7 +563,48 @@ static bool load_deps_to (dds_entity_t participant, const DDS_XTypes_CompleteTyp } } -DDS_XTypes_TypeObject *load_type_with_deps (dds_entity_t participant, const dds_typeinfo_t *typeinfo) +static bool load_deps_to_min (dds_entity_t participant, const DDS_XTypes_MinimalTypeObject *typeobj) +{ + if (load_deps_simple (typeobj->_d)) + return true; + switch (typeobj->_d) + { + case DDS_XTypes_TK_ALIAS: + return load_deps_ti (participant, &typeobj->_u.alias_type.body.common.related_type); + case DDS_XTypes_TK_ENUM: + case DDS_XTypes_TK_BITMASK: + return true; + case DDS_XTypes_TK_SEQUENCE: + return load_deps_ti (participant, &typeobj->_u.sequence_type.element.common.type); + case DDS_XTypes_TK_STRUCTURE: { + const DDS_XTypes_MinimalStructType *t = &typeobj->_u.struct_type; + if (!load_deps_ti (participant, &t->header.base_type)) + return load_deps_failed (); + for (uint32_t i = 0; i < t->member_seq._length; i++) { + if (!load_deps_ti (participant, &t->member_seq._buffer[i].common.member_type_id)) + return load_deps_failed (); + } + return true; + } + case DDS_XTypes_TK_UNION: { + const DDS_XTypes_MinimalUnionType *t = &typeobj->_u.union_type; + if (!load_deps_ti (participant, &t->discriminator.common.type_id)) + return load_deps_failed (); + for (uint32_t i = 0; i < t->member_seq._length; i++) { + if (!load_deps_ti (participant, &t->member_seq._buffer[i].common.type_id)) + return load_deps_failed (); + } + return true; + } + default: { + printf ("type object discriminant %u encountered, sorry\n", (unsigned) typeobj->_d); + abort (); + return load_deps_failed (); + } + } +} + +DDS_XTypes_TypeObject *load_type_with_deps (dds_entity_t participant, const dds_typeinfo_t *typeinfo, struct ppc *ppc) { DDS_XTypes_TypeInformation const * const xtypeinfo = (DDS_XTypes_TypeInformation *) typeinfo; if (!load_deps_ti (participant, &xtypeinfo->complete.typeid_with_size.type_id)) @@ -543,5 +613,21 @@ DDS_XTypes_TypeObject *load_type_with_deps (dds_entity_t participant, const dds_ memcpy (templ.id, &xtypeinfo->complete.typeid_with_size.type_id._u.equivalence_hash, sizeof (templ.id)); if ((info = type_hashid_map_lookup (&templ)) == NULL) return NULL; + if (ppc) + ppc_print_ti (ppc, &xtypeinfo->complete.typeid_with_size.type_id); + return (DDS_XTypes_TypeObject *) info->typeobj; +} + +DDS_XTypes_TypeObject *load_type_with_deps_min (dds_entity_t participant, const dds_typeinfo_t *typeinfo, struct ppc *ppc) +{ + DDS_XTypes_TypeInformation const * const xtypeinfo = (DDS_XTypes_TypeInformation *) typeinfo; + if (!load_deps_ti (participant, &xtypeinfo->minimal.typeid_with_size.type_id)) + return NULL; + struct type_hashid_map templ, *info; + memcpy (templ.id, &xtypeinfo->minimal.typeid_with_size.type_id._u.equivalence_hash, sizeof (templ.id)); + if ((info = type_hashid_map_lookup (&templ)) == NULL) + return NULL; + if (ppc) + ppc_print_ti (ppc, &xtypeinfo->minimal.typeid_with_size.type_id); return (DDS_XTypes_TypeObject *) info->typeobj; } From f0324c428ab103fe743d15734ea2e19fca068536 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 17 Jun 2024 10:36:02 +0200 Subject: [PATCH 140/207] dynsub example: support for arrays Signed-off-by: Erik Boasson --- examples/dynsub/print_sample.c | 80 ++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 22 deletions(-) diff --git a/examples/dynsub/print_sample.c b/examples/dynsub/print_sample.c index 8b0600d75c..4317977c83 100644 --- a/examples/dynsub/print_sample.c +++ b/examples/dynsub/print_sample.c @@ -75,14 +75,16 @@ static bool print_sample1_simple (const unsigned char *sample, const uint8_t dis static const char *get_string_pointer (const unsigned char *sample, const DDS_XTypes_TypeIdentifier *typeid, struct context *c) { - bool bounded; + uint32_t bound; if (typeid->_d == DDS_XTypes_TI_STRING8_SMALL) - bounded = typeid->_u.string_sdefn.bound != 0; + bound = typeid->_u.string_sdefn.bound; else - bounded = typeid->_u.string_ldefn.bound != 0; + bound = typeid->_u.string_ldefn.bound; // must always call align for its side effects - if (bounded) - return align (sample, c, _Alignof (char), sizeof (char)); + if (bound != 0) + { + return align (sample, c, _Alignof (char), bound + 1); + } else { // if not "valid_data" and not a key field, this'll be a null pointer @@ -90,7 +92,7 @@ static const char *get_string_pointer (const unsigned char *sample, const DDS_XT } } -static void print_sample1_ti (const unsigned char *sample, const DDS_XTypes_TypeIdentifier *typeid, struct context *c, const char *sep, const char *label, bool is_base_type) +static void print_sample1_ti (const unsigned char *sample, const DDS_XTypes_TypeIdentifier *typeid, uint32_t rank, struct context *c, const char *sep, const char *label, bool is_base_type) { if (print_sample1_simple (sample, typeid->_d, c, sep, label, NULL)) return; @@ -120,13 +122,45 @@ static void print_sample1_ti (const unsigned char *sample, const DDS_XTypes_Type sep = ""; for (uint32_t i = 0; i < p->_length; i++) { - print_sample1_ti (p->_buffer, et, &c1, sep, NULL, false); + print_sample1_ti (p->_buffer, et, 0, &c1, sep, NULL, false); sep = ","; } printf ("]"); } break; } + case DDS_XTypes_TI_PLAIN_ARRAY_SMALL: + case DDS_XTypes_TI_PLAIN_ARRAY_LARGE: { + const DDS_XTypes_TypeIdentifier *et; + uint32_t m, n; + if (typeid->_d == DDS_XTypes_TI_PLAIN_ARRAY_SMALL) { + et = typeid->_u.array_sdefn.element_identifier; + m = typeid->_u.array_sdefn.array_bound_seq._length; + n = typeid->_u.array_sdefn.array_bound_seq._buffer[rank]; + } else { + et = typeid->_u.array_ldefn.element_identifier; + m = typeid->_u.array_ldefn.array_bound_seq._length; + n = typeid->_u.array_ldefn.array_bound_seq._buffer[rank]; + } + if (c->key || c->valid_data) { + printf ("%s", sep); + if (label) printf ("\"%s\":", label); + printf ("["); + } + sep = ""; + for (uint32_t i = 0; i < n; i++) + { + if (rank + 1 < m) + print_sample1_ti (sample, typeid, rank + 1, c, "", NULL, is_base_type); + else + print_sample1_ti (sample, et, 0, c, sep, NULL, is_base_type); + sep = ","; + } + if (c->key || c->valid_data) { + printf ("]"); + } + break; + } case DDS_XTypes_EK_COMPLETE: { struct typeinfo templ = { .key = { .key = (uintptr_t) typeid } }, *info = type_cache_lookup (&templ); print_sample1_to (sample, info->typeobj, c, sep, label, is_base_type); @@ -142,7 +176,7 @@ static void print_sample1_to (const unsigned char *sample, const DDS_XTypes_Comp switch (typeobj->_d) { case DDS_XTypes_TK_ALIAS: { - print_sample1_ti (sample, &typeobj->_u.alias_type.body.common.related_type, c, sep, label, false); + print_sample1_ti (sample, &typeobj->_u.alias_type.body.common.related_type, 0, c, sep, label, false); break; } case DDS_XTypes_TK_SEQUENCE: { @@ -155,7 +189,7 @@ static void print_sample1_to (const unsigned char *sample, const DDS_XTypes_Comp sep = ""; for (uint32_t i = 0; i < p->_length; i++) { - print_sample1_ti ((const unsigned char *) p->_buffer, et, &c1, sep, NULL, false); + print_sample1_ti ((const unsigned char *) p->_buffer, et, 0, &c1, sep, NULL, false); sep = ","; if (c1.offset % c1.maxalign) c1.offset += c1.maxalign - (c1.offset % c1.maxalign); @@ -174,25 +208,27 @@ static void print_sample1_to (const unsigned char *sample, const DDS_XTypes_Comp sep = ""; if (t->header.base_type._d != DDS_XTypes_TK_NONE) { - print_sample1_ti (p, &t->header.base_type, &c1, sep, NULL, true); + print_sample1_ti (p, &t->header.base_type, 0, &c1, sep, NULL, true); sep = ","; } for (uint32_t i = 0; i < t->member_seq._length; i++) { const DDS_XTypes_CompleteStructMember *m = &t->member_seq._buffer[i]; - if (m->common.member_flags & DDS_XTypes_IS_OPTIONAL) { + if (!(m->common.member_flags & DDS_XTypes_IS_OPTIONAL)) { + c1.key = c->key && m->common.member_flags & DDS_XTypes_IS_KEY; + print_sample1_ti (p, &m->common.member_type_id, 0, &c1, sep, *m->detail.name ? m->detail.name : NULL, false); + } else { void const * const *p1 = (const void *) align (p, &c1, _Alignof (void *), sizeof (void *)); - if (*p1 == NULL) { - printf ("%s", sep); - if (*m->detail.name) printf ("\"%s\":", m->detail.name); - printf ("(nothing)"); - } else { - struct context c2 = { .valid_data = c->valid_data, .key = false, .offset = 0, .maxalign = 1 }; - print_sample1_ti (*p1, &m->common.member_type_id, &c2, sep, *m->detail.name ? m->detail.name : NULL, false); + if (c->valid_data) { // optional is never a key + if (*p1 == NULL) { + printf ("%s", sep); + if (*m->detail.name) printf ("\"%s\":", m->detail.name); + printf ("(nothing)"); + } else { + struct context c2 = { .valid_data = c->valid_data, .key = false, .offset = 0, .maxalign = 1 }; + print_sample1_ti (*p1, &m->common.member_type_id, 0, &c2, sep, *m->detail.name ? m->detail.name : NULL, false); + } } - } else { - c1.key = c->key && m->common.member_flags & DDS_XTypes_IS_KEY; - print_sample1_ti (p, &m->common.member_type_id, &c1, sep, *m->detail.name ? m->detail.name : NULL, false); } sep = ","; } @@ -245,7 +281,7 @@ static void print_sample1_to (const unsigned char *sample, const DDS_XTypes_Comp for (uint32_t l = 0; l < m->common.label_seq._length; l++) { if (m->common.label_seq._buffer[l] == disc_value) - print_sample1_ti (p, &m->common.type_id, &c1, sep, *m->detail.name ? m->detail.name : NULL, false); + print_sample1_ti (p, &m->common.type_id, 0, &c1, sep, *m->detail.name ? m->detail.name : NULL, false); } } printf ("}"); From 00c63c342c2d858bf94b6a602dcf8bd696fdbe26 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Mon, 17 Jun 2024 12:54:57 +0200 Subject: [PATCH 141/207] Export sysdef parser functions Adding export macros to the system definition parser initialization and finalize functions. Signed-off-by: Dennis Potman --- src/core/ddsc/src/dds__sysdef_parser.h | 11 ++++++----- src/core/xtests/symbol_export/symbol_export.c | 8 ++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/core/ddsc/src/dds__sysdef_parser.h b/src/core/ddsc/src/dds__sysdef_parser.h index e726979f27..74ed613bfe 100644 --- a/src/core/ddsc/src/dds__sysdef_parser.h +++ b/src/core/ddsc/src/dds__sysdef_parser.h @@ -12,6 +12,7 @@ #include "dds/ddsrt/log.h" #include "dds/ddsrt/retcode.h" +#include "dds/export.h" #if defined (__cplusplus) extern "C" { @@ -85,7 +86,7 @@ struct dds_sysdef_type_metadata_admin; * * @return a DDS return code */ -dds_return_t dds_sysdef_init_sysdef (FILE *fp, struct dds_sysdef_system **sysdef, uint32_t lib_scope); +DDS_EXPORT_INTERNAL_FUNCTION dds_return_t dds_sysdef_init_sysdef (FILE *fp, struct dds_sysdef_system **sysdef, uint32_t lib_scope); /** * @brief Initialize System definition from `xml` string. @@ -100,7 +101,7 @@ dds_return_t dds_sysdef_init_sysdef (FILE *fp, struct dds_sysdef_system **sysdef * * @return a DDS return code */ -dds_return_t dds_sysdef_init_sysdef_str (const char *raw, struct dds_sysdef_system **sysdef, uint32_t lib_scope); +DDS_EXPORT_INTERNAL_FUNCTION dds_return_t dds_sysdef_init_sysdef_str (const char *raw, struct dds_sysdef_system **sysdef, uint32_t lib_scope); /** * @brief Finalize System definition. @@ -112,7 +113,7 @@ dds_return_t dds_sysdef_init_sysdef_str (const char *raw, struct dds_sysdef_syst * @param[in] sysdef - Pointer to dds_sysdef_system structure. * */ -void dds_sysdef_fini_sysdef (struct dds_sysdef_system *sysdef); +DDS_EXPORT_INTERNAL_FUNCTION void dds_sysdef_fini_sysdef (struct dds_sysdef_system *sysdef); /** * @brief Initialize System definition for data types. @@ -126,7 +127,7 @@ void dds_sysdef_fini_sysdef (struct dds_sysdef_system *sysdef); * * @return a DDS return code */ -dds_return_t dds_sysdef_init_data_types (FILE *fp, struct dds_sysdef_type_metadata_admin **type_meta_data); +DDS_EXPORT_INTERNAL_FUNCTION dds_return_t dds_sysdef_init_data_types (FILE *fp, struct dds_sysdef_type_metadata_admin **type_meta_data); /** * @brief Finalize System definition for data types. @@ -138,7 +139,7 @@ dds_return_t dds_sysdef_init_data_types (FILE *fp, struct dds_sysdef_type_metada * @param[in,out] type_meta_data - Pointer dds_sysdef_type_metadata_admin structure. * */ -void dds_sysdef_fini_data_types (struct dds_sysdef_type_metadata_admin *type_meta_data); +DDS_EXPORT_INTERNAL_FUNCTION void dds_sysdef_fini_data_types (struct dds_sysdef_type_metadata_admin *type_meta_data); #if defined (__cplusplus) } diff --git a/src/core/xtests/symbol_export/symbol_export.c b/src/core/xtests/symbol_export/symbol_export.c index 2b8e107c79..ea8cbc4dc5 100644 --- a/src/core/xtests/symbol_export/symbol_export.c +++ b/src/core/xtests/symbol_export/symbol_export.c @@ -92,6 +92,7 @@ #include "dds__write.h" #include "dds__entity.h" +#include "dds__sysdef_parser.h" DDSRT_WARNING_DEPRECATED_OFF DDSRT_WARNING_GNUC_OFF (unused-result) @@ -1169,6 +1170,13 @@ int main (int argc, char **argv) dds_entity_lock (0, 0, ptr); dds_entity_unlock (ptr); + // dds__sysdef_parser.h + dds_sysdef_init_sysdef (ptr, ptr2, 0); + dds_sysdef_init_sysdef_str (ptr, ptr2, 0); + dds_sysdef_fini_sysdef (ptr); + dds_sysdef_init_data_types (ptr, ptr2); + dds_sysdef_fini_data_types (ptr); + return 0; } From d5b2a48239647d6e8c139d51c87c6b81d0e4eea6 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 17 Jun 2024 15:52:20 +0200 Subject: [PATCH 142/207] Trace reason for declaring types non-assignable This records some information during assignability checking why a pair of types is considered non-assignable and adds this information to the trace. One still needs to correlate the type ids with the actual type definitions in most cases, but in many cases even this little bit of information will probably help. involved in the rejection), but that is not Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi__typewrap.h | 45 ++++- src/core/ddsi/src/ddsi_typelib.c | 44 ++++- src/core/ddsi/src/ddsi_typewrap.c | 305 +++++++++++++++++++---------- 3 files changed, 281 insertions(+), 113 deletions(-) diff --git a/src/core/ddsi/src/ddsi__typewrap.h b/src/core/ddsi/src/ddsi__typewrap.h index 40099d16d1..c7738f5bcd 100644 --- a/src/core/ddsi/src/ddsi__typewrap.h +++ b/src/core/ddsi/src/ddsi__typewrap.h @@ -66,22 +66,55 @@ void ddsi_xt_get_typeobject (const struct xt_type *xt, ddsi_typeobj_t *to); void ddsi_xt_type_fini (struct ddsi_domaingv *gv, struct xt_type *xt, bool include_typeid); /** @component xtypes_wrapper */ -bool ddsi_xt_is_assignable_from (struct ddsi_domaingv *gv, const struct xt_type *rd_xt, const struct xt_type *wr_xt, const dds_type_consistency_enforcement_qospolicy_t *tce); + +enum ddsi_non_assignability_code { + DDSI_NONASSIGN_ASSIGNABLE, + DDSI_NONASSIGN_TYPE_UNRESOLVED, + DDSI_NONASSIGN_INCOMPATIBLE_TYPE, + DDSI_NONASSIGN_DIFFERENT_EXTENSIBILITY, + DDSI_NONASSIGN_WR_TYPE_NOT_DELIMITED, + DDSI_NONASSIGN_NAME_HASH_DIFFERS, + DDSI_NONASSIGN_MISSING_CASE, + DDSI_NONASSIGN_NUMBER_OF_MEMBERS, + DDSI_NONASSIGN_KEY_DIFFERS, + DDSI_NONASSIGN_NO_OVERLAP, + DDSI_NONASSIGN_STRUCT_MUST_UNDERSTAND, + DDSI_NONASSIGN_STRUCT_OPTIONAL, + DDSI_NONASSIGN_STRUCT_MEMBER_MISMATCH, + DDSI_NONASSIGN_KEY_INCOMPATIBLE, + DDSI_NONASSIGN_BOUND, + DDSI_NONASSIGN_UNKNOWN +}; + +struct ddsi_non_assignability_reason { + enum ddsi_non_assignability_code code; + const struct xt_type *t1; + const struct xt_type *t2; + uint32_t id; +}; + +bool ddsi_xt_is_assignable_from (struct ddsi_domaingv *gv, const struct xt_type *rd_xt, const struct xt_type *wr_xt, const dds_type_consistency_enforcement_qospolicy_t *tce, struct ddsi_non_assignability_reason *reason) + ddsrt_nonnull_all; /** @component xtypes_wrapper */ -dds_return_t ddsi_xt_validate (struct ddsi_domaingv *gv, const struct xt_type *t); +dds_return_t ddsi_xt_validate (struct ddsi_domaingv *gv, const struct xt_type *t) + ddsrt_nonnull_all; /** @component xtypes_wrapper */ -bool ddsi_xt_is_unresolved (const struct xt_type *t); +bool ddsi_xt_is_unresolved (const struct xt_type *t) + ddsrt_nonnull_all; /** @component xtypes_wrapper */ -bool ddsi_xt_is_resolved (const struct xt_type *t); +bool ddsi_xt_is_resolved (const struct xt_type *t) + ddsrt_nonnull_all; /** @component xtypes_wrapper */ -void ddsi_xt_copy (struct ddsi_domaingv *gv, struct xt_type *dst, const struct xt_type *src); +void ddsi_xt_copy (struct ddsi_domaingv *gv, struct xt_type *dst, const struct xt_type *src) + ddsrt_nonnull_all; /** @component xtypes_wrapper */ -void ddsi_xt_get_namehash (DDS_XTypes_NameHash name_hash, const char *name); +void ddsi_xt_get_namehash (DDS_XTypes_NameHash name_hash, const char *name) + ddsrt_nonnull_all; #if defined (__cplusplus) } diff --git a/src/core/ddsi/src/ddsi_typelib.c b/src/core/ddsi/src/ddsi_typelib.c index 7a6c1c7e63..ac3e4df3c0 100644 --- a/src/core/ddsi/src/ddsi_typelib.c +++ b/src/core/ddsi/src/ddsi_typelib.c @@ -1377,6 +1377,31 @@ bool ddsi_type_resolved (struct ddsi_domaingv *gv, const struct ddsi_type *type, return ret; } +static const char *ddsi_non_assignability_code_str (enum ddsi_non_assignability_code code) +{ + switch (code) + { + case DDSI_NONASSIGN_ASSIGNABLE: assert (0); break; + case DDSI_NONASSIGN_TYPE_UNRESOLVED: return "type unresolved"; + case DDSI_NONASSIGN_INCOMPATIBLE_TYPE: return "incompatible type"; + case DDSI_NONASSIGN_DIFFERENT_EXTENSIBILITY: return "different extensibility"; + case DDSI_NONASSIGN_WR_TYPE_NOT_DELIMITED: return "wr type not delimited"; + case DDSI_NONASSIGN_NAME_HASH_DIFFERS: return "name hash differs"; + case DDSI_NONASSIGN_MISSING_CASE: return "missing case/enum label"; + case DDSI_NONASSIGN_NUMBER_OF_MEMBERS: return "number of members/enum labels"; + case DDSI_NONASSIGN_KEY_DIFFERS: return "key annotation differs"; + case DDSI_NONASSIGN_NO_OVERLAP: return "no common members/labels"; + case DDSI_NONASSIGN_STRUCT_MUST_UNDERSTAND: return "must understand mismatch"; + case DDSI_NONASSIGN_STRUCT_OPTIONAL: return "optional mismatch"; + case DDSI_NONASSIGN_STRUCT_MEMBER_MISMATCH: return "member mismatch"; + case DDSI_NONASSIGN_KEY_INCOMPATIBLE: return "key incompatible"; + case DDSI_NONASSIGN_BOUND: return "incompatible bound"; + case DDSI_NONASSIGN_UNKNOWN: return "unknown"; + } + return "(invalid code)"; +}; + + bool ddsi_is_assignable_from (struct ddsi_domaingv *gv, const struct ddsi_type_pair *rd_type_pair, uint32_t rd_resolved, const struct ddsi_type_pair *wr_type_pair, uint32_t wr_resolved, const dds_type_consistency_enforcement_qospolicy_t *tce) { if (!rd_type_pair || !wr_type_pair) @@ -1385,8 +1410,25 @@ bool ddsi_is_assignable_from (struct ddsi_domaingv *gv, const struct ddsi_type_p const struct xt_type *rd_xt = (rd_resolved == DDS_XTypes_EK_BOTH || rd_resolved == DDS_XTypes_EK_MINIMAL) ? &rd_type_pair->minimal->xt : &rd_type_pair->complete->xt, *wr_xt = (wr_resolved == DDS_XTypes_EK_BOTH || wr_resolved == DDS_XTypes_EK_MINIMAL) ? &wr_type_pair->minimal->xt : &wr_type_pair->complete->xt; - bool assignable = ddsi_xt_is_assignable_from (gv, rd_xt, wr_xt, tce); + struct ddsi_non_assignability_reason reason; + bool assignable = ddsi_xt_is_assignable_from (gv, rd_xt, wr_xt, tce, &reason); ddsrt_mutex_unlock (&gv->typelib_lock); + + if (!assignable) + { + struct ddsi_typeid_str trdstr, twrstr; + struct ddsi_typeid_str t1str, t2str; + // not supposed to perform an assignability check while there are still unresolved types involved + const uint32_t lc_cat = DDS_LC_DISCOVERY | (reason.code == DDSI_NONASSIGN_TYPE_UNRESOLVED ? DDS_LC_WARNING : 0); + GVLOG (lc_cat, "assignability check failed: rd type %s wr type %s, t1=%s (%s) t2=%s (%s) id %"PRIu32": %s\n", + ddsi_make_typeid_str (&trdstr, &rd_xt->id), + ddsi_make_typeid_str (&twrstr, &wr_xt->id), + reason.t1 ? ddsi_make_typeid_str (&t1str, &reason.t1->id) : "(none)", + reason.t1 ? ddsi_typekind_descr (reason.t1->_d) : "", + reason.t2 ? ddsi_make_typeid_str (&t2str, &reason.t2->id) : "(none)", + reason.t2 ? ddsi_typekind_descr (reason.t2->_d) : "", + reason.id, ddsi_non_assignability_code_str (reason.code)); + } return assignable; } diff --git a/src/core/ddsi/src/ddsi_typewrap.c b/src/core/ddsi/src/ddsi_typewrap.c index 9dc842168f..cc7bd39f7b 100644 --- a/src/core/ddsi/src/ddsi_typewrap.c +++ b/src/core/ddsi/src/ddsi_typewrap.c @@ -1968,6 +1968,7 @@ static void xt_bitflag_seq_copy (struct xt_bitflag_seq *dst, const struct xt_bit } } +ddsrt_nonnull_all void ddsi_xt_copy (struct ddsi_domaingv *gv, struct xt_type *dst, const struct xt_type *src) { if (!ddsi_typeid_is_none (&src->id)) @@ -2045,6 +2046,7 @@ void ddsi_xt_copy (struct ddsi_domaingv *gv, struct xt_type *dst, const struct x } } +ddsrt_nonnull_all ddsrt_attribute_returns_nonnull static struct xt_type * xt_dup (struct ddsi_domaingv *gv, const struct xt_type *src) { struct xt_type *dst = ddsrt_calloc (1, sizeof (*dst)); @@ -2052,24 +2054,44 @@ static struct xt_type * xt_dup (struct ddsi_domaingv *gv, const struct xt_type * return dst; } +ddsrt_nonnull_all static bool xt_has_basetype (const struct xt_type *t) { assert (t->_d == DDS_XTypes_TK_STRUCTURE); return t->_u.structure.base_type != NULL; } -static struct xt_type *xt_expand_basetype (struct ddsi_domaingv *gv, const struct xt_type *t) +ddsrt_nonnull ((1, 3)) +static bool xt_non_assignable (struct ddsi_non_assignability_reason *reason, enum ddsi_non_assignability_code code, const struct xt_type *t1, const struct xt_type *t2, uint32_t id) +{ + reason->code = code; + reason->id = id; + reason->t1 = t1; + reason->t2 = t2; + return false; +} + +ddsrt_nonnull ((1, 2)) +static bool xt_is_assignable_check_resolved (const struct xt_type *t, struct ddsi_non_assignability_reason *reason, const struct xt_type *basetype, uint32_t id) +{ + assert (basetype == NULL || ddsi_xt_is_resolved (basetype)); + if (ddsi_xt_is_resolved (t)) + return true; + if (basetype) + return xt_non_assignable (reason, DDSI_NONASSIGN_TYPE_UNRESOLVED, basetype, t, id); + else + return xt_non_assignable (reason, DDSI_NONASSIGN_TYPE_UNRESOLVED, t, NULL, id); +} + +ddsrt_nonnull_all +static struct xt_type *xt_expand_basetype (struct ddsi_domaingv *gv, const struct xt_type *t, struct ddsi_non_assignability_reason *reason) { assert (t->_d == DDS_XTypes_TK_STRUCTURE); assert (t->_u.structure.base_type); const struct xt_type *b = ddsi_xt_unalias (&t->_u.structure.base_type->xt); - if (ddsi_xt_is_unresolved (b)) - { - struct ddsi_typeid_str tidstr; - GVWARNING ("assignability check: base type %s unresolved in xt_expand_basetype\n", ddsi_make_typeid_str (&tidstr, &b->id)); + if (!xt_is_assignable_check_resolved (b, reason, t, 0)) return NULL; - } - struct xt_type *te = xt_has_basetype (b) ? xt_expand_basetype (gv, b) : xt_dup (gv, t); + struct xt_type *te = xt_has_basetype (b) ? xt_expand_basetype (gv, b, reason) : xt_dup (gv, t); if (!te) return NULL; struct xt_struct_member_seq *ms = &te->_u.structure.members; @@ -2318,12 +2340,18 @@ static bool xt_is_equivalent_minimal (const struct xt_type *t1, const struct xt_ return false; } -static bool xt_is_strongly_assignable_from (struct ddsi_domaingv *gv, const struct xt_type *t1a, const struct xt_type *t2a, const dds_type_consistency_enforcement_qospolicy_t *tce) +ddsrt_nonnull_all +static bool xt_is_assignable_from_impl (struct ddsi_domaingv *gv, const struct xt_type *rd_xt, const struct xt_type *wr_xt, const dds_type_consistency_enforcement_qospolicy_t *tce, struct ddsi_non_assignability_reason *reason); + +ddsrt_nonnull_all +static bool xt_is_strongly_assignable_from (struct ddsi_domaingv *gv, const struct xt_type *t1a, const struct xt_type *t2a, const dds_type_consistency_enforcement_qospolicy_t *tce, struct ddsi_non_assignability_reason *reason) { const struct xt_type *t1 = ddsi_xt_unalias (t1a), *t2 = ddsi_xt_unalias (t2a); if (xt_is_equivalent_minimal (t1, t2)) return true; - return xt_is_delimited (gv, t2) && ddsi_xt_is_assignable_from (gv, t1, t2, tce); + if (xt_is_delimited (gv, t2)) + return xt_is_assignable_from_impl (gv, t1, t2, tce, reason); + return xt_non_assignable (reason, DDSI_NONASSIGN_WR_TYPE_NOT_DELIMITED, t1, t2, 0); } static bool xt_bounds_eq (const struct DDS_XTypes_LBoundSeq *a, const struct DDS_XTypes_LBoundSeq *b) @@ -2335,11 +2363,13 @@ static bool xt_bounds_eq (const struct DDS_XTypes_LBoundSeq *a, const struct DDS return !memcmp (a->_buffer, b->_buffer, a->_length * sizeof (*a->_buffer)); } +ddsrt_nonnull_all static bool xt_namehash_eq (const DDS_XTypes_NameHash *n1, const DDS_XTypes_NameHash *n2) { return !memcmp (n1, n2, sizeof (*n1)); } +ddsrt_nonnull_all static bool xt_union_label_selects (const struct DDS_XTypes_UnionCaseLabelSeq *ls1, const struct DDS_XTypes_UnionCaseLabelSeq *ls2) { /* UnionCaseLabelSeq is ordered by value (as noted in typeobject idl) */ @@ -2356,6 +2386,7 @@ static bool xt_union_label_selects (const struct DDS_XTypes_UnionCaseLabelSeq *l return false; } +ddsrt_nonnull_all static bool xt_union_labels_match (const struct DDS_XTypes_UnionCaseLabelSeq *ls1, const struct DDS_XTypes_UnionCaseLabelSeq *ls2) { /* UnionCaseLabelSeq is ordered by value (as noted in typeobject idl) */ @@ -2365,13 +2396,14 @@ static bool xt_union_labels_match (const struct DDS_XTypes_UnionCaseLabelSeq *ls return true; } -static bool xt_is_assignable_from_enum (const struct xt_type *t1, const struct xt_type *t2) +ddsrt_nonnull_all +static bool xt_is_assignable_from_enum (const struct xt_type *t1, const struct xt_type *t2, struct ddsi_non_assignability_reason *reason) { assert (t1->_d == DDS_XTypes_TK_ENUM); assert (t2->_d == DDS_XTypes_TK_ENUM); // Note: extensibility flags not defined, see https://issues.omg.org/issues/DDSXTY14-24 if (xt_get_extensibility (t1) != xt_get_extensibility (t2)) - return false; + return xt_non_assignable (reason, DDSI_NONASSIGN_DIFFERENT_EXTENSIBILITY, t1, t2, 0); /* Members are ordered by increasing value (XTypes 1.3 spec 7.3.4.5) */ uint32_t i1 = 0, i2 = 0, i1_max = t1->_u.enum_type.literals.length, i2_max = t2->_u.enum_type.literals.length; while (i1 < i1_max && i2 < i2_max) @@ -2381,34 +2413,35 @@ static bool xt_is_assignable_from_enum (const struct xt_type *t1, const struct x { /* FIXME: implement @ignore_literal_names */ if (!xt_namehash_eq (&l1->detail.name_hash, &l2->detail.name_hash)) - return false; + return xt_non_assignable (reason, DDSI_NONASSIGN_NAME_HASH_DIFFERS, t1, t2, (uint32_t) l1->value); i1++; i2++; } else if (xt_get_extensibility (t1) == DDS_XTypes_IS_FINAL) - return false; + return xt_non_assignable (reason, DDSI_NONASSIGN_MISSING_CASE, t1, t2, (uint32_t) l1->value); else if (l1->value < l2->value) i1++; else i2++; } if ((i1 != i1_max || i2 != i2_max) && xt_get_extensibility (t1) == DDS_XTypes_IS_FINAL) - return false; + return xt_non_assignable (reason, DDSI_NONASSIGN_NUMBER_OF_MEMBERS, t1, t2, 0); return true; } -static bool xt_is_assignable_from_union (struct ddsi_domaingv *gv, const struct xt_type *t1, const struct xt_type *t2, const dds_type_consistency_enforcement_qospolicy_t *tce) +ddsrt_nonnull_all +static bool xt_is_assignable_from_union (struct ddsi_domaingv *gv, const struct xt_type *t1, const struct xt_type *t2, const dds_type_consistency_enforcement_qospolicy_t *tce, struct ddsi_non_assignability_reason *reason) { assert (t1->_d == DDS_XTypes_TK_UNION); assert (t2->_d == DDS_XTypes_TK_UNION); if (xt_get_extensibility (t1) != xt_get_extensibility (t2)) - return false; - if (!xt_is_strongly_assignable_from (gv, ddsi_xt_unalias (&t1->_u.union_type.disc_type->xt), ddsi_xt_unalias (&t2->_u.union_type.disc_type->xt), tce)) + return xt_non_assignable (reason, DDSI_NONASSIGN_DIFFERENT_EXTENSIBILITY, t1, t2, 0); + if (!xt_is_strongly_assignable_from (gv, ddsi_xt_unalias (&t1->_u.union_type.disc_type->xt), ddsi_xt_unalias (&t2->_u.union_type.disc_type->xt), tce, reason)) return false; /* Rule: Either the discriminators of both T1 and T2 are keys or neither are keys. */ if ((t1->_u.union_type.disc_flags & DDS_XTypes_IS_KEY) != (t2->_u.union_type.disc_flags & DDS_XTypes_IS_KEY)) - return false; + return xt_non_assignable (reason, DDSI_NONASSIGN_KEY_DIFFERS, t1, t2, 0); /* Note that union members are ordered by their member index (=ordering in idl) and not by their member ID */ uint32_t i1_max = t1->_u.union_type.members.length, i2_max = t2->_u.union_type.members.length; @@ -2429,15 +2462,15 @@ static bool xt_is_assignable_from_union (struct ddsi_domaingv *gv, const struct /* Rule: Any members in T1 and T2 that have the same name also have the same ID and any members with the same ID also have the same name. */ - if (!xt_namehash_eq (&m1->detail.name_hash, &m2->detail.name_hash) && (!tce || !tce->ignore_member_names)) - return false; + if (!xt_namehash_eq (&m1->detail.name_hash, &m2->detail.name_hash) && !tce->ignore_member_names) + return xt_non_assignable (reason, DDSI_NONASSIGN_NAME_HASH_DIFFERS, t1, t2, m1->id); } /* Rule: If T1 and T2 both have default labels, the type associated with T1 default member is assignable from the type associated with T2 default member. */ if ((m1->flags & DDS_XTypes_IS_DEFAULT) && (m2->flags & DDS_XTypes_IS_DEFAULT)) { - if (!ddsi_xt_is_assignable_from (gv, m1t, m2t, tce)) + if (!xt_is_assignable_from_impl (gv, m1t, m2t, tce, reason)) return false; } @@ -2453,14 +2486,14 @@ static bool xt_is_assignable_from_union (struct ddsi_domaingv *gv, const struct assignable from the type of the T2 default member. */ if (!(m1->flags & DDS_XTypes_IS_DEFAULT) && !t1_selects_t2_member && def_m2) { - if (!ddsi_xt_is_assignable_from (gv, m1t, ddsi_xt_unalias (&def_m2->type->xt), tce)) + if (!xt_is_assignable_from_impl (gv, m1t, ddsi_xt_unalias (&def_m2->type->xt), tce, reason)) return false; } /* Rule: If T1 (and therefore T2) extensibility is final or prevent type widening is set then the set of labels is identical. */ - if ((xt_get_extensibility (t1) == DDS_XTypes_IS_FINAL || (tce && tce->prevent_type_widening)) && (!m2_id_match || !m2_labels_match)) - return false; + if ((xt_get_extensibility (t1) == DDS_XTypes_IS_FINAL || tce->prevent_type_widening) && (!m2_id_match || !m2_labels_match)) + return xt_non_assignable (reason, DDSI_NONASSIGN_MISSING_CASE, t1, t2, 0); if (t1_selects_t2_member) any_match = true; } /* loop T1 members */ @@ -2482,31 +2515,34 @@ static bool xt_is_assignable_from_union (struct ddsi_domaingv *gv, const struct if (m1->flags & DDS_XTypes_IS_DEFAULT) def_m1 = m1; } - if ((sel_m1 || def_m1) && !ddsi_xt_is_assignable_from (gv, ddsi_xt_unalias (sel_m1 ? &sel_m1->type->xt : &def_m1->type->xt), ddsi_xt_unalias(&m2->type->xt), tce)) - return false; - if (!sel_m1 && tce && tce->prevent_type_widening) + if ((sel_m1 || def_m1) && !xt_is_assignable_from_impl (gv, ddsi_xt_unalias (sel_m1 ? &sel_m1->type->xt : &def_m1->type->xt), ddsi_xt_unalias(&m2->type->xt), tce, reason)) return false; + if (!sel_m1 && tce->prevent_type_widening) + return xt_non_assignable (reason, DDSI_NONASSIGN_MISSING_CASE, t1, t2, m2->id); } /* Rule: [extensibility is final], otherwise, they have at least one common label other than the default label. */ if (!any_match) - return false; + return xt_non_assignable (reason, DDSI_NONASSIGN_NO_OVERLAP, t1, t2, 0); return true; } -static bool xt_is_assignable_from_struct (struct ddsi_domaingv *gv, const struct xt_type *t1, const struct xt_type *t2, const dds_type_consistency_enforcement_qospolicy_t *tce) +ddsrt_nonnull_all +static bool xt_is_assignable_from_struct (struct ddsi_domaingv *gv, const struct xt_type *t1, const struct xt_type *t2, const dds_type_consistency_enforcement_qospolicy_t *tce, struct ddsi_non_assignability_reason *reason) { assert (t1->_d == DDS_XTypes_TK_STRUCTURE); assert (t2->_d == DDS_XTypes_TK_STRUCTURE); bool result = false; struct xt_type *te1 = (struct xt_type *) t1, *te2 = (struct xt_type *) t2; - if (xt_get_extensibility (t1) != xt_get_extensibility (t2)) + if (xt_get_extensibility (t1) != xt_get_extensibility (t2)) { + xt_non_assignable (reason, DDSI_NONASSIGN_DIFFERENT_EXTENSIBILITY, t1, t2, 0); goto struct_failed; + } if (xt_has_basetype (t1)) - if ((te1 = xt_expand_basetype (gv, t1)) == NULL) + if ((te1 = xt_expand_basetype (gv, t1, reason)) == NULL) goto struct_failed; if (xt_has_basetype (t2)) - if ((te2 = xt_expand_basetype (gv, t2)) == NULL) + if ((te2 = xt_expand_basetype (gv, t2, reason)) == NULL) goto struct_failed; /* Note that struct members are ordered by their member index (=ordering in idl) and not by their member ID (although the TypeObject idl states that its ordered by member_id...) */ @@ -2516,12 +2552,8 @@ static bool xt_is_assignable_from_struct (struct ddsi_domaingv *gv, const struct { const struct xt_struct_member *m1 = &te1->_u.structure.members.seq[i1]; const struct xt_type *m1t = ddsi_xt_unalias (&m1->type->xt); - if (ddsi_xt_is_unresolved (m1t)) - { - struct ddsi_typeid_str tidstr; - GVWARNING ("assignability check: member %"PRIu32" type %s unresolved in xt_is_assignable_from_struct\n", m1->id, ddsi_make_typeid_str (&tidstr, &m1t->id)); + if (!xt_is_assignable_check_resolved (m1t, reason, t1, m1->id)) goto struct_failed; - } bool match = false, m1_opt = (m1->flags & DDS_XTypes_IS_OPTIONAL), @@ -2536,33 +2568,35 @@ static bool xt_is_assignable_from_struct (struct ddsi_domaingv *gv, const struct any_member_match = true; match = true; const struct xt_type *m2t = ddsi_xt_unalias (&m2->type->xt); - if (ddsi_xt_is_unresolved (m2t)) - { - struct ddsi_typeid_str tidstr; - GVWARNING ("assignability check: member %"PRIu32" type %s unresolved in xt_is_assignable_from_struct\n", m2->id, ddsi_make_typeid_str (&tidstr, &m2t->id)); + if (!xt_is_assignable_check_resolved (m2t, reason, t2, m2->id)) goto struct_failed; - } /* Rule: "Any members in T1 and T2 that have the same name also have the same ID and any members with the same ID also have the same name." */ - if (!xt_namehash_eq (&m1->detail.name_hash, &m2->detail.name_hash) && (!tce || !tce->ignore_member_names)) + if (!xt_namehash_eq (&m1->detail.name_hash, &m2->detail.name_hash) && !tce->ignore_member_names) + { + xt_non_assignable (reason, DDSI_NONASSIGN_NAME_HASH_DIFFERS, t1, t2, m1->id); goto struct_failed; + } /* Rule: "For any member m2 in T2, if there is a member m1 in T1 with the same member ID, then the type KeyErased(m1.type) is-assignable from the type KeyErased(m2.type) */ struct xt_type *m1_ke = xt_type_key_erased (gv, m1t), *m2_ke = xt_type_key_erased (gv, m2t); - bool ke_assignable = ddsi_xt_is_assignable_from (gv, m1_ke, m2_ke, tce); + bool ke_assignable = xt_is_assignable_from_impl (gv, m1_ke, m2_ke, tce, reason); ddsi_xt_type_fini (gv, m1_ke, true); ddsrt_free (m1_ke); ddsi_xt_type_fini (gv, m2_ke, true); ddsrt_free (m2_ke); - if (!ke_assignable) goto struct_failed; + /* Rule: "For any string key member m2 in T2, the m1 member of T1 with the same member ID verifies m1.type.length >= m2.type.length. */ if (m2_k && xt_is_string (m2t) && !xt_check_bound (xt_string_bound (m1t), xt_string_bound (m2t))) + { + xt_non_assignable (reason, DDSI_NONASSIGN_KEY_INCOMPATIBLE, m1t, m2t, m1->id); goto struct_failed; + } /* Rule: "For any enumerated key member m2 in T2, the m1 member of T1 with the same member ID verifies that all literals in m2.type appear as literals in m1.type" */ if (m2_k && xt_is_enumerated (m2t)) @@ -2571,30 +2605,36 @@ static bool xt_is_assignable_from_struct (struct ddsi_domaingv *gv, const struct while (ki1 < ki1_max && ki2 < ki2_max) { struct xt_enum_literal *kl1 = &m1t->_u.enum_type.literals.seq[ki1], *kl2 = &m2t->_u.enum_type.literals.seq[ki2]; - if (kl1->value == kl2->value) - { + if (kl1->value == kl2->value) { ki1++; ki2++; - } - else if (kl1->value < kl2->value) + } else if (kl1->value < kl2->value) { ki1++; - else + } else { + xt_non_assignable (reason, DDSI_NONASSIGN_KEY_INCOMPATIBLE, m1t, m2t, m1->id); goto struct_failed; + } } } /* Rule: "For any sequence or map key member m2 in T2, the m1 member of T1 with the same member ID verifies m1.type.length >= m2.type.length" */ if (m2_k && m2t->_d == DDS_XTypes_TK_SEQUENCE && !xt_check_bound (m1t->_u.seq.bound, m2t->_u.seq.bound)) + { + xt_non_assignable (reason, DDSI_NONASSIGN_KEY_INCOMPATIBLE, m1t, m2t, m1->id); goto struct_failed; + } if (m2_k && m2t->_d == DDS_XTypes_TK_MAP && !xt_check_bound (m1t->_u.map.bound, m2t->_u.map.bound)) + { + xt_non_assignable (reason, DDSI_NONASSIGN_KEY_INCOMPATIBLE, m1t, m2t, m1->id); goto struct_failed; + } /* Rule: "For any structure or union key member m2 in T2, the m1 member of T1 with the same member ID verifies that KeyHolder(m1.type) isassignable-from KeyHolder(m2.type)." */ if (m2_k && (m2t->_d == DDS_XTypes_TK_STRUCTURE || m2t->_d == DDS_XTypes_TK_UNION)) { struct xt_type *m1_kh = xt_type_keyholder (gv, m1t), *m2_kh = xt_type_keyholder (gv, m2t); - bool kh_assignable = ddsi_xt_is_assignable_from (gv, m1_kh, m2_kh, tce); + bool kh_assignable = xt_is_assignable_from_impl (gv, m1_kh, m2_kh, tce, reason); ddsi_xt_type_fini (gv, m1_kh, true); ddsrt_free (m1_kh); ddsi_xt_type_fini (gv, m2_kh, true); @@ -2618,16 +2658,12 @@ static bool xt_is_assignable_from_struct (struct ddsi_domaingv *gv, const struct { const struct xt_type *km1_t = ddsi_xt_unalias (&km1->type->xt), *km2_t = ddsi_xt_unalias (&km2->type->xt); - if (ddsi_xt_is_unresolved (km1_t) || ddsi_xt_is_unresolved (km2_t)) - { - struct ddsi_typeid_str tidstr; - GVWARNING ("assignability check: union member %"PRIu32" type %s unresolved in xt_is_assignable_from_struct\n", - (ddsi_xt_is_unresolved (km1_t) ? km1 : km2)->id, ddsi_make_typeid_str (&tidstr, &(ddsi_xt_is_unresolved (km1_t) ? km1_t : km2_t)->id)); + if (!xt_is_assignable_check_resolved (km1_t, reason, t1, m1->id) || + !xt_is_assignable_check_resolved (km2_t, reason, t2, m2->id)) goto struct_failed; - } struct xt_type *km1_kh = xt_type_keyholder (gv, km1_t), *km2_kh = xt_type_keyholder (gv, km2_t); - bool kh_assignable = ddsi_xt_is_assignable_from (gv, km1_kh, km2_kh, tce); + bool kh_assignable = xt_is_assignable_from_impl (gv, km1_kh, km2_kh, tce, reason); ddsi_xt_type_fini (gv, km1_kh, true); ddsrt_free (km1_kh); ddsi_xt_type_fini (gv, km2_kh, true); @@ -2645,11 +2681,17 @@ static bool xt_is_assignable_from_struct (struct ddsi_domaingv *gv, const struct /* Rule (for T1 members): "Members for which both optional is false and must_understand is true in either T1 or T2 appear (i.e., have a corresponding member of the same member ID) in both T1 and T2. */ if (!m1_opt && m1_mu && !match) + { + xt_non_assignable (reason, DDSI_NONASSIGN_STRUCT_MUST_UNDERSTAND, t1, m1t, m1->id); goto struct_failed; + } /* Rule (for T1 members): "Members marked as key in either T1 or T2 appear (i.e., have a corresponding member of the same member ID) in both T1 and T2." */ if (m1_k && !match) + { + xt_non_assignable (reason, DDSI_NONASSIGN_KEY_DIFFERS, t1, t2, 0); goto struct_failed; + } /* Rules: - if T1 is appendable, then members with the same member_index have the same member ID, the same setting for the optional attribute and the T1 member type is strongly assignable from the T2 member type @@ -2657,17 +2699,27 @@ static bool xt_is_assignable_from_struct (struct ddsi_domaingv *gv, const struct struct xt_struct_member *m2 = &te2->_u.structure.members.seq[i1]; if ((xt_get_extensibility (te1) == DDS_XTypes_IS_APPENDABLE && i1 < i2_max) || xt_get_extensibility (te1) == DDS_XTypes_IS_FINAL) { - if (i1 >= i2_max) + if (i1 >= i2_max) { + xt_non_assignable (reason, DDSI_NONASSIGN_NUMBER_OF_MEMBERS, t1, t2, 0); + goto struct_failed; + } else if (m1->id != m2->id) { + xt_non_assignable (reason, DDSI_NONASSIGN_STRUCT_MEMBER_MISMATCH, t1, t2, m1->id); goto struct_failed; - if (m1->id != m2->id || (m1->flags & DDS_XTypes_IS_OPTIONAL) != (m2->flags & DDS_XTypes_IS_OPTIONAL) || !xt_is_strongly_assignable_from (gv, m1t, ddsi_xt_unalias (&m2->type->xt), tce)) + } else if ((m1->flags & DDS_XTypes_IS_OPTIONAL) != (m2->flags & DDS_XTypes_IS_OPTIONAL)) { + xt_non_assignable (reason, DDSI_NONASSIGN_STRUCT_OPTIONAL, t1, t2, m1->id); goto struct_failed; + } else if (!xt_is_strongly_assignable_from (gv, m1t, ddsi_xt_unalias (&m2->type->xt), tce, reason)) { + goto struct_failed; + } } /* if T1 is final, or prevent type-widening is set: ... [continued] in addition T1 and T2 have the same set of member IDs */ - if ((xt_get_extensibility (te1) == DDS_XTypes_IS_FINAL || (tce && tce->prevent_type_widening && !(m2->flags & DDS_XTypes_IS_OPTIONAL))) && !match) + if ((xt_get_extensibility (te1) == DDS_XTypes_IS_FINAL || (tce->prevent_type_widening && !(m2->flags & DDS_XTypes_IS_OPTIONAL))) && !match) + { + xt_non_assignable (reason, DDSI_NONASSIGN_NUMBER_OF_MEMBERS, t1, t2, m2->id); goto struct_failed; + } } /* for members in T1 */ - /* Rules (for T2 members): - Members for which both optional is false and must_understand is true in either T1 or T2 appear (i.e., have a corresponding member of the same member ID) in both T1 and T2 @@ -2681,17 +2733,23 @@ static bool xt_is_assignable_from_struct (struct ddsi_domaingv *gv, const struct if ((!(m2->flags & DDS_XTypes_IS_OPTIONAL) && (m2->flags & DDS_XTypes_IS_MUST_UNDERSTAND)) || (m2->flags & DDS_XTypes_IS_KEY) || xt_get_extensibility (te1) == DDS_XTypes_IS_FINAL - || (tce && tce->prevent_type_widening && !(m2->flags & DDS_XTypes_IS_OPTIONAL))) + || (tce->prevent_type_widening && !(m2->flags & DDS_XTypes_IS_OPTIONAL))) { for (uint32_t i1 = i2; !match && i1 < i1_max + i2; i1++) match = (te1->_u.structure.members.seq[i1 % i1_max].id == m2->id); if (!match) + { + xt_non_assignable (reason, DDSI_NONASSIGN_STRUCT_MEMBER_MISMATCH, t1, t2, m2->id); goto struct_failed; + } } } /* Rule: There is at least one member m1 of T1 and one corresponding member m2 of T2 such that m1.id == m2.id */ if (!any_member_match) + { + xt_non_assignable (reason, DDSI_NONASSIGN_NO_OVERLAP, t1, t2, 0); goto struct_failed; + } result = true; struct_failed: @@ -2708,69 +2766,94 @@ static bool xt_is_assignable_from_struct (struct ddsi_domaingv *gv, const struct return result; } -bool ddsi_xt_is_assignable_from (struct ddsi_domaingv *gv, const struct xt_type *rd_xt, const struct xt_type *wr_xt, const dds_type_consistency_enforcement_qospolicy_t *tce) +ddsrt_nonnull_all +static bool xt_is_assignable_from_bitmask (const struct xt_type *t1, const struct xt_type *t2, struct ddsi_non_assignability_reason *reason) { - const struct xt_type *t1 = ddsi_xt_unalias (rd_xt), *t2 = ddsi_xt_unalias (wr_xt); - if (ddsi_xt_is_unresolved (t1) || ddsi_xt_is_unresolved (t2)) + const struct xt_type *t_bm = t1->_d == DDS_XTypes_TK_BITMASK ? t1 : t2; + const struct xt_type *t_other = t1->_d == DDS_XTypes_TK_BITMASK ? t2 : t1; + DDS_XTypes_BitBound bb = t_bm->_u.bitmask.bit_bound; + enum ddsi_non_assignability_code code = DDSI_NONASSIGN_BOUND; + switch (t_other->_d) { - struct ddsi_typeid_str tidstr; - GVWARNING ("assignability check: unresolved type %s in ddsi_xt_is_assignable_from\n", ddsi_make_typeid_str (&tidstr, &(ddsi_xt_is_unresolved (t1) ? t1 : t2)->id)); - return false; + case DDS_XTypes_TK_BITMASK: + if (bb == t_other->_u.bitmask.bit_bound) + return true; + break; + case DDS_XTypes_TK_UINT8: + if (bb >= 1 && bb <= 8) + return true; + break; + case DDS_XTypes_TK_UINT16: + if (bb >= 9 && bb <= 16) + return true; + break; + case DDS_XTypes_TK_UINT32: + if (bb >= 17 && bb <= 32) + return true; + break; + case DDS_XTypes_TK_UINT64: + if (bb >= 33 && bb <= 64) + return true; + break; + default: + code = DDSI_NONASSIGN_INCOMPATIBLE_TYPE; + break; } + return xt_non_assignable (reason, code, t1, t2, 0); +} + +static bool xt_is_assignable_from_impl (struct ddsi_domaingv *gv, const struct xt_type *rd_xt, const struct xt_type *wr_xt, const dds_type_consistency_enforcement_qospolicy_t *tce, struct ddsi_non_assignability_reason *reason) +{ + const struct xt_type *t1 = ddsi_xt_unalias (rd_xt), *t2 = ddsi_xt_unalias (wr_xt); + if (!xt_is_assignable_check_resolved (t1, reason, NULL, 0) || !xt_is_assignable_check_resolved (t2, reason, NULL, 0)) + return false; if (xt_is_equivalent_minimal (t1, t2)) return true; /* Bitmask type: must be equal, except bitmask can be assigned to uint types and vv */ if (t1->_d == DDS_XTypes_TK_BITMASK || t2->_d == DDS_XTypes_TK_BITMASK) - { - const struct xt_type *t_bm = t1->_d == DDS_XTypes_TK_BITMASK ? t1 : t2; - const struct xt_type *t_other = t1->_d == DDS_XTypes_TK_BITMASK ? t2 : t1; - DDS_XTypes_BitBound bb = t_bm->_u.bitmask.bit_bound; - switch (t_other->_d) - { - case DDS_XTypes_TK_BITMASK: - return bb == t_other->_u.bitmask.bit_bound; - case DDS_XTypes_TK_UINT8: - return bb >= 1 && bb <= 8; - case DDS_XTypes_TK_UINT16: - return bb >= 9 && bb <= 16; - case DDS_XTypes_TK_UINT32: - return bb >= 17 && bb <= 32; - case DDS_XTypes_TK_UINT64: - return bb >= 33 && bb <= 64; - default: - return false; - } - } + return xt_is_assignable_from_bitmask (t1, t2, reason); + /* Enum type */ if (t1->_d == DDS_XTypes_TK_ENUM && t2->_d == DDS_XTypes_TK_ENUM) - return xt_is_assignable_from_enum (t1, t2); + return xt_is_assignable_from_enum (t1, t2, reason); /* String types: character type must be assignable, bound not checked for assignability, unless ignore_string_bounds is false */ - if ((t1->_d == DDS_XTypes_TK_STRING8 && t2->_d == DDS_XTypes_TK_STRING8)) - return !tce || tce->ignore_string_bounds || xt_check_bound (t1->_u.str8.bound, t2->_u.str8.bound); - if ((t1->_d == DDS_XTypes_TK_STRING16 && t2->_d == DDS_XTypes_TK_STRING16)) - return !tce || tce->ignore_string_bounds || xt_check_bound (t1->_u.str16.bound, t2->_u.str16.bound); + if ((t1->_d == DDS_XTypes_TK_STRING8 && t2->_d == DDS_XTypes_TK_STRING8)) { + if (tce->ignore_string_bounds || xt_check_bound (t1->_u.str8.bound, t2->_u.str8.bound)) + return true; + return xt_non_assignable (reason, DDSI_NONASSIGN_BOUND, t1, t2, 0); + } + if ((t1->_d == DDS_XTypes_TK_STRING16 && t2->_d == DDS_XTypes_TK_STRING16)) { + if (tce->ignore_string_bounds || xt_check_bound (t1->_u.str16.bound, t2->_u.str16.bound)) + return true; + return xt_non_assignable (reason, DDSI_NONASSIGN_BOUND, t1, t2, 0); + } /* Collection types */ - if (t1->_d == DDS_XTypes_TK_ARRAY && t2->_d == DDS_XTypes_TK_ARRAY) - return xt_bounds_eq (&t1->_u.array.bounds, &t2->_u.array.bounds) - && xt_is_strongly_assignable_from (gv, &t1->_u.array.c.element_type->xt, &t2->_u.array.c.element_type->xt, tce); - if (t1->_d == DDS_XTypes_TK_SEQUENCE && t2->_d == DDS_XTypes_TK_SEQUENCE) - return (!tce || tce->ignore_sequence_bounds || xt_check_bound (t1->_u.seq.bound, t2->_u.seq.bound)) - && xt_is_strongly_assignable_from (gv, &t1->_u.seq.c.element_type->xt, &t2->_u.seq.c.element_type->xt, tce); - if (t1->_d == DDS_XTypes_TK_MAP && t2->_d == DDS_XTypes_TK_MAP) - return xt_is_strongly_assignable_from (gv, &t1->_u.map.key_type->xt, &t2->_u.map.key_type->xt, tce) - && xt_is_strongly_assignable_from (gv, &t1->_u.map.c.element_type->xt, &t2->_u.map.c.element_type->xt, tce); + if (t1->_d == DDS_XTypes_TK_ARRAY && t2->_d == DDS_XTypes_TK_ARRAY) { + if (xt_bounds_eq (&t1->_u.array.bounds, &t2->_u.array.bounds)) + return xt_is_strongly_assignable_from (gv, &t1->_u.array.c.element_type->xt, &t2->_u.array.c.element_type->xt, tce, reason); + return xt_non_assignable (reason, DDSI_NONASSIGN_BOUND, t1, t2, 0); + } + if (t1->_d == DDS_XTypes_TK_SEQUENCE && t2->_d == DDS_XTypes_TK_SEQUENCE) { + if (tce->ignore_sequence_bounds || xt_check_bound (t1->_u.seq.bound, t2->_u.seq.bound)) + return xt_is_strongly_assignable_from (gv, &t1->_u.seq.c.element_type->xt, &t2->_u.seq.c.element_type->xt, tce, reason); + return xt_non_assignable (reason, DDSI_NONASSIGN_BOUND, t1, t2, 0); + } + if (t1->_d == DDS_XTypes_TK_MAP && t2->_d == DDS_XTypes_TK_MAP) { + return xt_is_strongly_assignable_from (gv, &t1->_u.map.key_type->xt, &t2->_u.map.key_type->xt, tce, reason) + && xt_is_strongly_assignable_from (gv, &t1->_u.map.c.element_type->xt, &t2->_u.map.c.element_type->xt, tce, reason); + } // Aggregated types if (t1->_d == DDS_XTypes_TK_UNION && t2->_d == DDS_XTypes_TK_UNION) - return xt_is_assignable_from_union (gv, t1, t2, tce); + return xt_is_assignable_from_union (gv, t1, t2, tce, reason); if (t1->_d == DDS_XTypes_TK_STRUCTURE && t2->_d == DDS_XTypes_TK_STRUCTURE) - return xt_is_assignable_from_struct (gv, t1, t2, tce); + return xt_is_assignable_from_struct (gv, t1, t2, tce, reason); - return false; + return xt_non_assignable (reason, DDSI_NONASSIGN_INCOMPATIBLE_TYPE, t1, t2, 0); } static ddsi_typeid_kind_t ddsi_typeid_kind_impl (const struct DDS_XTypes_TypeIdentifier *type_id) @@ -2828,6 +2911,16 @@ static ddsi_typeid_kind_t ddsi_typeid_kind_impl (const struct DDS_XTypes_TypeIde return kind; } +bool ddsi_xt_is_assignable_from (struct ddsi_domaingv *gv, const struct xt_type *rd_xt, const struct xt_type *wr_xt, const dds_type_consistency_enforcement_qospolicy_t *tce, struct ddsi_non_assignability_reason *reason) +{ + reason->code = DDSI_NONASSIGN_ASSIGNABLE; + if (xt_is_assignable_from_impl (gv, rd_xt, wr_xt, tce, reason)) + return true; + if (reason->code == DDSI_NONASSIGN_ASSIGNABLE) + xt_non_assignable (reason, DDSI_NONASSIGN_UNKNOWN, rd_xt, wr_xt, 0); + return false; +} + ddsi_typeid_kind_t ddsi_typeid_kind (const ddsi_typeid_t *type_id) { return ddsi_typeid_kind_impl (&type_id->x); From b52b4073de02b228af0f3b209751f0af985f67d0 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 18 Jun 2024 11:21:56 +0200 Subject: [PATCH 143/207] UAF in tracing preemptive ACKNACK with security Encoding the submessage can delete it if the remote writer is no longer known. That in turn can free the submessage and invalidate the data used to print a message in the trace. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_acknack.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core/ddsi/src/ddsi_acknack.c b/src/core/ddsi/src/ddsi_acknack.c index 1b0a4c8dce..7efb1a4cf0 100644 --- a/src/core/ddsi/src/ddsi_acknack.c +++ b/src/core/ddsi/src/ddsi_acknack.c @@ -554,16 +554,18 @@ static struct ddsi_xmsg *make_preemptive_acknack (struct ddsi_xevent *ev, struct (ddsi_count_t *) ((char *) an + offsetof (ddsi_rtps_acknack_t, bits) + DDSI_SEQUENCE_NUMBER_SET_BITS_SIZE (0)); *countp = 0; ddsi_xmsg_submsg_setnext (msg, sm_marker); - ddsi_security_encode_datareader_submsg (msg, sm_marker, pwr, &rwn->rd_guid); - - rwn->t_last_ack = tnow; - const dds_duration_t new_intv = preemptive_acknack_interval (rwn); - (void) ddsi_resched_xevent_if_earlier (ev, ddsrt_mtime_add_duration (rwn->t_last_ack, new_intv)); + // print before security gets to it: it can delete the message // numbits is always 0 here, so need to print the bitmap ETRACE (pwr, "acknack "PGUIDFMT" -> "PGUIDFMT": #%"PRIu32":%"PRId64"/%"PRIu32":\n", PGUID (rwn->rd_guid), PGUID (pwr->e.guid), *countp, ddsi_from_seqno (an->readerSNState.bitmap_base), an->readerSNState.numbits); + + ddsi_security_encode_datareader_submsg (msg, sm_marker, pwr, &rwn->rd_guid); + + rwn->t_last_ack = tnow; + const dds_duration_t new_intv = preemptive_acknack_interval (rwn); + (void) ddsi_resched_xevent_if_earlier (ev, ddsrt_mtime_add_duration (rwn->t_last_ack, new_intv)); return msg; } From 8a2a7a9df80e0f29ee7a8a0c02ec6cbf1ef60bf7 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 18 Jun 2024 11:11:04 +0200 Subject: [PATCH 144/207] Fix harmless typo in dynsub output Signed-off-by: Erik Boasson --- examples/dynsub/dynsub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/dynsub/dynsub.c b/examples/dynsub/dynsub.c index d6fe30a4e9..c9dc572130 100644 --- a/examples/dynsub/dynsub.c +++ b/examples/dynsub/dynsub.c @@ -80,7 +80,7 @@ static dds_return_t get_topic_and_typeobj (const char *topic_name, dds_duration_ // as an approximation of the topic QoS. if ((*topic = dds_find_topic (DDS_FIND_SCOPE_GLOBAL, participant, ep->topic_name, typeinfo, DDS_SECS (2))) < 0) { - fprintf (stderr, "dds_find_topic: %s ... continuing on the assumptions that topic discovery is disabled\n", dds_strretcode (*topic)); + fprintf (stderr, "dds_find_topic: %s ... continuing on the assumption that topic discovery is disabled\n", dds_strretcode (*topic)); dds_topic_descriptor_t *descriptor; if ((ret = dds_create_topic_descriptor(DDS_FIND_SCOPE_GLOBAL, participant, typeinfo, DDS_SECS (10), &descriptor)) < 0) { From 72b4f8645374c24af863e6ccc7312ceb4f413422 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 18 Jun 2024 11:14:20 +0200 Subject: [PATCH 145/207] Use copy of type id in non-assignability reason The type may have been freed by the time the stated reason is interpreted. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi__typewrap.h | 6 ++++-- src/core/ddsi/src/ddsi_typelib.c | 8 ++++---- src/core/ddsi/src/ddsi_typewrap.c | 11 +++++++++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/core/ddsi/src/ddsi__typewrap.h b/src/core/ddsi/src/ddsi__typewrap.h index c7738f5bcd..fbdaee4639 100644 --- a/src/core/ddsi/src/ddsi__typewrap.h +++ b/src/core/ddsi/src/ddsi__typewrap.h @@ -88,8 +88,10 @@ enum ddsi_non_assignability_code { struct ddsi_non_assignability_reason { enum ddsi_non_assignability_code code; - const struct xt_type *t1; - const struct xt_type *t2; + DDS_XTypes_TypeIdentifier t1_id; + DDS_XTypes_TypeIdentifier t2_id; + uint8_t t1_typekind; + uint8_t t2_typekind; uint32_t id; }; diff --git a/src/core/ddsi/src/ddsi_typelib.c b/src/core/ddsi/src/ddsi_typelib.c index ac3e4df3c0..e6645b6f43 100644 --- a/src/core/ddsi/src/ddsi_typelib.c +++ b/src/core/ddsi/src/ddsi_typelib.c @@ -1423,10 +1423,10 @@ bool ddsi_is_assignable_from (struct ddsi_domaingv *gv, const struct ddsi_type_p GVLOG (lc_cat, "assignability check failed: rd type %s wr type %s, t1=%s (%s) t2=%s (%s) id %"PRIu32": %s\n", ddsi_make_typeid_str (&trdstr, &rd_xt->id), ddsi_make_typeid_str (&twrstr, &wr_xt->id), - reason.t1 ? ddsi_make_typeid_str (&t1str, &reason.t1->id) : "(none)", - reason.t1 ? ddsi_typekind_descr (reason.t1->_d) : "", - reason.t2 ? ddsi_make_typeid_str (&t2str, &reason.t2->id) : "(none)", - reason.t2 ? ddsi_typekind_descr (reason.t2->_d) : "", + reason.t1_typekind ? ddsi_make_typeid_str_impl (&t1str, &reason.t1_id) : "(none)", + reason.t1_typekind ? ddsi_typekind_descr (reason.t1_typekind) : "", + reason.t2_typekind ? ddsi_make_typeid_str_impl (&t2str, &reason.t2_id) : "(none)", + reason.t2_typekind ? ddsi_typekind_descr (reason.t2_typekind) : "", reason.id, ddsi_non_assignability_code_str (reason.code)); } return assignable; diff --git a/src/core/ddsi/src/ddsi_typewrap.c b/src/core/ddsi/src/ddsi_typewrap.c index cc7bd39f7b..02ea27ea9b 100644 --- a/src/core/ddsi/src/ddsi_typewrap.c +++ b/src/core/ddsi/src/ddsi_typewrap.c @@ -2066,8 +2066,13 @@ static bool xt_non_assignable (struct ddsi_non_assignability_reason *reason, enu { reason->code = code; reason->id = id; - reason->t1 = t1; - reason->t2 = t2; + reason->t1_id = t1->id.x; + reason->t1_typekind = t1->_d; + if (t2) + { + reason->t2_id = t2->id.x; + reason->t2_typekind = t2->_d; + } return false; } @@ -2914,6 +2919,8 @@ static ddsi_typeid_kind_t ddsi_typeid_kind_impl (const struct DDS_XTypes_TypeIde bool ddsi_xt_is_assignable_from (struct ddsi_domaingv *gv, const struct xt_type *rd_xt, const struct xt_type *wr_xt, const dds_type_consistency_enforcement_qospolicy_t *tce, struct ddsi_non_assignability_reason *reason) { reason->code = DDSI_NONASSIGN_ASSIGNABLE; + reason->t1_typekind = 0; + reason->t2_typekind = 0; if (xt_is_assignable_from_impl (gv, rd_xt, wr_xt, tce, reason)) return true; if (reason->code == DDSI_NONASSIGN_ASSIGNABLE) From 24c6e8c13e78198f92969d7170bf0f5c1c77e05a Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 18 Jun 2024 11:15:26 +0200 Subject: [PATCH 146/207] Fix loop bounds validating struct without members An struct that inherits from another struct need not any members. If the base type is not known yet the validation code used (uint32_t) -1 as the loop bound. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_typewrap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ddsi/src/ddsi_typewrap.c b/src/core/ddsi/src/ddsi_typewrap.c index 02ea27ea9b..69e4739275 100644 --- a/src/core/ddsi/src/ddsi_typewrap.c +++ b/src/core/ddsi/src/ddsi_typewrap.c @@ -640,9 +640,9 @@ static dds_return_t xt_valid_struct_member_ids (struct ddsi_domaingv *gv, const ids[--cnt1] = t1->_u.structure.members.seq[n].id; } qsort (ids, cnt, sizeof (*ids), xt_member_id_cmp); - for (uint32_t n = 0; n < cnt - 1; n++) + for (uint32_t n = 1; n < cnt; n++) { - if (ids[n] == ids[n + 1]) + if (ids[n] == ids[n - 1]) { GVTRACE ("duplicate member id %"PRIu32" in struct\n", ids[n]); ret = DDS_RETCODE_BAD_PARAMETER; From 545f4cb283d30c9151a53f93c38cb30613438428 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 18 Jun 2024 11:17:40 +0200 Subject: [PATCH 147/207] Type builder: keys from non-mutable base types This fixes a null pointer dereference in comparing key ids in dynamically constructing a (de)serializer when the key is an inherited composite key in a non-mutable type, e.g.: @final struct K { long a; }; @final struct Base { @key K a; }; @final struct Derived : Base { }; Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_typebuilder.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/core/ddsi/src/ddsi_typebuilder.c b/src/core/ddsi/src/ddsi_typebuilder.c index 57fd733e9d..0de164fdf8 100644 --- a/src/core/ddsi/src/ddsi_typebuilder.c +++ b/src/core/ddsi/src/ddsi_typebuilder.c @@ -1500,15 +1500,19 @@ static int key_id_cmp (const void *va, const void *vb) for (uint32_t n = 0; n < (*a)->path->n_parts; n++) { assert (n < (*b)->path->n_parts); - if ((*a)->path->parts[n].kind == KEY_PATH_PART_INHERIT_MUTABLE) + switch ((*a)->path->parts[n].kind) { - /* a derived type cannot add keys, so all keys must have an INHERIT_MUTABLE - kind part at this index */ - assert ((*b)->path->parts[n].kind == KEY_PATH_PART_INHERIT_MUTABLE); - continue; + case KEY_PATH_PART_INHERIT: + case KEY_PATH_PART_INHERIT_MUTABLE: + /* a derived type cannot add keys, so all keys must have an INHERIT_MUTABLE + kind part at this index */ + assert ((*b)->path->parts[n].kind == (*a)->path->parts[n].kind); + break; + case KEY_PATH_PART_REGULAR: + if ((*a)->path->parts[n].member->member_id != (*b)->path->parts[n].member->member_id) + return (*a)->path->parts[n].member->member_id < (*b)->path->parts[n].member->member_id ? -1 : 1; + break; } - if ((*a)->path->parts[n].member->member_id != (*b)->path->parts[n].member->member_id) - return (*a)->path->parts[n].member->member_id < (*b)->path->parts[n].member->member_id ? -1 : 1; } assert ((*a)->path->n_parts == (*b)->path->n_parts); return 0; From 03b1b09b89b74646a4eb7fee8d0c886f37fb8c94 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Wed, 19 Jun 2024 16:31:22 +0200 Subject: [PATCH 148/207] Fix serdata size in serdata_default_from_psmx The size of a serdata should include the padding bytes. This fix adds these padding bytes from the PSMX meta-data in the call to serdata_default_new_size when receiving data from PSMX. Signed-off-by: Dennis Potman --- src/core/ddsc/src/dds_serdata_default.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ddsc/src/dds_serdata_default.c b/src/core/ddsc/src/dds_serdata_default.c index 79bee52841..5e01b8485e 100644 --- a/src/core/ddsc/src/dds_serdata_default.c +++ b/src/core/ddsc/src/dds_serdata_default.c @@ -913,7 +913,8 @@ static struct ddsi_serdata * serdata_default_from_psmx (const struct ddsi_sertyp else return NULL; - struct dds_serdata_default *d = serdata_default_new_size (tp, kind, md->sample_size, xcdr_version); + const uint32_t pad = ddsrt_fromBE2u (md->cdr_options) & DDS_CDR_HDR_PADDING_MASK; + struct dds_serdata_default *d = serdata_default_new_size (tp, kind, md->sample_size + pad, xcdr_version); d->c.statusinfo = md->statusinfo; d->c.timestamp.v = md->timestamp; if (md->cdr_identifier == DDSI_RTPS_SAMPLE_NATIVE) From f24646bd787be4e2374137a54f1b172051c641ae Mon Sep 17 00:00:00 2001 From: reicheratwork <66302498+reicheratwork@users.noreply.github.com> Date: Wed, 19 Jun 2024 17:29:40 +0200 Subject: [PATCH 149/207] Fixed memory leak in idl preprocessor (#2023) * Fixed memory leak in idl preprocessor To reproduce this leak: parse an idl file which includes another idl file This leak was caused by not freeing the strings generated when resolving paths Signed-off-by: Martijn Reicher * Fixes due to GitHub comments Signed-off-by: Martijn Reicher * Fixes access-after-free in idlpp Signed-off-by: Martijn Reicher --------- Signed-off-by: Martijn Reicher --- src/tools/idlpp/src/internal.H | 1 + src/tools/idlpp/src/main.c | 3 +++ src/tools/idlpp/src/system.c | 11 ++++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/tools/idlpp/src/internal.H b/src/tools/idlpp/src/internal.H index feb3cefe90..6cbbb9b294 100644 --- a/src/tools/idlpp/src/internal.H +++ b/src/tools/idlpp/src/internal.H @@ -507,6 +507,7 @@ extern int (* mcpp_fprintf)( MCPP_OUTDEST od, const char * format, ...) MCPP_ATTRIBUTE_FORMAT_PRINTF(2, 3); /* system.c */ +extern void clean_system(void); extern void do_options( int argc, char ** argv, char ** in_pp , char ** out_pp); /* Process command line args */ diff --git a/src/tools/idlpp/src/main.c b/src/tools/idlpp/src/main.c index 3c49ffea73..322b95fc2b 100644 --- a/src/tools/idlpp/src/main.c +++ b/src/tools/idlpp/src/main.c @@ -450,6 +450,9 @@ int main fclose( fp_out); if (fp_err && fp_err != stderr) fclose( fp_err); + clean_system(); + if (in_file != NULL) + free(in_file); if (mcpp_debug & MEMORY) print_heap(); diff --git a/src/tools/idlpp/src/system.c b/src/tools/idlpp/src/system.c index 74ee280814..fa24b7ed98 100644 --- a/src/tools/idlpp/src/system.c +++ b/src/tools/idlpp/src/system.c @@ -3291,8 +3291,7 @@ int do_include( } #endif if (open_include( filename, (delim == '"'), next)) { - /* 'fname' should not be free()ed, it is used as file-> */ - /* real_fname and has been registered into fnamelist[] */ + free( filename); return TRUE; } @@ -3612,6 +3611,7 @@ static int open_file( put_depend( fullname); /* Output dependency line */ true: + free( fullname); return TRUE; false: free( fullname); @@ -3680,7 +3680,7 @@ static const char * set_fname( fnamelen = strlen( filename); for (fnamep = fnamelist; fnamep < fname_end; fnamep++) { if (fnamep->len == fnamelen && str_case_eq( fnamep->name, filename)) - return filename; /* Already registered */ + return fnamep->name; /* Already registered */ } fname_end->name = xmalloc( fnamelen + 1); filename = strcpy( (char *)fname_end->name, filename); @@ -5086,3 +5086,8 @@ void clear_filelist( void) } #endif +void clean_system(void) +{ + if (sharp_filename != NULL) + free(sharp_filename); +} From 0b81f871370dbca4367631a23e01f1b7c6dc5426 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Wed, 19 Jun 2024 14:03:27 +0200 Subject: [PATCH 150/207] Update ddsi_new_proxy_participant call in fuzzer Signed-off-by: Erik Boasson --- fuzz/fuzz_handshake/fuzz_handshake_harness.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/fuzz/fuzz_handshake/fuzz_handshake_harness.c b/fuzz/fuzz_handshake/fuzz_handshake_harness.c index 560c2ab30a..bb807c69bf 100644 --- a/fuzz/fuzz_handshake/fuzz_handshake_harness.c +++ b/fuzz/fuzz_handshake/fuzz_handshake_harness.c @@ -142,6 +142,7 @@ bool fuzz_handshake_init() ddsi_xqos_mergein_missing (&pplist.qos, new_qos, ~(uint64_t)0); dds_delete_qos(new_qos); + ddsi_generate_participant_guid (&g_ppguid, &gv); dds_return_t ret = ddsi_new_participant(&g_ppguid, &gv, 0, &pplist); if(ret != DDS_RETCODE_OK) abort(); harness.pp = ddsi_entidx_lookup_participant_guid(gv.entity_index, &g_ppguid); @@ -214,12 +215,10 @@ void fuzz_handshake_reset(bool initiate_remote) { g_proxy_ppguid.prefix.s[0] = 0xff; g_proxy_ppguid.prefix.s[1] = 0xff; g_proxy_ppguid.prefix.s[2] = 0xff; - g_proxy_ppguid.prefix.s[3] = 0xff; } else { g_proxy_ppguid.prefix.s[0] = 0x00; g_proxy_ppguid.prefix.s[1] = 0x00; g_proxy_ppguid.prefix.s[2] = 0x00; - g_proxy_ppguid.prefix.s[3] = 0x00; } ddsrt_wctime_t timestamp = { .v = dds_time() }; @@ -234,7 +233,7 @@ void fuzz_handshake_reset(bool initiate_remote) { assert(!ddsi_addrset_empty_uc(as)); ddsi_thread_state_awake(ddsi_lookup_thread_state(), &gv); - if (!ddsi_new_proxy_participant(&gv, + if (!ddsi_new_proxy_participant(&harness.proxy_pp, &gv, &g_proxy_ppguid, DDSI_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_ANNOUNCER| DDSI_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_ANNOUNCER|DDSI_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_DETECTOR, @@ -249,8 +248,6 @@ void fuzz_handshake_reset(bool initiate_remote) { 0)) { abort(); } - - harness.proxy_pp = ddsi_entidx_lookup_proxy_participant_guid(gv.entity_index, &g_proxy_ppguid); ddsi_thread_state_asleep(ddsi_lookup_thread_state()); ddsi_plist_fini(&pplist); From 53ecfa46bc74f0dcf5f383561e82309eb3a65fbc Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 4 Jun 2024 17:56:48 +0200 Subject: [PATCH 151/207] Always have a NACK scheduled if data is missing The spec says that readers may only send an ACKNACK message in response to a HEARTBEAT, but there is no guarantee that a writer will actually send that HEARTBEAT for historical data and in case of reconnecting after an asymmetric disconnection. The sensible thing to do is to not sit idle as a reader, but always eventually send an ACKNACK if data is known to be missing (or if no HEARTBEAT has been received yet). This has been a design choice in this stack since the very beginning, but it turns out that there is a case where the ACKNACK event doesn't get rescheduled even though data is missing because what would ordinarily have been a NACK gets generated as an ACK, and then potentially never sent out. This changes the ACKNACK generation logic to always distinguish the case where a NACK would have been generated if only circumstances allowed it, then ensures that the event is always scheduled if a NACK is generated or would have been generated. Signed-off-by: Erik Boasson --- src/core/ddsi/include/dds/ddsi/ddsi_xevent.h | 13 + src/core/ddsi/src/ddsi__acknack.h | 5 +- src/core/ddsi/src/ddsi__radmin.h | 8 +- src/core/ddsi/src/ddsi_acknack.c | 277 +++++++++++-------- src/core/ddsi/src/ddsi_radmin.c | 55 +++- src/core/ddsi/src/ddsi_receive.c | 2 +- src/core/ddsi/src/ddsi_xevent.c | 10 + 7 files changed, 249 insertions(+), 121 deletions(-) diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_xevent.h b/src/core/ddsi/include/dds/ddsi/ddsi_xevent.h index ebeba014a4..524c0b83f8 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_xevent.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_xevent.h @@ -55,6 +55,19 @@ void ddsi_delete_xevent (struct ddsi_xevent *ev) int ddsi_resched_xevent_if_earlier (struct ddsi_xevent *ev, ddsrt_mtime_t tsched) ddsrt_nonnull_all; +/** @brief returns whether or not the event is scheduled + * @component timed_events + * + * @remark: may be called from inside the event handler + * + * @param[in] ev the event for which to check whether it is scheduled + * + * @retval 0 not scheduled + * @retval 1 scheduled + */ +int ddsi_xevent_is_scheduled (struct ddsi_xevent *ev) + ddsrt_nonnull_all; + /** @brief creates a new event object on the given event queue for invoking `cb` in the * future on the thread handling this queue * @component timed_events diff --git a/src/core/ddsi/src/ddsi__acknack.h b/src/core/ddsi/src/ddsi__acknack.h index 8ceea1dab8..4170000153 100644 --- a/src/core/ddsi/src/ddsi__acknack.h +++ b/src/core/ddsi/src/ddsi__acknack.h @@ -27,7 +27,8 @@ struct ddsi_pwr_rd_match; struct ddsi_proxy_writer; enum ddsi_add_acknack_result { - AANR_SUPPRESSED_ACK, //!< sending nothing: too short a time since the last ACK + AANR_SILENT_ACK, //!< sending nothing: too short a time since the last ACK + AANR_SILENT_NACK, //!< sending nothing, even though there are things to NACK AANR_ACK, //!< sending an ACK and there's nothing to NACK AANR_SUPPRESSED_NACK, //!< sending an ACK even though there are things to NACK AANR_NACK, //!< sending a NACK, possibly also a NACKFRAG @@ -53,7 +54,7 @@ struct ddsi_add_acknack_info { /** @component incoming_rtps */ -void ddsi_sched_acknack_if_needed (struct ddsi_xevent *ev, struct ddsi_proxy_writer *pwr, struct ddsi_pwr_rd_match *rwn, ddsrt_mtime_t tnow, bool avoid_suppressed_nack); +void ddsi_sched_acknack_if_needed (struct ddsi_xevent *ev, struct ddsi_proxy_writer *pwr, struct ddsi_pwr_rd_match *rwn, ddsrt_mtime_t tnow); struct ddsi_acknack_xevent_cb_arg { ddsi_guid_t pwr_guid; diff --git a/src/core/ddsi/src/ddsi__radmin.h b/src/core/ddsi/src/ddsi__radmin.h index 53434d7578..1cdb788454 100644 --- a/src/core/ddsi/src/ddsi__radmin.h +++ b/src/core/ddsi/src/ddsi__radmin.h @@ -198,8 +198,14 @@ void ddsi_reorder_drop_upto (struct ddsi_reorder *reorder, ddsi_seqno_t maxp1); /** @component receive_buffers */ int ddsi_reorder_wantsample (const struct ddsi_reorder *reorder, ddsi_seqno_t seq); +enum ddsi_reorder_nackmap_result { + DDSI_REORDER_NACKMAP_ACK, //!< Nothing to ACK, bitmap length = 0 + DDSI_REORDER_NACKMAP_NACK, //!< Some bits set in bitmap, bitmap length \> 0 + DDSI_REORDER_NACKMAP_SUPPRESSED_NACK //!< No bits set in bitmap even though there are things to NACK, bitmap length \> 0 +}; + /** @component receive_buffers */ -unsigned ddsi_reorder_nackmap (const struct ddsi_reorder *reorder, ddsi_seqno_t base, ddsi_seqno_t maxseq, struct ddsi_sequence_number_set_header *map, uint32_t *mapbits, uint32_t maxsz, int notail); +enum ddsi_reorder_nackmap_result ddsi_reorder_nackmap (const struct ddsi_reorder *reorder, ddsi_seqno_t base, ddsi_seqno_t maxseq, struct ddsi_sequence_number_set_header *map, uint32_t *mapbits, uint32_t maxsz, int notail); /** @component receive_buffers */ ddsi_seqno_t ddsi_reorder_next_seq (const struct ddsi_reorder *reorder); diff --git a/src/core/ddsi/src/ddsi_acknack.c b/src/core/ddsi/src/ddsi_acknack.c index 7efb1a4cf0..4c818e7558 100644 --- a/src/core/ddsi/src/ddsi_acknack.c +++ b/src/core/ddsi/src/ddsi_acknack.c @@ -100,7 +100,7 @@ static void add_acknack_getsource (const struct ddsi_proxy_writer *pwr, const st } } -static bool add_acknack_makebitmaps (const struct ddsi_proxy_writer *pwr, const struct ddsi_pwr_rd_match *rwn, struct ddsi_add_acknack_info *info) +static enum ddsi_reorder_nackmap_result add_acknack_makebitmaps (const struct ddsi_proxy_writer *pwr, const struct ddsi_pwr_rd_match *rwn, struct ddsi_add_acknack_info *info) { struct ddsi_reorder *reorder; ddsi_seqno_t bitmap_base; @@ -109,17 +109,18 @@ static bool add_acknack_makebitmaps (const struct ddsi_proxy_writer *pwr, const /* Make bitmap; note that we've made sure to have room for the maximum bitmap size. */ const ddsi_seqno_t last_seq = rwn->filtered ? rwn->last_seq : pwr->last_seq; - const uint32_t numbits = ddsi_reorder_nackmap (reorder, bitmap_base, last_seq, &info->acknack.set, info->acknack.bits, DDSI_SEQUENCE_NUMBER_SET_MAX_BITS, notail); - if (numbits == 0) + const enum ddsi_reorder_nackmap_result nackmap_result = ddsi_reorder_nackmap (reorder, bitmap_base, last_seq, &info->acknack.set, info->acknack.bits, DDSI_SEQUENCE_NUMBER_SET_MAX_BITS, notail); + if (nackmap_result != DDSI_REORDER_NACKMAP_NACK) { info->nackfrag.seq = 0; - return false; + return nackmap_result; } /* Scan through bitmap, cutting it off at the first missing sample that the defragmenter knows about. Then note the sequence number & add a NACKFRAG for that sample */ info->nackfrag.seq = 0; const ddsi_seqno_t base = ddsi_from_seqno (info->acknack.set.bitmap_base); + const uint32_t numbits = info->acknack.set.numbits; for (uint32_t i = 0; i < numbits; i++) { if (!ddsi_bitset_isset (numbits, info->acknack.bits, i)) @@ -135,15 +136,15 @@ static bool add_acknack_makebitmaps (const struct ddsi_proxy_writer *pwr, const /* Cut the NACK short (or make it an ACK if this is the first sample), no NACKFRAG */ info->nackfrag.seq = 0; info->acknack.set.numbits = i; - return (i > 0); + return (i > 0) ? DDSI_REORDER_NACKMAP_NACK : DDSI_REORDER_NACKMAP_SUPPRESSED_NACK; case DDSI_DEFRAG_NACKMAP_FRAGMENTS_MISSING: /* Cut the NACK short, NACKFRAG */ info->nackfrag.seq = seq; info->acknack.set.numbits = i; - return true; + return DDSI_REORDER_NACKMAP_NACK; } } - return true; + return DDSI_REORDER_NACKMAP_NACK; } static void add_NackFrag (struct ddsi_xmsg *msg, const struct ddsi_proxy_writer *pwr, const struct ddsi_pwr_rd_match *rwn, const struct ddsi_add_acknack_info *info) @@ -238,81 +239,87 @@ static enum ddsi_add_acknack_result get_acknack_info (const struct ddsi_proxy_wr AckNack. NACKing data now will most likely cause another NACK upon reception of the first heartbeat, and so cause the data to be resent twice. */ - enum ddsi_add_acknack_result result; + enum ddsi_add_acknack_result result = AANR_SILENT_ACK; #if ACK_REASON_IN_FLAGS info->flags = 0; #endif - if (!add_acknack_makebitmaps (pwr, rwn, info)) + const enum ddsi_reorder_nackmap_result bitmap_result = add_acknack_makebitmaps (pwr, rwn, info); + switch (bitmap_result) { - info->nack_sent_on_nackdelay = rwn->nack_sent_on_nackdelay; - nack_summary->seq_base = ddsi_from_seqno (info->acknack.set.bitmap_base); - nack_summary->seq_end_p1 = 0; - nack_summary->frag_base = 0; - nack_summary->frag_end_p1 = 0; - result = AANR_ACK; - } - else - { - // [seq_base:0 .. seq_end_p1:0) + [seq_end_p1:frag_base .. seq_end_p1:frag_end_p1) if frag_end_p1 > 0 - const ddsi_seqno_t seq_base = ddsi_from_seqno (info->acknack.set.bitmap_base); - assert (seq_base >= 1 && (info->acknack.set.numbits > 0 || info->nackfrag.seq > 0)); - assert (info->nackfrag.seq == 0 || info->nackfrag.set.numbits > 0); - const ddsi_seqno_t seq_end_p1 = seq_base + info->acknack.set.numbits; - const uint32_t frag_base = (info->nackfrag.seq > 0) ? info->nackfrag.set.bitmap_base : 0; - const uint32_t frag_end_p1 = (info->nackfrag.seq > 0) ? info->nackfrag.set.bitmap_base + info->nackfrag.set.numbits : 0; - - /* Let caller know whether it is a nack, and, in steady state, set - final to prevent a response if it isn't. The initial - (pre-emptive) acknack is different: it'd be nice to get a - heartbeat in response. - - Who cares about an answer to an acknowledgment!? -- actually, - that'd a very useful feature in combination with directed - heartbeats, or somesuch, to get reliability guarantees. */ - nack_summary->seq_end_p1 = seq_end_p1; - nack_summary->frag_end_p1 = frag_end_p1; - nack_summary->seq_base = seq_base; - nack_summary->frag_base = frag_base; - - // [seq_base:0 .. seq_end_p1:0) and [seq_end_p1:frag_base .. seq_end_p1:frag_end_p1) if frag_end_p1 > 0 - if (seq_base > rwn->last_nack.seq_end_p1 || (seq_base == rwn->last_nack.seq_end_p1 && frag_base >= rwn->last_nack.frag_end_p1)) - { - // A NACK for something not previously NACK'd or NackDelay passed, update nack_{seq,frag} to reflect - // the changed state - info->nack_sent_on_nackdelay = false; + case DDSI_REORDER_NACKMAP_ACK: + case DDSI_REORDER_NACKMAP_SUPPRESSED_NACK: { + info->nack_sent_on_nackdelay = rwn->nack_sent_on_nackdelay; + nack_summary->seq_base = ddsi_from_seqno (info->acknack.set.bitmap_base); + nack_summary->seq_end_p1 = 0; + nack_summary->frag_base = 0; + nack_summary->frag_end_p1 = 0; + result = (bitmap_result == DDSI_REORDER_NACKMAP_ACK) ? AANR_ACK : AANR_SUPPRESSED_NACK; + break; + } + + case DDSI_REORDER_NACKMAP_NACK: { + // [seq_base:0 .. seq_end_p1:0) + [seq_end_p1:frag_base .. seq_end_p1:frag_end_p1) if frag_end_p1 > 0 + const ddsi_seqno_t seq_base = ddsi_from_seqno (info->acknack.set.bitmap_base); + assert (seq_base >= 1 && (info->acknack.set.numbits > 0 || info->nackfrag.seq > 0)); + assert (info->nackfrag.seq == 0 || info->nackfrag.set.numbits > 0); + const ddsi_seqno_t seq_end_p1 = seq_base + info->acknack.set.numbits; + const uint32_t frag_base = (info->nackfrag.seq > 0) ? info->nackfrag.set.bitmap_base : 0; + const uint32_t frag_end_p1 = (info->nackfrag.seq > 0) ? info->nackfrag.set.bitmap_base + info->nackfrag.set.numbits : 0; + + /* Let caller know whether it is a nack, and, in steady state, set + final to prevent a response if it isn't. The initial + (pre-emptive) acknack is different: it'd be nice to get a + heartbeat in response. + + Who cares about an answer to an acknowledgment!? -- actually, + that'd a very useful feature in combination with directed + heartbeats, or somesuch, to get reliability guarantees. */ + nack_summary->seq_end_p1 = seq_end_p1; + nack_summary->frag_end_p1 = frag_end_p1; + nack_summary->seq_base = seq_base; + nack_summary->frag_base = frag_base; + + // [seq_base:0 .. seq_end_p1:0) and [seq_end_p1:frag_base .. seq_end_p1:frag_end_p1) if frag_end_p1 > 0 + if (seq_base > rwn->last_nack.seq_end_p1 || (seq_base == rwn->last_nack.seq_end_p1 && frag_base >= rwn->last_nack.frag_end_p1)) + { + // A NACK for something not previously NACK'd or NackDelay passed, update nack_{seq,frag} to reflect + // the changed state + info->nack_sent_on_nackdelay = false; #if ACK_REASON_IN_FLAGS - info->flags = 0x10; + info->flags = 0x10; #endif - result = AANR_NACK; - } - else if (rwn->directed_heartbeat && (!rwn->nack_sent_on_nackdelay || nackdelay_passed)) - { - info->nack_sent_on_nackdelay = false; + result = AANR_NACK; + } + else if (rwn->directed_heartbeat && (!rwn->nack_sent_on_nackdelay || nackdelay_passed)) + { + info->nack_sent_on_nackdelay = false; #if ACK_REASON_IN_FLAGS - info->flags = 0x20; + info->flags = 0x20; #endif - result = AANR_NACK; - } - else if (nackdelay_passed) - { - info->nack_sent_on_nackdelay = true; + result = AANR_NACK; + } + else if (nackdelay_passed) + { + info->nack_sent_on_nackdelay = true; #if ACK_REASON_IN_FLAGS - info->flags = 0x30; + info->flags = 0x30; #endif - result = AANR_NACK; - } - else - { - // Overlap between this NACK and the previous one and NackDelay has not yet passed: clear numbits and - // nackfrag_numbits to turn the NACK into an ACK and pretend to the caller nothing scary is going on. + result = AANR_NACK; + } + else + { + // Overlap between this NACK and the previous one and NackDelay has not yet passed: clear numbits and + // nackfrag_numbits to turn the NACK into an ACK and pretend to the caller nothing scary is going on. #if ACK_REASON_IN_FLAGS - info->flags = 0x40; + info->flags = 0x40; #endif - info->nack_sent_on_nackdelay = rwn->nack_sent_on_nackdelay; - info->acknack.set.numbits = 0; - info->nackfrag.seq = 0; - result = AANR_SUPPRESSED_NACK; + info->nack_sent_on_nackdelay = rwn->nack_sent_on_nackdelay; + info->acknack.set.numbits = 0; + info->nackfrag.seq = 0; + result = AANR_SUPPRESSED_NACK; + } + break; } } @@ -320,9 +327,9 @@ static enum ddsi_add_acknack_result get_acknack_info (const struct ddsi_proxy_wr { // ACK and SUPPRESSED_NACK both end up being a pure ACK; send those only if we have to if (!(rwn->heartbeat_since_ack && rwn->ack_requested)) - result = AANR_SUPPRESSED_ACK; // writer didn't ask for it + result = (result == AANR_ACK ? AANR_SILENT_ACK : AANR_SILENT_NACK); // writer didn't ask for it else if (!(nack_summary->seq_base > rwn->last_nack.seq_base || ackdelay_passed)) - result = AANR_SUPPRESSED_ACK; // no progress since last, not enough time passed + result = (result == AANR_ACK ? AANR_SILENT_ACK : AANR_SILENT_NACK); // no progress since last, not enough time passed } else if (info->acknack.set.numbits == 0 && info->nackfrag.seq > 0 && !rwn->ack_requested) { @@ -333,7 +340,7 @@ static enum ddsi_add_acknack_result get_acknack_info (const struct ddsi_proxy_wr return result; } -void ddsi_sched_acknack_if_needed (struct ddsi_xevent *ev, struct ddsi_proxy_writer *pwr, struct ddsi_pwr_rd_match *rwn, ddsrt_mtime_t tnow, bool avoid_suppressed_nack) +void ddsi_sched_acknack_if_needed (struct ddsi_xevent *ev, struct ddsi_proxy_writer *pwr, struct ddsi_pwr_rd_match *rwn, ddsrt_mtime_t tnow) { // This is the relatively expensive and precise code to determine what the ACKNACK event will do, // the alternative is to do: @@ -360,15 +367,61 @@ void ddsi_sched_acknack_if_needed (struct ddsi_xevent *ev, struct ddsi_proxy_wri struct ddsi_last_nack_summary nack_summary; const enum ddsi_add_acknack_result aanr = get_acknack_info (pwr, rwn, &nack_summary, &info, ackdelay_passed, nackdelay_passed); - if (aanr == AANR_SUPPRESSED_ACK) - ; // nothing to be done now - else if (avoid_suppressed_nack && aanr == AANR_SUPPRESSED_NACK) - (void) ddsi_resched_xevent_if_earlier (ev, ddsrt_mtime_add_duration (rwn->t_last_nack, gv->config.nack_delay)); - else - (void) ddsi_resched_xevent_if_earlier (ev, tnow); + switch (aanr) + { + case AANR_SILENT_ACK: + // nothing to be done for now + break; + case AANR_ACK: + case AANR_NACK: + case AANR_NACKFRAG_ONLY: + (void) ddsi_resched_xevent_if_earlier (ev, tnow); + break; + case AANR_SILENT_NACK: + case AANR_SUPPRESSED_NACK: + (void) ddsi_resched_xevent_if_earlier (ev, ddsrt_mtime_add_duration (rwn->t_last_nack, gv->config.nack_delay)); + break; + } } -static struct ddsi_xmsg *make_and_resched_acknack (struct ddsi_xevent *ev, struct ddsi_proxy_writer *pwr, struct ddsi_pwr_rd_match *rwn, ddsrt_mtime_t tnow, bool avoid_suppressed_nack) +static bool need_to_eventually_nack (enum ddsi_add_acknack_result aanr) +{ + switch (aanr) + { + case AANR_SILENT_ACK: + case AANR_ACK: + return false; + case AANR_NACK: + case AANR_NACKFRAG_ONLY: + case AANR_SILENT_NACK: + case AANR_SUPPRESSED_NACK: + break; + } + return true; +} + +static bool need_to_eventually_nack_intv (const struct ddsi_domaingv *gv, enum ddsi_add_acknack_result aanr, int64_t *intv) +{ + switch (aanr) + { + case AANR_SILENT_ACK: + case AANR_ACK: + assert (!need_to_eventually_nack (aanr)); + return false; + case AANR_NACK: + case AANR_NACKFRAG_ONLY: + *intv = gv->config.auto_resched_nack_delay; + break; + case AANR_SILENT_NACK: + case AANR_SUPPRESSED_NACK: + *intv = gv->config.nack_delay; + break; + } + assert (need_to_eventually_nack (aanr)); + return true; +} + +static struct ddsi_xmsg *make_and_resched_acknack (struct ddsi_xevent *ev, struct ddsi_proxy_writer *pwr, struct ddsi_pwr_rd_match *rwn, ddsrt_mtime_t tnow) { struct ddsi_domaingv * const gv = pwr->e.gv; struct ddsi_xmsg *msg; @@ -380,38 +433,45 @@ static struct ddsi_xmsg *make_and_resched_acknack (struct ddsi_xevent *ev, struc tnow.v >= ddsrt_mtime_add_duration (rwn->t_last_ack, gv->config.ack_delay).v, tnow.v >= ddsrt_mtime_add_duration (rwn->t_last_nack, gv->config.nack_delay).v); - if (aanr == AANR_SUPPRESSED_ACK) + // Trivial case: no data missing, suppressing an ACK now because of the rate + if (aanr == AANR_SILENT_ACK) return NULL; - else if (avoid_suppressed_nack && aanr == AANR_SUPPRESSED_NACK) + + // Reschedule if there is data missing + if (rwn->heartbeat_since_ack || rwn->heartbeatfrag_since_ack) { - (void) ddsi_resched_xevent_if_earlier (ev, ddsrt_mtime_add_duration (rwn->t_last_nack, gv->config.nack_delay)); - return NULL; + // Responding to a heartbeat, so reschedule if there's something to NACK, then continue + // sending ACKNACK / NACK_FRAG + int64_t intv = 0; + if (need_to_eventually_nack_intv (gv, aanr, &intv)) + (void) ddsi_resched_xevent_if_earlier (ev, ddsrt_mtime_add_duration (tnow, intv)); } - else if (!(rwn->heartbeat_since_ack || rwn->heartbeatfrag_since_ack)) + else { // Not really allowed to send an ACKNACK by the spec, except we do it sometimes to recover // from packet loss after an asymmetrical disconnect where the writer never has any reason // to send a heartbeat - switch (aanr) + if (!need_to_eventually_nack (aanr)) { - case AANR_SUPPRESSED_ACK: - // handled above - assert (0); - case AANR_ACK: - // we only break the rules if we need retransmits + // If there's nothing to NACK, don't send anything and don't reschedule + return NULL; + } + else + { + // Rate-limit spontaneous (or "illegal") NACKs, do any further processing only if enough + // time has passed, else bail out after rescheduling it for the time at which we are + // willing to send it + const int64_t intv = gv->config.auto_resched_nack_delay; + const ddsrt_mtime_t tsend = ddsrt_mtime_add_duration (rwn->t_last_nack, intv); + const ddsrt_mtime_t trepeat = ddsrt_mtime_add_duration (tnow, intv); + if (tnow.v < tsend.v) + { + (void) ddsi_resched_xevent_if_earlier (ev, tsend); return NULL; - case AANR_NACK: - case AANR_NACKFRAG_ONLY: - case AANR_SUPPRESSED_NACK: - // suppress these spontaneous NACKs if they be more frequent than the auto-resched nack_delay - if (tnow.v < ddsrt_mtime_add_duration (rwn->t_last_nack, gv->config.auto_resched_nack_delay).v) - { - (void) ddsi_resched_xevent_if_earlier (ev, ddsrt_mtime_add_duration (rwn->t_last_nack, gv->config.auto_resched_nack_delay)); - return NULL; - } - break; + } + (void) ddsi_resched_xevent_if_earlier (ev, trepeat); } - } + } // Committing to sending a message in response: update the state. Note that there's still a // possibility of not sending a message, but that is only in case of failures of some sort. @@ -432,6 +492,7 @@ static struct ddsi_xmsg *make_and_resched_acknack (struct ddsi_xevent *ev, struc if ((msg = ddsi_xmsg_new (gv->xmsgpool, &rwn->rd_guid, pp, DDSI_ACKNACK_SIZE_MAX, DDSI_XMSG_KIND_CONTROL)) == NULL) { + assert (!need_to_eventually_nack (aanr) || ddsi_xevent_is_scheduled (ev)); return NULL; } @@ -459,13 +520,15 @@ static struct ddsi_xmsg *make_and_resched_acknack (struct ddsi_xevent *ev, struc { // attempt at encoding the message caused it to be dropped ddsi_xmsg_free (msg); + assert (!need_to_eventually_nack (aanr) || ddsi_xevent_is_scheduled (ev)); return NULL; } rwn->count++; switch (aanr) { - case AANR_SUPPRESSED_ACK: + case AANR_SILENT_ACK: + case AANR_SILENT_NACK: // no message: caught by the size = 0 check assert (0); break; @@ -485,21 +548,15 @@ static struct ddsi_xmsg *make_and_resched_acknack (struct ddsi_xevent *ev, struc } rwn->last_nack = nack_summary; rwn->t_last_nack = tnow; - /* If NACKing, make sure we don't give up too soon: even though - we're not allowed to send an ACKNACK unless in response to a - HEARTBEAT, I've seen too many cases of not sending an NACK - because the writing side got confused ... Better to recover - eventually. */ - (void) ddsi_resched_xevent_if_earlier (ev, ddsrt_mtime_add_duration (tnow, gv->config.auto_resched_nack_delay)); break; case AANR_SUPPRESSED_NACK: rwn->ack_requested = 0; rwn->t_last_ack = tnow; rwn->last_nack.seq_base = nack_summary.seq_base; - (void) ddsi_resched_xevent_if_earlier (ev, ddsrt_mtime_add_duration (rwn->t_last_nack, gv->config.nack_delay)); break; } GVTRACE ("send acknack(rd "PGUIDFMT" -> pwr "PGUIDFMT")\n", PGUID (rwn->rd_guid), PGUID (pwr->e.guid)); + assert (!need_to_eventually_nack (aanr) || ddsi_xevent_is_scheduled (ev)); return msg; } @@ -600,7 +657,7 @@ void ddsi_acknack_xevent_cb (struct ddsi_domaingv *gv, struct ddsi_xevent *ev, s if (!pwr->have_seen_heartbeat) msg = make_preemptive_acknack (ev, pwr, rwn, tnow); else - msg = make_and_resched_acknack (ev, pwr, rwn, tnow, false); + msg = make_and_resched_acknack (ev, pwr, rwn, tnow); ddsrt_mutex_unlock (&pwr->e.lock); /* ddsi_xpack_addmsg may sleep (for bandwidth-limited channels), so diff --git a/src/core/ddsi/src/ddsi_radmin.c b/src/core/ddsi/src/ddsi_radmin.c index 15ad336830..23f9e5a227 100644 --- a/src/core/ddsi/src/ddsi_radmin.c +++ b/src/core/ddsi/src/ddsi_radmin.c @@ -2376,7 +2376,7 @@ int ddsi_reorder_wantsample (const struct ddsi_reorder *reorder, ddsi_seqno_t se return (s == NULL || s->u.reorder.maxp1 <= seq); } -unsigned ddsi_reorder_nackmap (const struct ddsi_reorder *reorder, ddsi_seqno_t base, ddsi_seqno_t maxseq, struct ddsi_sequence_number_set_header *map, uint32_t *mapbits, uint32_t maxsz, int notail) +enum ddsi_reorder_nackmap_result ddsi_reorder_nackmap (const struct ddsi_reorder *reorder, ddsi_seqno_t base, ddsi_seqno_t maxseq, struct ddsi_sequence_number_set_header *map, uint32_t *mapbits, uint32_t maxsz, int notail) { /* reorder->next_seq-1 is the last one we delivered, so the last one we ack; maxseq is the latest sample we know exists. Valid bitmap @@ -2384,6 +2384,7 @@ unsigned ddsi_reorder_nackmap (const struct ddsi_reorder *reorder, ddsi_seqno_t that we allow length-0 bitmaps here as well. Map->numbits is bounded by max(based on sequence numbers, maxsz). */ assert (maxsz <= 256); + assert (base >= 1); /* not much point in requesting more data than we're willing to store (it would be ok if we knew we'd be able to keep up) */ if (maxsz > reorder->max_samples) @@ -2404,17 +2405,31 @@ unsigned ddsi_reorder_nackmap (const struct ddsi_reorder *reorder, ddsi_seqno_t DDS_CERROR (reorder->logcfg, "ddsi_reorder_nackmap: incorrect max sequence number supplied (maxseq %"PRIu64" base %"PRIu64")\n", maxseq, base); maxseq = base - 1; } - + + // starting point for bitmap: ACK what we delivered map->bitmap_base = ddsi_to_seqno (base); + // if maxseq == base-1 we want an empty bitmap because we delivered everything we know to exist + // if maxseq == base, we want a bitmap of size 1 to NACK the one sample with seqno == base + // ... + // numbits = min((maxseq+1 - base), maxsz) does that, albeit with the caveat that it may be + // longer than ultimately useful if some of the samples in the tail are stored in the reorder + // buffer if (maxseq + 1 - base > maxsz) map->numbits = maxsz; else map->numbits = (uint32_t) (maxseq + 1 - base); - ddsi_bitset_zero (map->numbits, mapbits); + // Early out if nothing to NACK + if (map->numbits == 0) + return DDSI_REORDER_NACKMAP_ACK; + ddsi_bitset_zero (map->numbits, mapbits); + // Reorder buffer can be treated as a sequence of intervals of available samples with gaps in + // between and with a gap between base and the first interval. The bitmap is clear, we only + // need to set the bits corresponding to the gaps in the range [base, base+numbits). struct ddsi_rsample *iv = ddsrt_avl_find_min (&reorder_sampleivtree_treedef, &reorder->sampleivtree); assert (iv == NULL || iv->u.reorder.min > base); ddsi_seqno_t i = base; + ddsi_seqno_t last_nacked_p1 = 0; while (iv && i < base + map->numbits) { for (; i < base + map->numbits && i < iv->u.reorder.min; i++) @@ -2422,20 +2437,46 @@ unsigned ddsi_reorder_nackmap (const struct ddsi_reorder *reorder, ddsi_seqno_t uint32_t x = (uint32_t) (i - base); ddsi_bitset_set (map->numbits, mapbits, x); } + last_nacked_p1 = i; i = iv->u.reorder.maxp1; iv = ddsrt_avl_find_succ (&reorder_sampleivtree_treedef, &reorder->sampleivtree, iv); } - if (notail && i < base + map->numbits) - map->numbits = (uint32_t) (i - base); - else + if (!notail) { + // Not "notail" (the normal case): NACK all remaining sequence numbers that we know + // exist and that fit in the bitmap. for (; i < base + map->numbits; i++) { uint32_t x = (uint32_t) (i - base); ddsi_bitset_set (map->numbits, mapbits, x); } + return DDSI_REORDER_NACKMAP_NACK; + } + else if (last_nacked_p1 == 0) + { + // "notail", empty reorder: it probably makes more sense to NACK one sample than to + // NACK nothing at all (given that "notail" still results in NACKs when the reorder + // buffer is not empty). + map->numbits = 1; + ddsi_bitset_set (map->numbits, mapbits, 0); + return DDSI_REORDER_NACKMAP_NACK; + } + else if (last_nacked_p1 > base) + { + // "notail", non-empty reorder, at least one bit set: truncate after the last bit we set + assert (last_nacked_p1 > base); + map->numbits = (uint32_t) (last_nacked_p1 - base); + assert (ddsi_bitset_isset (map->numbits, mapbits, map->numbits - 1)); + return DDSI_REORDER_NACKMAP_NACK; + } + else + { + // "notail", non-empty reorder, no bit set: that should mean that the delivery is behind + // by more than the bitmap can hold. Make a bitmap with a trailing 0 so we can tell the + // different cases apart just from looking at an ACKNACK. + map->numbits = 1; + return DDSI_REORDER_NACKMAP_SUPPRESSED_NACK; } - return map->numbits; } ddsi_seqno_t ddsi_reorder_next_seq (const struct ddsi_reorder *reorder) diff --git a/src/core/ddsi/src/ddsi_receive.c b/src/core/ddsi/src/ddsi_receive.c index ba49c22ef3..e96de5901d 100644 --- a/src/core/ddsi/src/ddsi_receive.c +++ b/src/core/ddsi/src/ddsi_receive.c @@ -1227,7 +1227,7 @@ static void handle_Heartbeat_helper (struct ddsi_pwr_rd_match * const wn, struct if (arg->directed_heartbeat) wn->directed_heartbeat = 1; - ddsi_sched_acknack_if_needed (wn->acknack_xevent, pwr, wn, arg->tnow_mt, true); + ddsi_sched_acknack_if_needed (wn->acknack_xevent, pwr, wn, arg->tnow_mt); } static int handle_Heartbeat (struct ddsi_receiver_state *rst, ddsrt_etime_t tnow, struct ddsi_rmsg *rmsg, const ddsi_rtps_heartbeat_t *msg, ddsrt_wctime_t timestamp, ddsi_rtps_submessage_kind_t prev_smid) diff --git a/src/core/ddsi/src/ddsi_xevent.c b/src/core/ddsi/src/ddsi_xevent.c index d4b68ebc74..15d8a21fa8 100644 --- a/src/core/ddsi/src/ddsi_xevent.c +++ b/src/core/ddsi/src/ddsi_xevent.c @@ -345,6 +345,16 @@ int ddsi_resched_xevent_if_earlier (struct ddsi_xevent *ev, ddsrt_mtime_t tsched return is_resched; } +int ddsi_xevent_is_scheduled (struct ddsi_xevent *ev) +{ + struct ddsi_xeventq *evq = ev->evq; + int is_scheduled; + ddsrt_mutex_lock (&evq->lock); + is_scheduled = (ev->tsched.v != TSCHED_DELETE && ev->tsched.v != DDS_NEVER); + ddsrt_mutex_unlock (&evq->lock); + return is_scheduled; +} + #ifndef NDEBUG bool ddsi_delete_xevent_pending (struct ddsi_xevent *ev) { From 80a4c2c633d97323314b6138328eebe975d01120 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Wed, 19 Jun 2024 20:49:53 +0200 Subject: [PATCH 152/207] Consistently set in_file to a malloc'd pointer In some cases, the input file would point to a string constant (stdin name), in some cases to a command-line argument, and in some (probably most in reality) to malloc'd address. This changes the code to always assign it to a malloc'd string. Signed-off-by: Erik Boasson --- src/tools/idlpp/src/main.c | 10 +++------- src/tools/idlpp/src/system.c | 7 +++++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/tools/idlpp/src/main.c b/src/tools/idlpp/src/main.c index 322b95fc2b..c04232f332 100644 --- a/src/tools/idlpp/src/main.c +++ b/src/tools/idlpp/src/main.c @@ -391,7 +391,8 @@ int main #endif } } else { - in_file = stdin_name; + in_file = xmalloc( strlen( stdin_name) + 1); + strcpy( in_file, stdin_name); } /* Open output file, "-" means stdout. */ if (out_file != NULL && ! str_eq( out_file, "-")) { @@ -435,11 +436,6 @@ int main fatal_error_exit: #if MCPP_LIB - /* Free malloced memory */ - if (mcpp_debug & MACRO_CALL) { - if (in_file != stdin_name) - free( in_file); - } clear_filelist(); clear_symtable(); #endif @@ -452,7 +448,7 @@ int main fclose( fp_err); clean_system(); if (in_file != NULL) - free(in_file); + free( in_file); if (mcpp_debug & MEMORY) print_heap(); diff --git a/src/tools/idlpp/src/system.c b/src/tools/idlpp/src/system.c index fa24b7ed98..523ef4e9e6 100644 --- a/src/tools/idlpp/src/system.c +++ b/src/tools/idlpp/src/system.c @@ -1406,9 +1406,11 @@ opt_search: ; /* Normalize the path-list */ if (*in_pp && ! str_eq( *in_pp, "-")) { char * tmp = norm_path( null, *in_pp, FALSE, FALSE); - if (tmp) /* The file exists */ + if (tmp) { /* The file exists */ + free(*in_pp); *in_pp = tmp; /* Else mcpp_main() will diagnose *in_pp and exit */ + } } if (! (mcpp_debug & MACRO_CALL)) { /* -K option alters behavior of -v option */ @@ -2224,7 +2226,8 @@ static char * set_files( #if SYS_FAMILY == SYS_WIN cp = bsl2sl( cp); #endif - *in_pp = cp; + *in_pp = xmalloc( strlen(cp) + 1); /* Need a new buffer */ + strcpy( *in_pp, cp); } if (mcpp_optind < argc && argv[ mcpp_optind][ 0] != '-' && *out_pp == NULL) { From d7db65c7f9def668af029890c351de6186977d58 Mon Sep 17 00:00:00 2001 From: eboasson Date: Thu, 20 Jun 2024 12:08:51 +0200 Subject: [PATCH 153/207] Fix ACKNACK event mishandling of AANR_SILENT_NACK (#2049) * Fix ACKNACK event mishandling of AANR_SILENT_NACK This case is supposed to not send anything at all, only rescheduling the event to send a NACK when we are willing to do that. The early out was missing, causing a (pure) ACK to be generated and a failing assertion in the code updating the state of last ACK sent because it was supposed to be unreachable. In a release build it should not cause more damage than a sometimes sending ACK where sending nothing was intended; in a debug build it would instead crash. Signed-off-by: Erik Boasson * Consider an event about to be deleted as scheduled The function is used only in one place, for verifying that an ACKNACK event is scheduled if data is known to be missing. It is also be ok if the event is pending deletion because that is tied to the disappearance of the writer. Signed-off-by: Erik Boasson --------- Signed-off-by: Erik Boasson --- src/core/ddsi/include/dds/ddsi/ddsi_xevent.h | 4 +- src/core/ddsi/src/ddsi_acknack.c | 96 ++++++++++---------- src/core/ddsi/src/ddsi_xevent.c | 3 +- 3 files changed, 50 insertions(+), 53 deletions(-) diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_xevent.h b/src/core/ddsi/include/dds/ddsi/ddsi_xevent.h index 524c0b83f8..e75b314acf 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_xevent.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_xevent.h @@ -55,7 +55,7 @@ void ddsi_delete_xevent (struct ddsi_xevent *ev) int ddsi_resched_xevent_if_earlier (struct ddsi_xevent *ev, ddsrt_mtime_t tsched) ddsrt_nonnull_all; -/** @brief returns whether or not the event is scheduled +/** @brief returns whether or not the event is scheduled or pending deletion * @component timed_events * * @remark: may be called from inside the event handler @@ -63,7 +63,7 @@ int ddsi_resched_xevent_if_earlier (struct ddsi_xevent *ev, ddsrt_mtime_t tsched * @param[in] ev the event for which to check whether it is scheduled * * @retval 0 not scheduled - * @retval 1 scheduled + * @retval 1 scheduled or pending deletion */ int ddsi_xevent_is_scheduled (struct ddsi_xevent *ev) ddsrt_nonnull_all; diff --git a/src/core/ddsi/src/ddsi_acknack.c b/src/core/ddsi/src/ddsi_acknack.c index 4c818e7558..3eaec25e3e 100644 --- a/src/core/ddsi/src/ddsi_acknack.c +++ b/src/core/ddsi/src/ddsi_acknack.c @@ -257,7 +257,7 @@ static enum ddsi_add_acknack_result get_acknack_info (const struct ddsi_proxy_wr result = (bitmap_result == DDSI_REORDER_NACKMAP_ACK) ? AANR_ACK : AANR_SUPPRESSED_NACK; break; } - + case DDSI_REORDER_NACKMAP_NACK: { // [seq_base:0 .. seq_end_p1:0) + [seq_end_p1:frag_base .. seq_end_p1:frag_end_p1) if frag_end_p1 > 0 const ddsi_seqno_t seq_base = ddsi_from_seqno (info->acknack.set.bitmap_base); @@ -266,12 +266,12 @@ static enum ddsi_add_acknack_result get_acknack_info (const struct ddsi_proxy_wr const ddsi_seqno_t seq_end_p1 = seq_base + info->acknack.set.numbits; const uint32_t frag_base = (info->nackfrag.seq > 0) ? info->nackfrag.set.bitmap_base : 0; const uint32_t frag_end_p1 = (info->nackfrag.seq > 0) ? info->nackfrag.set.bitmap_base + info->nackfrag.set.numbits : 0; - + /* Let caller know whether it is a nack, and, in steady state, set final to prevent a response if it isn't. The initial (pre-emptive) acknack is different: it'd be nice to get a heartbeat in response. - + Who cares about an answer to an acknowledgment!? -- actually, that'd a very useful feature in combination with directed heartbeats, or somesuch, to get reliability guarantees. */ @@ -279,7 +279,7 @@ static enum ddsi_add_acknack_result get_acknack_info (const struct ddsi_proxy_wr nack_summary->frag_end_p1 = frag_end_p1; nack_summary->seq_base = seq_base; nack_summary->frag_base = frag_base; - + // [seq_base:0 .. seq_end_p1:0) and [seq_end_p1:frag_base .. seq_end_p1:frag_end_p1) if frag_end_p1 > 0 if (seq_base > rwn->last_nack.seq_end_p1 || (seq_base == rwn->last_nack.seq_end_p1 && frag_base >= rwn->last_nack.frag_end_p1)) { @@ -323,6 +323,10 @@ static enum ddsi_add_acknack_result get_acknack_info (const struct ddsi_proxy_wr } } + // all cases of enum ddsi_reorder_nackmap_result are covered above, so: + // result initialization is dead code (but needed because C and some compilers) and: + assert (result == AANR_ACK || result == AANR_NACK || result == AANR_SUPPRESSED_NACK); + if (result == AANR_ACK || result == AANR_SUPPRESSED_NACK) { // ACK and SUPPRESSED_NACK both end up being a pure ACK; send those only if we have to @@ -384,6 +388,7 @@ void ddsi_sched_acknack_if_needed (struct ddsi_xevent *ev, struct ddsi_proxy_wri } } +#ifndef NDEBUG static bool need_to_eventually_nack (enum ddsi_add_acknack_result aanr) { switch (aanr) @@ -399,26 +404,42 @@ static bool need_to_eventually_nack (enum ddsi_add_acknack_result aanr) } return true; } +#endif -static bool need_to_eventually_nack_intv (const struct ddsi_domaingv *gv, enum ddsi_add_acknack_result aanr, int64_t *intv) +static void resched_acknack_if_data_missing (struct ddsi_xevent *ev, struct ddsi_proxy_writer *pwr, struct ddsi_pwr_rd_match *rwn, ddsrt_mtime_t tnow, const enum ddsi_add_acknack_result aanr) { switch (aanr) { - case AANR_SILENT_ACK: case AANR_ACK: - assert (!need_to_eventually_nack (aanr)); - return false; + // Sending something, nothing missing so no need to reschedule + break; + + case AANR_SILENT_ACK: + // Not sending anything, nothing missing so no need to reschedule + break; + case AANR_NACK: case AANR_NACKFRAG_ONLY: - *intv = gv->config.auto_resched_nack_delay; + // Sending a retransmit request now, reschedule because requesting data isn't a guarantee + // we'll get it. + (void) ddsi_resched_xevent_if_earlier (ev, ddsrt_mtime_add_duration (tnow, pwr->e.gv->config.auto_resched_nack_delay)); break; + case AANR_SILENT_NACK: - case AANR_SUPPRESSED_NACK: - *intv = gv->config.nack_delay; + case AANR_SUPPRESSED_NACK: { + // Not sending anything or only sending an ACK, despite knowing we are missing data. + // + // Rate-limit spontaneous (or "illegal") NACKs, do any further processing only if enough + // time has passed, else bail out after rescheduling it for the time at which we are + // willing to send it + const int64_t intv = pwr->e.gv->config.nack_delay; + ddsrt_mtime_t tnext = ddsrt_mtime_add_duration (rwn->t_last_nack, intv); + if (tnext.v < tnow.v) + tnext = ddsrt_mtime_add_duration (tnow, intv); + ddsi_resched_xevent_if_earlier (ev, tnext); break; + } } - assert (need_to_eventually_nack (aanr)); - return true; } static struct ddsi_xmsg *make_and_resched_acknack (struct ddsi_xevent *ev, struct ddsi_proxy_writer *pwr, struct ddsi_pwr_rd_match *rwn, ddsrt_mtime_t tnow) @@ -433,44 +454,19 @@ static struct ddsi_xmsg *make_and_resched_acknack (struct ddsi_xevent *ev, struc tnow.v >= ddsrt_mtime_add_duration (rwn->t_last_ack, gv->config.ack_delay).v, tnow.v >= ddsrt_mtime_add_duration (rwn->t_last_nack, gv->config.nack_delay).v); - // Trivial case: no data missing, suppressing an ACK now because of the rate - if (aanr == AANR_SILENT_ACK) - return NULL; - - // Reschedule if there is data missing - if (rwn->heartbeat_since_ack || rwn->heartbeatfrag_since_ack) - { - // Responding to a heartbeat, so reschedule if there's something to NACK, then continue - // sending ACKNACK / NACK_FRAG - int64_t intv = 0; - if (need_to_eventually_nack_intv (gv, aanr, &intv)) - (void) ddsi_resched_xevent_if_earlier (ev, ddsrt_mtime_add_duration (tnow, intv)); - } - else + // Reschedule in cases there is data missing, bail out if not sending anything at all + resched_acknack_if_data_missing (ev, pwr, rwn, tnow, aanr); + switch (aanr) { - // Not really allowed to send an ACKNACK by the spec, except we do it sometimes to recover - // from packet loss after an asymmetrical disconnect where the writer never has any reason - // to send a heartbeat - if (!need_to_eventually_nack (aanr)) - { - // If there's nothing to NACK, don't send anything and don't reschedule + case AANR_SILENT_ACK: + case AANR_SILENT_NACK: + assert (!need_to_eventually_nack (aanr) || ddsi_xevent_is_scheduled (ev)); return NULL; - } - else - { - // Rate-limit spontaneous (or "illegal") NACKs, do any further processing only if enough - // time has passed, else bail out after rescheduling it for the time at which we are - // willing to send it - const int64_t intv = gv->config.auto_resched_nack_delay; - const ddsrt_mtime_t tsend = ddsrt_mtime_add_duration (rwn->t_last_nack, intv); - const ddsrt_mtime_t trepeat = ddsrt_mtime_add_duration (tnow, intv); - if (tnow.v < tsend.v) - { - (void) ddsi_resched_xevent_if_earlier (ev, tsend); - return NULL; - } - (void) ddsi_resched_xevent_if_earlier (ev, trepeat); - } + case AANR_ACK: + case AANR_NACK: + case AANR_NACKFRAG_ONLY: + case AANR_SUPPRESSED_NACK: + break; } // Committing to sending a message in response: update the state. Note that there's still a @@ -529,7 +525,7 @@ static struct ddsi_xmsg *make_and_resched_acknack (struct ddsi_xevent *ev, struc { case AANR_SILENT_ACK: case AANR_SILENT_NACK: - // no message: caught by the size = 0 check + // can't be reached because of early returns assert (0); break; case AANR_ACK: diff --git a/src/core/ddsi/src/ddsi_xevent.c b/src/core/ddsi/src/ddsi_xevent.c index 15d8a21fa8..51505cd529 100644 --- a/src/core/ddsi/src/ddsi_xevent.c +++ b/src/core/ddsi/src/ddsi_xevent.c @@ -350,7 +350,8 @@ int ddsi_xevent_is_scheduled (struct ddsi_xevent *ev) struct ddsi_xeventq *evq = ev->evq; int is_scheduled; ddsrt_mutex_lock (&evq->lock); - is_scheduled = (ev->tsched.v != TSCHED_DELETE && ev->tsched.v != DDS_NEVER); + // Also considers it scheduled if it is about to be deleted + is_scheduled = (ev->tsched.v != DDS_NEVER); ddsrt_mutex_unlock (&evq->lock); return is_scheduled; } From ce7cf3dc05041db863396466c20971ba6fca6bd5 Mon Sep 17 00:00:00 2001 From: Philip Oetinger Date: Mon, 1 Jul 2024 12:07:44 +0200 Subject: [PATCH 154/207] check return value of `X509_digest` Section 4.3.1.1 of X41's security audit found a potential vulnerability where potentially two uninitialized stack values could result in incorrect behaviour. --- .../authentication/src/authentication.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/security/builtin_plugins/authentication/src/authentication.c b/src/security/builtin_plugins/authentication/src/authentication.c index 26eda30987..cd5d71968c 100644 --- a/src/security/builtin_plugins/authentication/src/authentication.c +++ b/src/security/builtin_plugins/authentication/src/authentication.c @@ -716,14 +716,17 @@ DDS_Security_ValidationResult_t validate_local_identity(dds_security_authenticat unsigned char hash_buffer[20], hash_buffer_trusted[20]; DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_FAILED; - X509_digest(identityCA, digest, hash_buffer, &size); - for (unsigned i = 0; i < implementation->trustedCAList.length; ++i) - { - X509_digest(implementation->trustedCAList.buffer[i], digest, hash_buffer_trusted, &size); - if (memcmp(hash_buffer_trusted, hash_buffer, 20) == 0) + // OpenSSL return value type int: 1 = success, 0 = fail + int digest_result = X509_digest(identityCA, digest, hash_buffer, &size); + if (digest_result) { + for (unsigned i = 0; i < implementation->trustedCAList.length; ++i) { - result = DDS_SECURITY_VALIDATION_OK; - break; + digest_result = X509_digest(implementation->trustedCAList.buffer[i], digest, hash_buffer_trusted, &size); + if (digest_result && (memcmp(hash_buffer_trusted, hash_buffer, 20) == 0)) // Do not compare potentially uninitialized values + { + result = DDS_SECURITY_VALIDATION_OK; + break; + } } } if (result != DDS_SECURITY_VALIDATION_OK) From f5e5d6c42a1c08d481f0a69413561a496026d68a Mon Sep 17 00:00:00 2001 From: Michel <58435247+mvandenhoek@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:29:26 +0200 Subject: [PATCH 155/207] Tests and fixes for PSMX interface This adds some tests verifying that the configuration, API and PSMX interface are aligned. It fixes the initialization code to reject a configuration that defines multiple plugins. Signed-off-by: Michel van den Hoek --- src/core/ddsc/src/dds_psmx.c | 44 ++- src/core/ddsc/tests/CMakeLists.txt | 40 ++- src/core/ddsc/tests/psmx.c | 49 ++-- src/core/ddsc/tests/psmx_dummy_impl.c | 203 +++++++++++++ src/core/ddsc/tests/psmx_dummy_impl.h | 26 ++ src/core/ddsc/tests/psmx_dummy_public.h | 71 +++++ src/core/ddsc/tests/psmxif.c | 361 ++++++++++++++++++++++++ 7 files changed, 747 insertions(+), 47 deletions(-) create mode 100644 src/core/ddsc/tests/psmx_dummy_impl.c create mode 100644 src/core/ddsc/tests/psmx_dummy_impl.h create mode 100644 src/core/ddsc/tests/psmx_dummy_public.h create mode 100644 src/core/ddsc/tests/psmxif.c diff --git a/src/core/ddsc/src/dds_psmx.c b/src/core/ddsc/src/dds_psmx.c index d382c1524d..19260e8665 100644 --- a/src/core/ddsc/src/dds_psmx.c +++ b/src/core/ddsc/src/dds_psmx.c @@ -327,40 +327,32 @@ static dds_return_t psmx_instance_load (const struct ddsi_domaingv *gv, const st return ret; } -static int compare_psmx_prio (const void *va, const void *vb) -{ - const struct dds_psmx *psmx1 = va; - const struct dds_psmx *psmx2 = vb; - return (psmx1->priority == psmx2->priority) ? 0 : ((psmx1->priority < psmx2->priority) ? 1 : -1); -} - dds_return_t dds_pubsub_message_exchange_init (const struct ddsi_domaingv *gv, struct dds_domain *domain) { dds_return_t ret = DDS_RETCODE_OK; if (gv->config.psmx_instances != NULL) { struct ddsi_config_psmx_listelem *iface = gv->config.psmx_instances; - while (iface && domain->psmx_instances.length < DDS_MAX_PSMX_INSTANCES) - { - GVLOG(DDS_LC_INFO, "Loading PSMX instances %s\n", iface->cfg.name); - struct dds_psmx *psmx = NULL; - ddsrt_dynlib_t lib_handle; - if (psmx_instance_load (gv, &iface->cfg, &psmx, &lib_handle) == DDS_RETCODE_OK) - { - domain->psmx_instances.instances[domain->psmx_instances.length] = psmx; - domain->psmx_instances.lib_handles[domain->psmx_instances.length] = lib_handle; - domain->psmx_instances.length++; - } - else - { - GVERROR ("error loading PSMX instance \"%s\"\n", iface->cfg.name); - ret = DDS_RETCODE_ERROR; - break; + if ( iface != NULL ) { + if ( iface->next != NULL ) { + ret = DDS_RETCODE_UNSUPPORTED; // Only one psmx interface is supported. + }else{ + GVLOG(DDS_LC_INFO, "Loading PSMX instances %s\n", iface->cfg.name); + struct dds_psmx *psmx = NULL; + ddsrt_dynlib_t lib_handle; + if (psmx_instance_load (gv, &iface->cfg, &psmx, &lib_handle) == DDS_RETCODE_OK) + { + domain->psmx_instances.instances[domain->psmx_instances.length] = psmx; + domain->psmx_instances.lib_handles[domain->psmx_instances.length] = lib_handle; + domain->psmx_instances.length++; + } + else + { + GVERROR ("error loading PSMX instance \"%s\"\n", iface->cfg.name); + ret = DDS_RETCODE_ERROR; + } } - iface = iface->next; } - - qsort (domain->psmx_instances.instances, domain->psmx_instances.length, sizeof (*domain->psmx_instances.instances), compare_psmx_prio); } return ret; } diff --git a/src/core/ddsc/tests/CMakeLists.txt b/src/core/ddsc/tests/CMakeLists.txt index 27007b0357..b54e40ad0f 100644 --- a/src/core/ddsc/tests/CMakeLists.txt +++ b/src/core/ddsc/tests/CMakeLists.txt @@ -63,6 +63,7 @@ set(ddsc_test_sources "nwpart.c" "participant.c" "pp_lease_dur.c" + "psmxif.c" "publisher.c" "qos.c" "qosmatch.c" @@ -157,10 +158,43 @@ if(ENABLE_QOS_PROVIDER) "qos_provider.c") endif() +# PSMX dummy implementation for interface testing +if(BUILD_SHARED_LIBS) + add_library(psmx_dummy SHARED "psmx_dummy_impl.c") +else() + add_library(psmx_dummy OBJECT "psmx_dummy_impl.c") + set_property(GLOBAL APPEND PROPERTY cdds_plugin_list psmx_dummy) + set_property(GLOBAL PROPERTY psmx_dummy_symbols dummy_create_psmx) +endif() +generate_export_header(psmx_dummy BASE_NAME PSMX_DUMMY EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/include/dds/psmx_dummy/export.h") +target_include_directories( + psmx_dummy PRIVATE + "$" + "$" + "$" + "$" + "$" + "$" + "$" + "$" +) +if(BUILD_SHARED_LIBS) + target_link_libraries(psmx_dummy PRIVATE ddsc) +else() + install( + TARGETS psmx_dummy + EXPORT "${PROJECT_NAME}" + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) +endif() + + add_cunit_executable(cunit_ddsc ${ddsc_test_sources}) target_include_directories( cunit_ddsc PRIVATE "$" + "$" "$" "$" "$" @@ -181,6 +215,7 @@ target_link_libraries(cunit_ddsc PRIVATE CdrStreamSkipDefault CdrStreamDataTypeInfo PsmxDataModels + psmx_dummy DynamicData Array100 CdrStreamKeySize @@ -243,7 +278,6 @@ target_include_directories( target_link_libraries(oneliner PRIVATE RoundTrip Space ddsc) - # PSMX implementation with Cyclone as transport, for testing if (BUILD_SHARED_LIBS) idlc_generate(TARGET psmx_cdds_data FILES psmx_cdds_data.idl) @@ -258,10 +292,6 @@ if (BUILD_SHARED_LIBS) target_link_libraries(psmx_cdds PRIVATE ddsc psmx_cdds_data) generate_export_header(psmx_cdds BASE_NAME PSMX_CDDS EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/include/dds/psmx_cdds/export.h") - - install(TARGETS psmx_cdds - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) endif() # If Iceoryx is available, then also run all PSMX tests using Iceoryx. Colcon complicates diff --git a/src/core/ddsc/tests/psmx.c b/src/core/ddsc/tests/psmx.c index 050e537115..bb55fb6580 100644 --- a/src/core/ddsc/tests/psmx.c +++ b/src/core/ddsc/tests/psmx.c @@ -113,22 +113,13 @@ static bool endpoint_has_psmx_enabled (dds_entity_t rd_or_wr) bool psmx_enabled = false; rc = dds_entity_pin (rd_or_wr, &x); CU_ASSERT_FATAL (rc == DDS_RETCODE_OK); - switch (dds_entity_kind (x)) - { - case DDS_KIND_READER: { - struct dds_reader const * const rd = (struct dds_reader *) x; - psmx_enabled = (rd->m_endpoint.psmx_endpoints.length > 0); - break; - } - case DDS_KIND_WRITER: { - struct dds_writer const * const wr = (struct dds_writer *) x; - psmx_enabled = (wr->m_endpoint.psmx_endpoints.length > 0); - break; - } - default: { - CU_ASSERT_FATAL (dds_entity_kind (x) == DDS_KIND_READER || dds_entity_kind (x) == DDS_KIND_WRITER); - break; - } + if ( dds_entity_kind (x) == DDS_KIND_READER ) { + struct dds_reader const * const rd = (struct dds_reader *) x; + psmx_enabled = (rd->m_endpoint.psmx_endpoints.length > 0); + } else { + CU_ASSERT_FATAL(dds_entity_kind (x) == DDS_KIND_WRITER); + struct dds_writer const * const wr = (struct dds_writer *) x; + psmx_enabled = (wr->m_endpoint.psmx_endpoints.length > 0); } dds_entity_unpin (x); return psmx_enabled; @@ -1208,6 +1199,32 @@ CU_Test(ddsc_psmx, partition_xtalk) CU_ASSERT_FATAL (rc == 0); } +/// @brief Check that shared memory is not supported by endpoints created from a default Cyclone domain. +/// @methodology +/// - Create endpoints with a from a default domain. +/// - Assert that shared memory is not available. +CU_Test(ddsc_psmx, no_shared_memory) +{ + dds_entity_t participant, topic, writer, reader; + + participant = dds_create_participant(0, NULL, NULL); + CU_ASSERT_FATAL(participant > 0); + + char topicname[100]; + create_unique_topic_name("test_psmx_no_shared_memory", topicname, sizeof(topicname)); + topic = dds_create_topic(participant, &SC_Model_desc, topicname, NULL, NULL); + CU_ASSERT_FATAL(topic > 0); + + writer = dds_create_writer(participant, topic, NULL, NULL); + CU_ASSERT_FATAL(writer > 0); + + reader = dds_create_reader(participant, topic, NULL, NULL); + CU_ASSERT_FATAL(reader > 0); + + CU_ASSERT_FATAL(!dds_is_shared_memory_available(writer)); + CU_ASSERT_FATAL(!dds_is_shared_memory_available(reader)); + dds_delete(dds_get_parent(participant)); +} #define MAX_SAMPLES 8 CU_Test (ddsc_psmx, basic) diff --git a/src/core/ddsc/tests/psmx_dummy_impl.c b/src/core/ddsc/tests/psmx_dummy_impl.c new file mode 100644 index 0000000000..f11e7a1795 --- /dev/null +++ b/src/core/ddsc/tests/psmx_dummy_impl.c @@ -0,0 +1,203 @@ + +#include +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/string.h" +#include "dds/ddsrt/strtol.h" +#include "dds/ddsi/ddsi_locator.h" +#include "dds/ddsc/dds_psmx.h" +#include "psmx_dummy_public.h" +#include "psmx_dummy_impl.h" + +static dummy_mockstats_t g_mockstats; + +dummy_mockstats_t* dummy_mockstats_get_ptr(void) +{ + return &g_mockstats; +} + +void dummy_topics_alloc(dummy_mockstats_t* mockstats, size_t topics_capacity) +{ + mockstats->topics._maximum = topics_capacity; + mockstats->topics._length = 0; + mockstats->topics._buffer = ddsrt_malloc(topics_capacity * sizeof(dds_psmx_topic_t)); +} + +void dummy_endpoints_alloc(dummy_mockstats_t* mockstats, size_t endpoints_capacity) +{ + mockstats->endpoints._maximum = endpoints_capacity; + mockstats->endpoints._length = 0; + mockstats->endpoints._buffer = ddsrt_malloc(endpoints_capacity * sizeof(dds_psmx_endpoint_t)); +} + +static void dummy_psmx_loan_free(dds_loaned_sample_t* loan) +{ + (void)loan; +} + +static dds_loaned_sample_t* dummy_psmx_ep_request_loan(dds_psmx_endpoint_t* psmx_endpoint, uint32_t size_requested) +{ + (void)size_requested; + ++g_mockstats.cnt_request_loan; + g_mockstats.request_loan_rcv_endpt = psmx_endpoint; + memset(&g_mockstats.loan, 0x0, sizeof(dds_loaned_sample_t)); + memset(&g_mockstats.loan_metadata, 0x0, sizeof(dds_psmx_metadata_t)); + g_mockstats.loan.ops.free = dummy_psmx_loan_free; + g_mockstats.loan.loan_origin.origin_kind = DDS_LOAN_ORIGIN_KIND_PSMX; + g_mockstats.loan.loan_origin.psmx_endpoint = psmx_endpoint; + g_mockstats.loan.metadata = &g_mockstats.loan_metadata; + g_mockstats.loan.sample_ptr = (void*)0x1; + ddsrt_atomic_st32(&g_mockstats.loan.refc, 1); + return &g_mockstats.loan; +} + +static dds_return_t dummy_psmx_ep_write(dds_psmx_endpoint_t* psmx_endpoint, dds_loaned_sample_t* data) +{ + (void)psmx_endpoint; + (void)data; + // Details yet to be implemented + ++g_mockstats.cnt_write; + g_mockstats.write_rcv_endpt = psmx_endpoint; + g_mockstats.write_rcv_loan = data; + return DDS_RETCODE_OK; +} + +static dds_loaned_sample_t* dummy_psmx_ep_take(dds_psmx_endpoint_t* psmx_endpoint) +{ + (void)psmx_endpoint; + // Details yet to be implemented + ++g_mockstats.cnt_take; + return NULL; +} + +static dds_return_t dummy_psmx_ep_on_data_available(dds_psmx_endpoint_t* psmx_endpoint, dds_entity_t reader) +{ + (void)psmx_endpoint; + (void)reader; + // Details yet to be implemented + ++g_mockstats.cnt_on_data_available; + return DDS_RETCODE_OK; +} + +static dds_psmx_endpoint_t* dummy_psmx_create_endpoint( + dds_psmx_topic_t* psmx_topic, + const struct dds_qos* qos, + dds_psmx_endpoint_type_t endpoint_type +) { + (void)qos; + dds_psmx_endpoint_t* endp = (dds_psmx_endpoint_t*)g_mockstats.endpoints._buffer + g_mockstats.endpoints._length++; + memset(endp, 0, sizeof(dds_psmx_endpoint_t)); + endp->ops.request_loan = dummy_psmx_ep_request_loan; + endp->ops.write = dummy_psmx_ep_write; + endp->ops.take = dummy_psmx_ep_take; + endp->ops.on_data_available = dummy_psmx_ep_on_data_available; + + endp->psmx_topic = psmx_topic; + endp->endpoint_type = endpoint_type; + dds_add_psmx_endpoint_to_list(endp, &psmx_topic->psmx_endpoints); + + ++g_mockstats.cnt_create_endpoint; + g_mockstats.create_endpoint_rcv_topic = psmx_topic; + return endp; +} + +static dds_return_t dummy_psmx_delete_endpoint(dds_psmx_endpoint_t* psmx_endpoint) +{ + memset(psmx_endpoint, 0x0, sizeof(dds_psmx_endpoint_t)); + ++g_mockstats.cnt_delete_endpoint; + g_mockstats.delete_endpoint_rcv_endpt = psmx_endpoint; + return DDS_RETCODE_OK; +} + +static bool dummy_psmx_type_qos_supported( + dds_psmx_t* psmx, + dds_psmx_endpoint_type_t forwhat, + dds_data_type_properties_t data_type_props, + const struct dds_qos* qos +) { + (void)psmx; + (void)forwhat; + (void)data_type_props; + (void)qos; + ++g_mockstats.cnt_type_qos_supported; + return true; +} + +static dds_psmx_topic_t* dummy_psmx_create_topic( + dds_psmx_t* psmx, + const char* topic_name, + const char* type_name, + dds_data_type_properties_t data_type_props +) { + (void)data_type_props; + assert(g_mockstats.topics._length < g_mockstats.topics._maximum); + dds_psmx_topic_t* topic = (dds_psmx_topic_t*)g_mockstats.topics._buffer + g_mockstats.topics._length++; + memset(topic, 0, sizeof(dds_psmx_topic_t)); + topic->ops.create_endpoint = dummy_psmx_create_endpoint; + topic->ops.delete_endpoint = dummy_psmx_delete_endpoint; + topic->psmx_instance = psmx; + topic->topic_name = ddsrt_strdup(topic_name); + topic->type_name = ddsrt_strdup(type_name); + dds_add_psmx_topic_to_list(topic, &psmx->psmx_topics); + ++g_mockstats.cnt_create_topic; + return topic; +} + +static dds_return_t dummy_psmx_delete_topic(dds_psmx_topic_t* psmx_topic) +{ + dds_psmx_topic_cleanup_generic(psmx_topic); + memset(psmx_topic, 0x0, sizeof(dds_psmx_topic_t)); + ++g_mockstats.cnt_delete_topic; + return DDS_RETCODE_OK; +} + +static dds_return_t dummy_psmx_deinit(dds_psmx_t* psmx) +{ + dds_psmx_cleanup_generic(psmx); + dds_free(psmx); + ++g_mockstats.cnt_deinit; + ddsrt_free(g_mockstats.config); + ddsrt_free(g_mockstats.topics._buffer); + ddsrt_free(g_mockstats.endpoints._buffer); + return DDS_RETCODE_OK; +} + +static dds_psmx_node_identifier_t dummy_psmx_get_node_id(const dds_psmx_t* psmx) +{ + (void)psmx; + dds_psmx_node_identifier_t node_id; + memset(&node_id, 0, sizeof(dds_psmx_node_identifier_t)); + ++g_mockstats.cnt_get_node_id; + return node_id; +} + +static dds_psmx_features_t dummy_supported_features(const dds_psmx_t* psmx) +{ + (void)psmx; + ++g_mockstats.cnt_supported_features; + return g_mockstats.supports_shared_memory ? (DDS_PSMX_FEATURE_SHARED_MEMORY | DDS_PSMX_FEATURE_ZERO_COPY) : 0; +} + +dds_return_t dummy_create_psmx(dds_psmx_t** psmx_out, dds_psmx_instance_id_t instance_id, const char* config) +{ + assert(psmx_out); + memset(&g_mockstats, 0, sizeof(dummy_mockstats_t)); + g_mockstats.cnt_create_psmx = 1; + + dds_psmx_t* psmx = dds_alloc(sizeof(dds_psmx_t)); + memset(psmx, 0, sizeof(dds_psmx_t)); + psmx->instance_name = dds_string_dup("dummy_psmx"); + psmx->instance_id = instance_id; + + psmx->ops.type_qos_supported = dummy_psmx_type_qos_supported; + psmx->ops.create_topic = dummy_psmx_create_topic; + psmx->ops.delete_topic = dummy_psmx_delete_topic; + psmx->ops.deinit = dummy_psmx_deinit; + psmx->ops.get_node_id = dummy_psmx_get_node_id; + psmx->ops.supported_features = dummy_supported_features; + dds_psmx_init_generic(psmx); + + g_mockstats.config = ddsrt_strdup(config); + + *psmx_out = psmx; + return DDS_RETCODE_OK; +} diff --git a/src/core/ddsc/tests/psmx_dummy_impl.h b/src/core/ddsc/tests/psmx_dummy_impl.h new file mode 100644 index 0000000000..1e03474f4c --- /dev/null +++ b/src/core/ddsc/tests/psmx_dummy_impl.h @@ -0,0 +1,26 @@ +// Copyright(c) 2023 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#ifndef PSMX_DUMMY_IMPL_H +#define PSMX_DUMMY_IMPL_H + +#include "dds/psmx_dummy/export.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +PSMX_DUMMY_EXPORT dds_return_t dummy_create_psmx(dds_psmx_t **psmx, dds_psmx_instance_id_t instance_id, const char *config); + +#if defined (__cplusplus) +} +#endif + +#endif /* PSMX_DUMMY_IMPL_H */ diff --git a/src/core/ddsc/tests/psmx_dummy_public.h b/src/core/ddsc/tests/psmx_dummy_public.h new file mode 100644 index 0000000000..176ec63f4a --- /dev/null +++ b/src/core/ddsc/tests/psmx_dummy_public.h @@ -0,0 +1,71 @@ + +// Copyright(c) 2023 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#ifndef PSMX_DUMMY_PUBLIC_H +#define PSMX_DUMMY_PUBLIC_H + +#include "dds/psmx_dummy/export.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +typedef struct dynamic_array_s{ + size_t _maximum; + size_t _length; + void* _buffer; +}dynamic_array_t; + +typedef struct dummy_mockstats_s{ + int cnt_create_psmx; + + // dds_psmx_ops + int cnt_type_qos_supported; + int cnt_create_topic; + int cnt_delete_topic; + int cnt_deinit; + int cnt_get_node_id; + int cnt_supported_features; + + // dds_psmx_topic_ops + int cnt_create_endpoint; + int cnt_delete_endpoint; + + // dds_psmx_endpoint_ops + int cnt_request_loan; + int cnt_write; + int cnt_take; + int cnt_on_data_available; + + // Exposed internals + bool supports_shared_memory; + char* config; + dynamic_array_t topics; + dynamic_array_t endpoints; + dds_loaned_sample_t loan; + dds_psmx_metadata_t loan_metadata; + + dds_psmx_topic_t* create_endpoint_rcv_topic; + dds_psmx_endpoint_t* delete_endpoint_rcv_endpt; + dds_psmx_endpoint_t* request_loan_rcv_endpt; + dds_psmx_endpoint_t* write_rcv_endpt; + dds_loaned_sample_t* write_rcv_loan; +}dummy_mockstats_t; + +PSMX_DUMMY_EXPORT dummy_mockstats_t* dummy_mockstats_get_ptr(void); +PSMX_DUMMY_EXPORT void dummy_topics_alloc(dummy_mockstats_t* mockstats, size_t topics_capacity); +PSMX_DUMMY_EXPORT void dummy_endpoints_alloc(dummy_mockstats_t* mockstats, size_t endpoints_capacity); + +#if defined (__cplusplus) +} +#endif + +#endif /* PSMX_DUMMY_PUBLIC_H */ diff --git a/src/core/ddsc/tests/psmxif.c b/src/core/ddsc/tests/psmxif.c new file mode 100644 index 0000000000..cdccc554a0 --- /dev/null +++ b/src/core/ddsc/tests/psmxif.c @@ -0,0 +1,361 @@ +// Copyright(c) 2020 to 2023 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#include +#include + +#include "dds/ddsrt/mh3.h" +#include "dds/ddsrt/md5.h" +#include "dds/ddsrt/io.h" +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/string.h" +#include "dds/ddsrt/bswap.h" +#include "dds/ddsrt/environ.h" +#include "dds/ddsrt/static_assert.h" + +#include "dds/dds.h" +#include "dds/ddsi/ddsi_entity_index.h" +#include "ddsi__addrset.h" +#include "ddsi__entity.h" +#include "ddsi__xevent.h" +#include "dds__entity.h" +#include "dds__serdata_default.h" + +#include "config_env.h" +#include "test_common.h" +#include "psmx_dummy_public.h" +#include "Array100.h" +#include "DynamicData.h" +#include "PsmxDataModels.h" + +static void free_strings(uint32_t len, char** strings) +{ + if (len != 0 && strings != NULL) { + for (uint32_t i = 0; i < len; i++) { + dds_free(strings[i]); + } + } + dds_free(strings); +} + +/** @brief Convert a set of stats to a string. + * + * Truncates the output string if the string buffer capacity is too small. + * + * @param[in] dmock stats to convert + * @param[out] str_out string buffer to write the string into + * @param[in] str_capacity number of bytes the string buffer can hold + * + * @return Upon successful return, it returns the number of characters printed + * (excluding the null byte used to end output to strings). + * If an output error is encountered, a negative value is returned. +*/ +static int dummy_mockstats_tostring(const dummy_mockstats_t* dmock, char* str_out, size_t str_capacity) +{ + return snprintf( + str_out, + str_capacity, + "\ + create_psmx: %i\n\ + \n\ + type_qos_supported: %i\n\ + create_topic: %i\n\ + delete_topic: %i\n\ + deinit: %i\n\ + get_node_id: %i\n\ + supported_features: %i\n\ + \n\ + create_endpoint: %i\n\ + delete_endpoint: %i\n\ + \n\ + request_loan: %i\n\ + write: %i\n\ + take: %i\n\ + on_data_available: %i\n", + dmock->cnt_create_psmx, + dmock->cnt_type_qos_supported, + dmock->cnt_create_topic, + dmock->cnt_delete_topic, + dmock->cnt_deinit, + dmock->cnt_get_node_id, + dmock->cnt_supported_features, + dmock->cnt_create_endpoint, + dmock->cnt_delete_endpoint, + dmock->cnt_request_loan, + dmock->cnt_write, + dmock->cnt_take, + dmock->cnt_on_data_available + ); +} + +static dds_entity_t create_participant(dds_domainid_t domainId) +{ + char configstr[] = "\ +${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}\ +\ +spdp\ +\ + \ +\ +\ +\ +cdds.log.0\ +\ +"; + char* configstr_in = ddsrt_expand_envvars (configstr, domainId); + const dds_entity_t domain = dds_create_domain(domainId, configstr_in); + ddsrt_free(configstr_in); + CU_ASSERT_FATAL(domain > 0); + const dds_entity_t participant = dds_create_participant(domainId, NULL, NULL); + CU_ASSERT_FATAL(participant > 0); + return participant; +} + +/// @brief Check that creating a domain with more than one psmx interface fails. +/// @methodology +/// - Create a config string with two psmx interfaces. +/// - Try to create a domain using this config string. +/// - Expectation: Failed to create the domain. +/// +CU_Test(ddsc_psmxif, config_multiple_psmx) +{ + dds_domainid_t domainId = 0; + char* configstr_in = NULL; + { + char configstr[] = "\ +${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}\ +\ + spdp\ + \ + \ + \ + \ +\ +\ + ${CYCLONEDDS_PID}\ + 0\ +\ +\ + cdds.log.0\ +\ + "; + configstr_in = ddsrt_expand_envvars(configstr, domainId); + } + const dds_entity_t domain = dds_create_domain (domainId, configstr_in); + ddsrt_free(configstr_in); + CU_ASSERT_FATAL(domain <= 0); +} + +static void assert_psmx_instance_name(dds_entity_t endpt, const char* name_expected) +{ + dds_qos_t* qos = dds_create_qos(); + dds_get_qos(endpt, qos); + uint32_t strs_len = 0; + char** strs = NULL; + CU_ASSERT_FATAL(dds_qget_psmx_instances(qos, &strs_len, &strs)); + CU_ASSERT_FATAL(strs_len == 1 && strcmp(strs[0], name_expected) == 0); + free_strings(strs_len, strs); + dds_delete_qos(qos); +} + +/// @brief Check that the instance_name is as provided from dummy_create_psmx(). +/// @methodology +/// - Create domain with a config containing the name for the psmx instance. +/// - Create readers and writers. +/// - Using the QoS interface, for each endpoint check that the instance_name is correct. +/// +CU_Test(ddsc_psmxif, instance_name) +{ + const dds_domainid_t domainId = 0; + dds_entity_t participant = create_participant(domainId); + dds_entity_t domain = dds_get_parent(participant); + dummy_mockstats_t* dmock = dummy_mockstats_get_ptr(); + + dds_entity_t writer1 = 0, reader1 = 0, writer2 = 0, reader2 = 0; + + char topicname[100]; + dummy_topics_alloc(dmock, 2); + dummy_endpoints_alloc(dmock, 4); + + create_unique_topic_name("shared_memory", topicname, sizeof(topicname)); + dds_entity_t topic1 = dds_create_topic(participant, &SC_Model_desc, topicname, NULL, NULL); + CU_ASSERT_FATAL(topic1 > 0); + create_unique_topic_name("shared_memory", topicname, sizeof(topicname)); + dds_entity_t topic2 = dds_create_topic(participant, &PsmxType1_desc, topicname, NULL, NULL); + CU_ASSERT_FATAL(topic2 > 0); + + writer1 = dds_create_writer(participant, topic1, NULL, NULL); + CU_ASSERT_FATAL(writer1 > 0); + assert_psmx_instance_name(writer1, "dummy_psmx"); + reader1 = dds_create_reader(participant, topic1, NULL, NULL); + CU_ASSERT_FATAL(reader1 > 0); + assert_psmx_instance_name(reader1, "dummy_psmx"); + writer2 = dds_create_writer(participant, topic2, NULL, NULL); + CU_ASSERT_FATAL(writer2 > 0); + assert_psmx_instance_name(writer2, "dummy_psmx"); + reader2 = dds_create_reader(participant, topic2, NULL, NULL); + CU_ASSERT_FATAL(reader2 > 0); + assert_psmx_instance_name(reader2, "dummy_psmx"); + dds_delete(domain); +} + +/// @brief Check that shared memory availability and entity and loan pointers are correctly propagated through the psmx interface. +/// @methodology +/// - Check that the data types I'm planning to use are actually suitable for use with shared memory. +/// - Expectation: They are memcopy-safe. +/// +/// - Create a configuration with a psmx interface. +/// - Create a domain using this configuration. +/// - Assert that there is exactly one psmx instance. +/// - Decide whether shared memory is supported (communicated to the dummy psmx). +/// - Create some entities +/// - Assert that the psmx_topic created during dummy_psmx_create_topic, is propagated to dummy_psmx_create_endpoint(). +/// - Assert that the psmx_endpoint created during dummy_psmx_create_endpoint(), is propagated to dummy_psmx_request_loan(), dummy_psmx_write(), dummy_psmx_delete_endpoint(). +/// - Assert that the loan created during dummy_psmx_request_loan(), is propagated to dummy_psmx_write(). +/// - Check if shared memory is available. +/// - Expectation: Shared memory is available iff the psmx interface supports it (check for the false and the true case). +/// - Delete the domain +/// - Check the function call counts of the dummy psmx. +/// - Expectation: The counts match expectations. In particular, create counts must match their delete counterpart. +/// +CU_Test(ddsc_psmxif, shared_memory) +{ + char strbuf[512]; + const size_t strbuf_size = sizeof(strbuf); + { + // Check that the data types I'm planning to use are actually suitable for use with shared memory. + dds_data_type_properties_t props; + props = dds_stream_data_types(SC_Model_desc.m_ops); + CU_ASSERT_FATAL((props & DDS_DATA_TYPE_IS_MEMCPY_SAFE) == DDS_DATA_TYPE_IS_MEMCPY_SAFE); + props = dds_stream_data_types(PsmxType1_desc.m_ops); + CU_ASSERT_FATAL((props & DDS_DATA_TYPE_IS_MEMCPY_SAFE) == DDS_DATA_TYPE_IS_MEMCPY_SAFE); + } + + for (size_t i = 0; i < 2; ++i) { + const dds_domainid_t domainId = 0; + dds_entity_t participant = create_participant(domainId); + dds_entity_t domain = dds_get_parent(participant); + dummy_mockstats_t* dmock = dummy_mockstats_get_ptr(); + CU_ASSERT_FATAL(dmock->cnt_create_psmx == 1); // Confirm the dummy psmx has been loaded. + { + // Assert that there is exactly one psmx instance. + dds_entity* x = NULL; + CU_ASSERT_FATAL(dds_entity_pin(domain, &x) == DDS_RETCODE_OK && dds_entity_kind(x) == DDS_KIND_DOMAIN); + CU_ASSERT_FATAL(((dds_domain*)x)->psmx_instances.length == 1); + dds_entity_unpin(x); + } + + bool supports_shared_memory_expected = (bool)i; + dmock->supports_shared_memory = supports_shared_memory_expected; + + dds_psmx_topic_t* psmx_topic_expected = NULL; + dds_psmx_endpoint_t* psmx_endpt_expected = NULL; + dds_psmx_endpoint_t* delete_endpoint_expected[4]; + memset(delete_endpoint_expected, 0x0, sizeof(delete_endpoint_expected)); + size_t delete_endpoint_idx = 0; + const size_t endpt_cnt = sizeof(delete_endpoint_expected) / sizeof(delete_endpoint_expected[0]); + + // Check that the config string passed to `dds_create_domain()` has been correctly forwarded to the dummy psmx. + char dmock_config_expected[] = "LOCATOR=4a4d203df6996395e1412fbecc2de4b6;SERVICE_NAME=service_psmx_dummy;KEYED_TOPICS=true;"; + CU_ASSERT_FATAL(strcmp(dmock->config, dmock_config_expected) == 0); + + void* sample = NULL; + dds_entity_t writer1 = 0, reader1 = 0, writer2 = 0, reader2 = 0; + + char topicname[100]; + dummy_topics_alloc(dmock, 2); + dummy_endpoints_alloc(dmock, endpt_cnt); + + create_unique_topic_name("shared_memory", topicname, sizeof(topicname)); + psmx_topic_expected = (dds_psmx_topic_t*)dmock->topics._buffer + dmock->topics._length; + dds_entity_t topic1 = dds_create_topic(participant, &SC_Model_desc, topicname, NULL, NULL); + CU_ASSERT_FATAL(topic1 > 0); + + psmx_endpt_expected = (dds_psmx_endpoint_t*)dmock->endpoints._buffer + dmock->endpoints._length; + delete_endpoint_expected[delete_endpoint_idx++] = psmx_endpt_expected; + writer1 = dds_create_writer(participant, topic1, NULL, NULL); + CU_ASSERT_FATAL(writer1 > 0); + CU_ASSERT_FATAL(dmock->create_endpoint_rcv_topic == psmx_topic_expected); + CU_ASSERT_FATAL(dds_request_loan(writer1, &sample) == DDS_RETCODE_OK); + CU_ASSERT_FATAL(dmock->request_loan_rcv_endpt == psmx_endpt_expected); + dmock->write_rcv_loan = NULL; + CU_ASSERT_FATAL(dds_write(writer1, sample) == DDS_RETCODE_OK); + CU_ASSERT_FATAL(dmock->write_rcv_endpt == psmx_endpt_expected); + CU_ASSERT_FATAL(dmock->write_rcv_loan == &dmock->loan); + + psmx_endpt_expected = (dds_psmx_endpoint_t*)dmock->endpoints._buffer + dmock->endpoints._length; + delete_endpoint_expected[delete_endpoint_idx++] = psmx_endpt_expected; + reader1 = dds_create_reader(participant, topic1, NULL, NULL); + CU_ASSERT_FATAL(reader1 > 0); + CU_ASSERT_FATAL(dmock->create_endpoint_rcv_topic == psmx_topic_expected); + + create_unique_topic_name("shared_memory", topicname, sizeof(topicname)); + psmx_topic_expected = (dds_psmx_topic_t*)dmock->topics._buffer + dmock->topics._length; + dds_entity_t topic2 = dds_create_topic(participant, &PsmxType1_desc, topicname, NULL, NULL); + CU_ASSERT_FATAL(topic2 > 0); + + psmx_endpt_expected = (dds_psmx_endpoint_t*)dmock->endpoints._buffer + dmock->endpoints._length; + delete_endpoint_expected[delete_endpoint_idx++] = psmx_endpt_expected; + writer2 = dds_create_writer(participant, topic2, NULL, NULL); + CU_ASSERT_FATAL(writer2 > 0); + CU_ASSERT_FATAL(dmock->create_endpoint_rcv_topic == psmx_topic_expected); + CU_ASSERT_FATAL(dds_request_loan(writer2, &sample) == DDS_RETCODE_OK); + CU_ASSERT_FATAL(dmock->request_loan_rcv_endpt == psmx_endpt_expected); + dmock->write_rcv_loan = NULL; + CU_ASSERT_FATAL(dds_write(writer2, sample) == DDS_RETCODE_OK); + CU_ASSERT_FATAL(dmock->write_rcv_endpt == psmx_endpt_expected); + CU_ASSERT_FATAL(dmock->write_rcv_loan == &dmock->loan); + + psmx_endpt_expected = (dds_psmx_endpoint_t*)dmock->endpoints._buffer + dmock->endpoints._length; + delete_endpoint_expected[delete_endpoint_idx++] = psmx_endpt_expected; + reader2 = dds_create_reader(participant, topic2, NULL, NULL); + CU_ASSERT_FATAL(reader2 > 0); + CU_ASSERT_FATAL(dmock->create_endpoint_rcv_topic == psmx_topic_expected); + + // Check that shared memory is available when it should, and not available when it shouldn't. + CU_ASSERT_FATAL(dds_is_shared_memory_available(writer1) == supports_shared_memory_expected); + CU_ASSERT_FATAL(dds_is_shared_memory_available(reader1) == supports_shared_memory_expected); + CU_ASSERT_FATAL(dds_is_shared_memory_available(writer2) == supports_shared_memory_expected); + CU_ASSERT_FATAL(dds_is_shared_memory_available(reader2) == supports_shared_memory_expected); + + // Check that psmx_endpoint pointers originally from `dummy_psmx_create_endpoint()`, end up in `dummy_psmx_delete_endpoint()`. + CU_ASSERT_FATAL(delete_endpoint_idx == endpt_cnt); + dds_delete(reader2); + CU_ASSERT_FATAL(dmock->delete_endpoint_rcv_endpt == delete_endpoint_expected[--delete_endpoint_idx]); + dds_delete(writer2); + CU_ASSERT_FATAL(dmock->delete_endpoint_rcv_endpt == delete_endpoint_expected[--delete_endpoint_idx]); + dds_delete(reader1); + CU_ASSERT_FATAL(dmock->delete_endpoint_rcv_endpt == delete_endpoint_expected[--delete_endpoint_idx]); + dds_delete(writer1); + CU_ASSERT_FATAL(dmock->delete_endpoint_rcv_endpt == delete_endpoint_expected[--delete_endpoint_idx]); + dds_delete(domain); + + // Check number of calls against expected counts. + dummy_mockstats_tostring(dmock, strbuf, strbuf_size); + printf("ddsc_psmxif_shared_memory calls counts:\n%s\n", strbuf); + + CU_ASSERT_FATAL(dmock->cnt_create_psmx == 1); + + CU_ASSERT_FATAL(dmock->cnt_type_qos_supported == 10); + CU_ASSERT_FATAL(dmock->cnt_create_topic == 2); + CU_ASSERT_FATAL(dmock->cnt_delete_topic == 2); + CU_ASSERT_FATAL(dmock->cnt_deinit == 1); + CU_ASSERT_FATAL(dmock->cnt_get_node_id == 1); + CU_ASSERT_FATAL(dmock->cnt_supported_features == 4); + + CU_ASSERT_FATAL(dmock->cnt_create_endpoint == 4); + CU_ASSERT_FATAL(dmock->cnt_delete_endpoint == 4); + + CU_ASSERT_FATAL(dmock->cnt_request_loan == 2); + CU_ASSERT_FATAL(dmock->cnt_write == 2); + CU_ASSERT_FATAL(dmock->cnt_take == 0); + CU_ASSERT_FATAL(dmock->cnt_on_data_available == 2); + } +} From 5842d13153299add8c1969930c9bfd9b91059939 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Mon, 22 Jul 2024 16:47:30 +0200 Subject: [PATCH 156/207] Implement wfhd Signed-off-by: TheFixer --- src/core/ddsc/src/dds__types.h | 4 + src/core/ddsc/src/dds_reader.c | 17 +- .../dds/durability/dds_durability_public.h | 5 +- src/durability/src/dds_durability.c | 203 ++++++++++++++---- src/durability/src/durablesupport.idl | 29 ++- 5 files changed, 210 insertions(+), 48 deletions(-) diff --git a/src/core/ddsc/src/dds__types.h b/src/core/ddsc/src/dds__types.h index f42d7d53a5..6186ec7cb1 100644 --- a/src/core/ddsc/src/dds__types.h +++ b/src/core/ddsc/src/dds__types.h @@ -397,6 +397,10 @@ typedef struct dds_reader { struct dds_loan_pool *m_loans; /* administration of outstanding loans */ struct dds_loan_pool *m_heap_loan_cache; + /* Mutex and condition variable for wfhd; only available for readers */ + ddsrt_mutex_t wfhd_mutex; + ddsrt_cond_t wfhd_cond; + /* Status metrics */ dds_sample_rejected_status_t m_sample_rejected_status; dds_liveliness_changed_status_t m_liveliness_changed_status; diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index 713af1f292..0dedaf0d47 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -90,6 +90,11 @@ static dds_return_t dds_reader_delete (dds_entity *e) dds_rhc_free (rd->m_rhc); ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); + // Destroy mutex and condition variable for wfhd + // LH: Not sure if this is the right spot to destroy + ddsrt_mutex_destroy(&rd->wfhd_mutex); + ddsrt_cond_destroy(&rd->wfhd_cond); + dds_loan_pool_free (rd->m_heap_loan_cache); dds_loan_pool_free (rd->m_loans); @@ -713,6 +718,10 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe // Ownership of rqos is transferred to reader entity own_rqos = false; + // Initialize mutex and condition variable for wfhd + ddsrt_mutex_init (&rd->wfhd_mutex); + ddsrt_cond_init (&rd->wfhd_cond); + // assume DATA_ON_READERS is materialized in the subscriber: // - changes to it won't be propagated to this reader until after it has been added to the subscriber's children // - data can arrive once `new_reader` is called, requiring raising DATA_ON_READERS if materialized @@ -906,7 +915,9 @@ dds_return_t dds_reader_wait_for_historical_data (dds_entity_t reader, dds_durat dds_reader *rd; dds_return_t ret; (void) max_wait; - if ((ret = dds_reader_lock (reader, &rd)) != DDS_RETCODE_OK) + bool call_wfhd = false; + + if ((ret = dds_reader_lock(reader, &rd)) != DDS_RETCODE_OK) return ret; switch (rd->m_entity.m_qos->durability.kind) { @@ -917,9 +928,13 @@ dds_return_t dds_reader_wait_for_historical_data (dds_entity_t reader, dds_durat break; case DDS_DURABILITY_TRANSIENT: case DDS_DURABILITY_PERSISTENT: + call_wfhd = true; break; } dds_reader_unlock(rd); + if (call_wfhd) { + ret = rd->m_entity.m_domain->dc.dds_durability_wait_for_historical_data(reader, max_wait); + } return ret; } diff --git a/src/durability/include/dds/durability/dds_durability_public.h b/src/durability/include/dds/durability/dds_durability_public.h index e990cba38b..97c2690973 100644 --- a/src/durability/include/dds/durability/dds_durability_public.h +++ b/src/durability/include/dds/durability/dds_durability_public.h @@ -19,7 +19,7 @@ extern "C" { #endif -typedef struct dds_durability{ +typedef struct dds_durability { ddsrt_dynlib_t lib_handle; dds_return_t (*dds_durability_init) (const dds_domainid_t domain, struct ddsi_domaingv *gv); dds_entity_t (*_dds_durability_fini) (void); @@ -27,8 +27,9 @@ typedef struct dds_durability{ dds_return_t (*dds_durability_new_local_reader) (dds_entity_t reader, struct dds_rhc *rhc); dds_return_t (*dds_durability_new_local_writer) (dds_entity_t writer); dds_return_t (*dds_durability_wait_for_quorum) (dds_entity_t writer); + dds_return_t (*dds_durability_wait_for_historical_data) (dds_entity_t reader, dds_duration_t max_wait); bool (*dds_durability_is_terminating) (void); -}dds_durability_t; +} dds_durability_t; void dds_durability_fini (dds_durability_t* dc); dds_return_t dds_durability_load (dds_durability_t* dc, const struct ddsi_domaingv* gv); diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index e6eaa4feec..cd70f8423e 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -17,12 +17,15 @@ #include "dds/ddsrt/heap.h" #include "dds/ddsrt/threads.h" #include "dds/ddsrt/log.h" +#include "dds/ddsrt/avl.h" #include "ddsc/dds.h" #include "../src/dds__writer.h" +#include "../src/dds__reader.h" #include "dds/ddsi/ddsi_endpoint.h" #include "dds/ddsrt/avl.h" #include "dds/ddsi/ddsi_serdata.h" #include "dds/ddsi/ddsi_typelib.h" +#include "dds/ddsi/ddsi_entity_index.h" #include #define DEFAULT_QOURUM 1 @@ -60,6 +63,8 @@ static char *dc_responsetype_image (DurableSupport_responsetype_t type) switch (type) { case DurableSupport_RESPONSETYPE_SET: return "set"; + case DurableSupport_RESPONSETYPE_READER: + return "reader"; case DurableSupport_RESPONSETYPE_DATA: return "data"; default: @@ -281,6 +286,33 @@ static int dc_stringify_response_set (char *buf, size_t n, const DurableSupport_ return -1; } +static int dc_stringify_response_reader (char *buf, size_t n, const DurableSupport_response_reader_t *response_reader) +{ + size_t i = 0; + int l; + char id_str[37]; + + if (buf == NULL) { + goto err; + } + if (response_reader == NULL) { + buf[0] = '\0'; + return 0; + } + if ((l = snprintf(buf+i, n-i, "{\"rguid\":\"%s\"}" , dc_stringify_id(response_reader->rguid, id_str))) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_response_reader failed"); + return -1; +} + static int dc_stringify_response_data (char *buf, size_t n, const DurableSupport_response_data_t *response_data) { size_t i = 0; @@ -345,6 +377,12 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp } i += (size_t)l; break; + case DurableSupport_RESPONSETYPE_READER : + if ((l = dc_stringify_response_reader(buf+i, n-i, &response->body._u.reader)) < 0) { + goto err; + } + i += (size_t)l; + break; case DurableSupport_RESPONSETYPE_DATA : if ((l = dc_stringify_response_data(buf+i, n-i, &response->body._u.data)) < 0) { goto err; @@ -398,7 +436,7 @@ struct delivery_reader_key_t { }; struct delivery_reader_t { - ddsrt_avl_node_t node; /* represents a node in the tree of delivery reader */ + ddsrt_avl_node_t node; /* represents a node in the tree of readers for which there is a delivery pending */ struct delivery_reader_key_t key; /* key of a delivery reader */ }; @@ -412,8 +450,8 @@ static int cmp_delivery_reader (const void *a, const void *b) static void cleanup_delivery_reader (void *n) { - struct delivery_reader_t *rd = (struct delivery_reader_t *)n; - ddsrt_free(rd); + struct delivery_reader_t *dr = (struct delivery_reader_t *)n; + ddsrt_free(dr); } static const ddsrt_avl_ctreedef_t delivery_readers_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct delivery_reader_t, node), offsetof (struct delivery_reader_t, key), cmp_delivery_reader, 0); @@ -493,7 +531,7 @@ static int dc_stringify_delivery_request (char *buf, size_t n, const struct deli if (i >= n) { goto trunc; } - if ((l = snprintf(buf+i, n-i, ", \", reader\":%" PRId32, dr->reader)) < 0) { + if ((l = snprintf(buf+i, n-i, ", \"reader\":%" PRId32, dr->reader)) < 0) { goto err; } i += (size_t)l; @@ -556,12 +594,11 @@ static const ddsrt_avl_ctreedef_t delivery_requests_td = DDSRT_AVL_CTREEDEF_INIT static const ddsrt_fibheap_def_t delivery_requests_fd = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct delivery_request_t, fhnode), cmp_exp_time); - struct delivery_ctx_t { ddsrt_avl_node_t node; DurableSupport_id_t id; /* id of the ds that delivers the data; key of the delivery context */ uint64_t delivery_id; /* the id of the delivery by this ds; this is a monotonic increased sequence number */ - ddsrt_avl_ctree_t readers; /* tree of reader guids for which this delivery is intended */ + ddsrt_avl_ctree_t readers; /* tree of reader guids for which this delivery is intended; populated when a delivery is opened */ }; static int dc_stringify_delivery_ctx (char *buf, size_t n, const struct delivery_ctx_t *delivery_ctx) @@ -626,7 +663,7 @@ static void cleanup_delivery_ctx (void *n) static const ddsrt_avl_ctreedef_t delivery_ctx_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct delivery_ctx_t, node), offsetof (struct delivery_ctx_t, id), delivery_ctx_cmp, 0); -/* Administration to keep track of the request readers of a ds +/* Administration to keep track of the request readers of a DS * that can act as a target to send requests for historical data to.. * Based on this administration requests for historical data are published immediately, * or pending until a ds is found that matches. */ @@ -709,7 +746,7 @@ struct dc_t { ddsrt_mutex_t delivery_request_mutex; /* delivery request queue mutex */ ddsrt_cond_t delivery_request_cond; /* delivery request condition */ dds_instance_handle_t selected_request_reader_ih; /* instance handle to matched request reader, DDS_HANDLE_NIL if not available */ - ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on a ds that match with my request writer */ + ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on DSs that match with my request writer */ uint32_t nr_of_matched_dc_requests; /* indicates the number of matched dc_request readers for the dc_request writer of this client */ struct delivery_ctx_t *delivery_ctx; /* reference to current delivery context, NULL if none */ ddsrt_avl_ctree_t delivery_ctxs; /* table of delivery contexts, keyed by ds id */ @@ -1420,7 +1457,7 @@ static dds_return_t dc_com_request_write (struct com_t *com, const dds_guid_t rg request = DurableSupport_request__alloc(); memcpy(request->key.rguid, rguid.v, 16); memcpy(request->client, dc.cfg.id, 16); - request->timeout = DDS_INFINITY; + request->timeout = DDS_INFINITY; /* currently not used */ l = dc_stringify_request(str, sizeof(str), request, true); assert(l > 0); len = (size_t)l; @@ -1518,6 +1555,7 @@ static struct delivery_ctx_t *dc_get_delivery_ctx (struct dc_t *dc, DurableSuppo delivery_ctx = dc->delivery_ctx; } else if (((delivery_ctx = ddsrt_avl_clookup (&delivery_ctx_td, &dc->delivery_ctxs, id)) == NULL) && autocreate) { delivery_ctx = ddsrt_malloc(sizeof(struct delivery_ctx_t)); + memset(delivery_ctx, 0, sizeof(struct delivery_ctx_t)); memcpy(delivery_ctx->id,id,16); ddsrt_avl_cinit(&delivery_readers_td, &delivery_ctx->readers); ddsrt_avl_cinsert(&delivery_ctx_td, &dc->delivery_ctxs, delivery_ctx); @@ -1564,7 +1602,38 @@ static struct delivery_reader_t *dc_get_reader_from_delivery_ctx (struct deliver return delivery_reader; } -/* close the current delivery context for the ds identified by id */ +static void unblock_wfhd_for_reader (struct dc_t *dc, dds_entity_t reader) +{ + dds_entity *e; + dds_reader *rd; + dds_return_t rc; + dds_guid_t rguid; + char id_str[37]; + + if ((rc = dds_entity_lock (reader, DDS_KIND_READER, &e)) != DDS_RETCODE_OK) { + /* The reader could not be found, it may have been deleted. + * Since this is legitimate, we silently return from this function. */ + return; + } + if ((rc = dds_get_guid(reader, &rguid)) != DDS_RETCODE_OK) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "failed to retrieve reader guid for reader with handle %" PRId32 "\n", reader); + goto err_get_guid; + } + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "unblock wfhd for reader \"%s\"\n", dc_stringify_id(rguid.v, id_str)); + rd = (dds_reader *)e; + /* unblock wfhd for this reader */ + ddsrt_mutex_lock(&rd->wfhd_mutex); + ddsrt_cond_broadcast(&rd->wfhd_cond); + ddsrt_mutex_unlock(&rd->wfhd_mutex); + dds_entity_unlock(e); + return; + +err_get_guid: + dds_entity_unlock(e); + return; +} + +/* Close the current delivery context for the ds identified by id */ static void dc_close_delivery (struct dc_t *dc, DurableSupport_id_t id, DurableSupport_response_set_t *response_set) { char id_str[37]; @@ -1572,13 +1641,14 @@ static void dc_close_delivery (struct dc_t *dc, DurableSupport_id_t id, DurableS assert(response_set); assert(response_set->flags & DC_FLAG_SET_END); - /* lookup the align context for this aligner */ + (void)response_set; /* to silence the compiler for release builds */ + /* Lookup the delivery context for this aligner */ if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, id, false)) == NULL) { - /* There exists a delivery context for the ds that produced the response. */ + /* There does not exists a delivery context for the DS that produced the response. */ DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "unable to close delivery for ds \"%s\"\n", dc_stringify_id(id, id_str)); return; } - /* there exists a delivery context for the ds identified by id, close this delivery context */ + /* There exists a delivery context for the ds identified by id, close this delivery context */ (void)dc_stringify_delivery_ctx(str, sizeof(str), dc->delivery_ctx); DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "close delivery %s\n", str); /* remove current delivery ctx */ @@ -1666,20 +1736,39 @@ static void dc_process_set_response_begin(struct dc_t *dc, DurableSupport_respon static void dc_process_set_response_end (struct dc_t *dc, DurableSupport_response *response) { + char id_str[37]; + assert(response); assert(response->body._d == DurableSupport_RESPONSETYPE_SET); - dc_close_delivery(dc, response->id, &response->body._u.set); + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, false)) != NULL) { + assert(memcmp(dc->delivery_ctx->id, response->id, 16) == 0); + /* There exists an open delivery from the DS. + * Now check if end delivery id corresponds to the open delivery id. */ + if (dc->delivery_ctx->delivery_id != response->body._u.set.delivery_id) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "current open delivery %" PRIu64 " does not match with end delivery %" PRIu64 "\n", dc->delivery_ctx->delivery_id, response->body._u.set.delivery_id); + /* abort the currently open delivery */ + dc_abort_delivery(dc, dc->delivery_ctx->id, &response->body._u.set); + } + dc_close_delivery(dc, response->id, &response->body._u.set); + } else { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "unable to close delivery %" PRIu64 " from ds \"%s\"\n", response->body._u.set.delivery_id, dc_stringify_id(response->id, id_str)); + } } -static void dc_process_set_response_not_found(struct dc_t *dc, DurableSupport_response *response) +static void dc_process_reader_response (struct dc_t *dc, DurableSupport_response *response) { - /* the set indicated in the response does not exist at the ds. - * This can for example happen when a transient reader has been created, - * but no transient writer exists. In such cases we can mark the reader - * as complete. - */ - DC_UNUSED_ARG(dc); - DC_UNUSED_ARG(response); + struct delivery_request_key_t key; + struct delivery_request_t *dr; + ddsrt_avl_dpath_t dpath; + + assert(response); + assert(response->body._d == DurableSupport_RESPONSETYPE_READER); + memcpy(key.guid.v, response->body._u.reader.rguid, 16); + /* Lookup if there is a delivery request for this reader. + * If so, unblock the reader. */ + if ((dr = ddsrt_avl_clookup_dpath(&delivery_requests_td, &dc->delivery_requests, &key, &dpath)) != NULL) { + unblock_wfhd_for_reader(dc, dr->reader); + } } static void dc_process_set_response (struct dc_t *dc, DurableSupport_response *response) @@ -1689,8 +1778,6 @@ static void dc_process_set_response (struct dc_t *dc, DurableSupport_response *r dc_process_set_response_begin(dc, response); } else if (response->body._u.set.flags & DC_FLAG_SET_END) { dc_process_set_response_end(dc, response); - } else if (response->body._u.set.flags & DC_FLAG_SET_NOT_FOUND) { - dc_process_set_response_not_found(dc, response); } else { DDS_ERROR("invalid response set flag 0x%04" PRIx32, response->body._u.set.flags); } @@ -1778,7 +1865,7 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * data_out.iov_base = response->body._u.data.blob._buffer + serdata_offset; /* Now deliver the data to the local readers. */ for (delivery_reader = ddsrt_avl_citer_first (&delivery_readers_td, &dc->delivery_ctx->readers, &it); delivery_reader; delivery_reader = ddsrt_avl_citer_next (&it)) { - /* take the guid and lookup the reader entity that requested the delivery */ + /* Lookup the reader entity that requested the delivery. */ /* check if the reader still exists by lookup the entity */ struct delivery_request_t *dr; struct delivery_request_key_t key; @@ -1796,9 +1883,9 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * /* in order to insert the data in the rhc of the reader we first * need to resolve the type of the reader */ if ((ret = dds_get_entity_sertype (reader, &sertype)) < 0) { - /* We failed to get the sertype of the reader., so we cannot + /* We failed to get the sertype of the reader. * This could be because the reader does not exist any more, - * but frankly I don't about the reason. All that matters is + * but frankly I don't care about the reason. All that matters is * that we cannot inject data into the rhc of this reader. */ continue; } @@ -1860,6 +1947,9 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) case DurableSupport_RESPONSETYPE_SET: dc_process_set_response(dc, response); break; + case DurableSupport_RESPONSETYPE_READER: + dc_process_reader_response(dc, response); + break; case DurableSupport_RESPONSETYPE_DATA: dc_process_data_response(dc, response); break; @@ -1884,6 +1974,9 @@ static void dc_delete_delivery_request (struct dc_t *dc, dds_guid_t rguid) memcpy(key.guid.v, rguid.v, 16); if ((dr = ddsrt_avl_clookup_dpath (&delivery_requests_td, &dc->delivery_requests, &key, &dpath)) != NULL) { + /* remove from fibheap */ + ddsrt_fibheap_delete(&delivery_requests_fd, &dc->delivery_requests_fh, dr); + /* remove from delivery requests */ ddsrt_avl_cdelete_dpath(&delivery_requests_td, &dc->delivery_requests, dr, &dpath); (void)dc_stringify_delivery_request(dr_str, sizeof(dr_str), dr); DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delete delivery request %s\n", dr_str); @@ -1902,7 +1995,7 @@ static struct delivery_request_t *dc_insert_delivery_request (struct dc_t *dc, d memcpy(key.guid.v, rguid.v, 16); if ((dr = ddsrt_avl_clookup_ipath (&delivery_requests_td, &dc->delivery_requests, &key, &ipath)) == NULL) { dr = ddsrt_malloc(sizeof(struct delivery_request_t)); - memcpy(dr->key.guid.v, rguid.v, 16); + memcpy(dr->key.guid.v, key.guid.v, 16); dr->reader = reader; dr->exp_time = DDS_NEVER; (void)dc_stringify_delivery_request(dr_str, sizeof(dr_str), dr); @@ -1929,7 +2022,7 @@ static void dc_send_request_for_reader (struct dc_t *dc, dds_entity_t reader, st DDS_ERROR("Unable to retrieve the guid of the reader [%s]", dds_strretcode(-rc)); goto err_get_guid; } - /* Administrate the outstanding request. + /* Remember the delivery request for this reader. * This is used a.o. to correlate reader guids to actual readers. */ dc_insert_delivery_request(dc, reader, rguid); /* Publish the quest */ @@ -1990,7 +2083,6 @@ static void dc_dispose_delivery_request (struct dc_t *dc, struct delivery_reques char id_str[37]; DC_UNUSED_ARG(dr); - /* create a dummy request containing the reader guid that */ memcpy(request.key.rguid, dr->key.guid.v, 16); if ((ih = dds_lookup_instance(dc->com->wr_request, &request)) == DDS_HANDLE_NIL) { DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "no delivery request for reader \"%s\" found, unable to dispose\n", dc_stringify_id(request.key.rguid, id_str)); @@ -2000,7 +2092,6 @@ static void dc_dispose_delivery_request (struct dc_t *dc, struct delivery_reques DDS_ERROR("failed to dispose delivery request for reader \"%s\" [%s]\n", dc_stringify_id(request.key.rguid, id_str), dds_strretcode(-rc)); goto err_dispose_delivery_request; } - /* LH: todo: use dc_stringify_request, but only print the keys */ DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dispose delivery request for reader \"%s\"\n", dc_stringify_id(request.key.rguid, id_str)); err_dispose_delivery_request: return; @@ -2062,7 +2153,7 @@ static void default_request_writer_matched_cb (dds_entity_t writer, dds_publicat } if ((ep = dds_get_matched_subscription_data(writer, ih)) != NULL) { if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { - /* A dc_request reader on a data container has matched with the dc_request writer. + /* A dc_request reader on a DS has matched with the dc_request writer. * From now on it is allowed to publish requests. * In case there are any delivery requests, we can sent them now */ dc_add_matched_request_reader(dc, ep, ih); @@ -2112,7 +2203,7 @@ static void dc_process_delivery_request_guard (struct dc_t *dc, dds_time_t *time ddsrt_mutex_unlock(&dc->delivery_request_mutex); } -static uint32_t recv_handler (void *a) +static uint32_t delivery_handler (void *a) { struct dc_t *dc = (struct dc_t *)a; dds_time_t timeout = DDS_NEVER; @@ -2257,7 +2348,7 @@ static dds_return_t dds_durability_init (const dds_domainid_t domainid, struct d activate_request_listener(&dc); /* start a thread to process messages coming from a ds */ ddsrt_threadattr_init(&dc.recv_tattr); - if ((rc = ddsrt_thread_create(&dc.recv_tid, "dc", &dc.recv_tattr, recv_handler, &dc)) != DDS_RETCODE_OK) { + if ((rc = ddsrt_thread_create(&dc.recv_tid, "dc", &dc.recv_tattr, delivery_handler, &dc)) != DDS_RETCODE_OK) { goto err_recv_thread; } return DDS_RETCODE_OK; @@ -2394,7 +2485,7 @@ static dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct } if ((dkind == DDS_DURABILITY_TRANSIENT) || (dkind == DDS_DURABILITY_PERSISTENT)) { if (is_application_entity(&dc, reader)) { - /* the user data of the participant for this durable reader does + /* The user data of the participant for this durable reader does * not contain the ident, so the endpoint is not from a remote DS. * We can now publish a dc_request for this durable reader. The * dc_request is published as a transient-local topic. This means @@ -2499,11 +2590,34 @@ static dds_return_t dds_durability_get_quorum_reached (dds_entity_t writer, bool return ret; } +static dds_return_t dds_durability_wait_for_historical_data (dds_entity_t reader, dds_duration_t max_wait) +{ + dds_return_t ret = DDS_RETCODE_OK; + dds_entity *e; + dds_reader *rd; + + /* LH: The reader is pinned while waiting for wfhd. + * The reason for this is that I don't want the reader to be + * deleted while waiting for historical data. + * I am not sure if pinning alone is sufficient. */ + if ((ret = dds_entity_pin(reader, &e)) != DDS_RETCODE_OK) { + return ret; + } + rd = (dds_reader *) e; + ddsrt_mutex_lock(&rd->wfhd_mutex); + if (!ddsrt_cond_waitfor(&rd->wfhd_cond, &rd->wfhd_mutex, max_wait)) { + ret = DDS_RETCODE_TIMEOUT; + } + ddsrt_mutex_unlock(&rd->wfhd_mutex); + dds_entity_unpin(e); + return ret; +} + /* This function waits for a quorum of durable data containers to be available, * or timeout in case max_blocking_time is expired and quorum not yet reached. * * If the quorum is not reached before the max_blocking_time() is expired, - * DDS_RETCODE_PRECONDITION + * DDS_RETCODE_PRECONDITION is returned * * The quorum is calculated based on the number of discovered and matched data containers * for a writer. This also implies that if a writer has reached a quorum, @@ -2558,13 +2672,14 @@ static uint32_t dds_durability_get_quorum (void) return dc.cfg.quorum; } -void dds_durability_creator(dds_durability_t* ds) +void dds_durability_creator (dds_durability_t *dc) { - ds->dds_durability_init = dds_durability_init; - ds->_dds_durability_fini = _dds_durability_fini; - ds->dds_durability_get_quorum = dds_durability_get_quorum; - ds->dds_durability_new_local_reader = dds_durability_new_local_reader; - ds->dds_durability_new_local_writer = dds_durability_new_local_writer; - ds->dds_durability_wait_for_quorum = dds_durability_wait_for_quorum; - ds->dds_durability_is_terminating = dds_durability_is_terminating; + dc->dds_durability_init = dds_durability_init; + dc->_dds_durability_fini = _dds_durability_fini; + dc->dds_durability_get_quorum = dds_durability_get_quorum; + dc->dds_durability_new_local_reader = dds_durability_new_local_reader; + dc->dds_durability_new_local_writer = dds_durability_new_local_writer; + dc->dds_durability_wait_for_quorum = dds_durability_wait_for_quorum; + dc->dds_durability_is_terminating = dds_durability_is_terminating; + dc->dds_durability_wait_for_historical_data = dds_durability_wait_for_historical_data; } diff --git a/src/durability/src/durablesupport.idl b/src/durability/src/durablesupport.idl index 0e4d949512..6b0592fa59 100644 --- a/src/durability/src/durablesupport.idl +++ b/src/durability/src/durablesupport.idl @@ -15,6 +15,26 @@ module DurableSupport { /******************** * Durable client + * + * The following topics definitions specify the delivery topics used + * for communication between a durarable service and a user application + * (client). The following topics are defined: + * + * - request message send by a user application to a durable service. + * message to indicate that the user application requests delivery + * of historical data from a durable service to the user application. + * Typically, such request is done by an aplication reader that + * hat is interested in historical data. + * - response message send by a durable service to deliver historical data + * to a user application. Typically, a durable service sends a + * a stream of beads to a user application to provide the requested + * data. There are 3 types of responses: + * - set response: indicates the delivery start or delivery end of + * data set + * - data response: indicates delivery of historical data + * - reader response: indicates that all available historical data for + * a reader has been provided; signals that reader + * can return from dds_wait_for_historical_data(). ********************/ /* duration */ @@ -40,7 +60,8 @@ module DurableSupport { /* List of supported response types */ const responsetype_t RESPONSETYPE_SET = 1; - const responsetype_t RESPONSETYPE_DATA = 2; + const responsetype_t RESPONSETYPE_READER = 2; + const responsetype_t RESPONSETYPE_DATA = 3; @appendable @nested struct response_set_t { @@ -52,6 +73,11 @@ module DurableSupport { unsigned long flags; /* flags for this set */ }; + @appendable @nested + struct response_reader_t { + id_t rguid; /* guid of the reader that has become complete */ + }; + @appendable @nested struct response_data_t { sequence blob; @@ -60,6 +86,7 @@ module DurableSupport { @appendable @nested union response_content switch (responsetype_t) { case RESPONSETYPE_SET : response_set_t set; + case RESPONSETYPE_READER : response_reader_t reader; case RESPONSETYPE_DATA: response_data_t data; }; From 3262baac9994d5d051b41241552215c6994e2642 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 1 Jul 2024 13:35:22 +0200 Subject: [PATCH 157/207] Delete broken alternative for thread sanitizer Signed-off-by: Erik Boasson --- src/ddsrt/include/dds/ddsrt/hopscotch.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/ddsrt/include/dds/ddsrt/hopscotch.h b/src/ddsrt/include/dds/ddsrt/hopscotch.h index 1b6b998795..4016905054 100644 --- a/src/ddsrt/include/dds/ddsrt/hopscotch.h +++ b/src/ddsrt/include/dds/ddsrt/hopscotch.h @@ -215,18 +215,11 @@ struct ddsrt_chh_bucket; * @brief Embedded data version of @ref ddsrt_hh_iter. * @see ddsrt_chh_iter_first */ -#if ! ddsrt_has_feature_thread_sanitizer struct ddsrt_chh_iter { struct ddsrt_chh_bucket *bs; uint32_t size; uint32_t cursor; }; -#else -struct ddsrt_chh_iter { - struct ddsrt_chh *chh; - struct ddsrt_hh_iter it; -}; -#endif /** * @brief Concurrent version of @ref ddsrt_hh_new From e8120b2d65cd54465b0d331a1569c1cfa2df3f12 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Fri, 28 Jun 2024 09:09:38 +0200 Subject: [PATCH 158/207] Improve ddsrt_recvmsg interface There is only one caller of ddsrt_recvmsg (outside the tests), ddsi_udp_conn_read, and it assumed that ddsrt_recvmsg: 1. returns OK with *rcvd > 0 2. returns OK with *rcvd = 0 3. returns not-OK with *rcvd untouched or set to 0 Case 1 is the perfectly ordinary case. Case 2 is treated as a spurious but successful read. This is somewhat weird: the socket triggers because data is available and so a read should return something. IIRC it is there because with OpenSSL 3 and TCP+TLS I saw received bytes all getting consumed internally by OpenSSL during a handshake. Anyway, it exists. Case 3 is for all errors. The "*rcvd untouched or set to 0" was important because ddsi_udp_conn_read would first check whether it is > 0. It initializes it to 0, so if it is untouched on error or set to 0, all is well. The one caller of ddsi_udp_conn_read is ddsi_receive.c:do_packet, which simply ignores any call to ddsi_udp_conn_read that returns <= 0. So case 2 can be propagated by returning 0 (successful spurious read) or < 0 (error) without any difference in behaviour. This requirement on *rcvd in case of an error is an accident waiting to happen. This commit changes the interface so that it is: 1. OK and *rcvd >= 0 2. not-OK and *rcvd undefined This requires no changes on the implementation of ddsrt_recvmsg. The change in the caller is trivial and makes it as one would expect. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_udp.c | 62 ++++++------- src/ddsrt/include/dds/ddsrt/sockets.h | 2 +- src/ddsrt/src/sockets/windows/socket.c | 119 ++++++++++++++----------- 3 files changed, 97 insertions(+), 86 deletions(-) diff --git a/src/core/ddsi/src/ddsi_udp.c b/src/core/ddsi/src/ddsi_udp.c index 5efd60b4a1..788678260d 100644 --- a/src/core/ddsi/src/ddsi_udp.c +++ b/src/core/ddsi/src/ddsi_udp.c @@ -184,49 +184,49 @@ static ssize_t ddsi_udp_conn_read (struct ddsi_tran_conn * conn_cmn, unsigned ch (void) allow_spurious; dds_return_t rc; - ssize_t nrecv = 0; + ssize_t nrecv; do { rc = ddsrt_recvmsg (&conn->m_sockext, &msghdr, 0, &nrecv); } while (rc == DDS_RETCODE_INTERRUPTED); - if (nrecv > 0) + if (rc != DDS_RETCODE_OK) { - if (pktinfo) - { - addr_to_loc (conn->m_base.m_factory, &pktinfo->src, &src); - translate_pktinfo (pktinfo, &msghdr, conn->m_base.m_base.m_port, src.a.sa_family == AF_INET6); - } + if (rc != DDS_RETCODE_BAD_PARAMETER && rc != DDS_RETCODE_NO_CONNECTION) + GVERROR ("UDP recvmsg sock %d: ret %d retcode %"PRId32"\n", (int) conn->m_sockext.sock, (int) nrecv, rc); + return -1; + } - if (gv->pcap_fp) - { - union addr dest; - socklen_t dest_len = sizeof (dest); - if (ddsrt_getsockname (conn->m_sockext.sock, &dest.a, &dest_len) != DDS_RETCODE_OK) - memset (&dest, 0, sizeof (dest)); - ddsi_write_pcap_received (gv, ddsrt_time_wallclock (), &src.x, &dest.x, buf, (size_t) nrecv); - } + assert (rc == DDS_RETCODE_OK && nrecv >= 0); + if (pktinfo) + { + addr_to_loc (conn->m_base.m_factory, &pktinfo->src, &src); + translate_pktinfo (pktinfo, &msghdr, conn->m_base.m_base.m_port, src.a.sa_family == AF_INET6); + } + + if (gv->pcap_fp) + { + union addr dest; + socklen_t dest_len = sizeof (dest); + if (ddsrt_getsockname (conn->m_sockext.sock, &dest.a, &dest_len) != DDS_RETCODE_OK) + memset (&dest, 0, sizeof (dest)); + ddsi_write_pcap_received (gv, ddsrt_time_wallclock (), &src.x, &dest.x, buf, (size_t) nrecv); + } - /* Check for udp packet truncation */ + /* Check for udp packet truncation */ #if ! DDSRT_MSGHDR_FLAGS - const bool trunc_flag = false; + const bool trunc_flag = false; #elif defined MSG_CTRUNC - const bool trunc_flag = (msghdr.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) != 0; + const bool trunc_flag = (msghdr.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) != 0; #else - const bool trunc_flag = (msghdr.msg_flags & MSG_TRUNC) != 0; + const bool trunc_flag = (msghdr.msg_flags & MSG_TRUNC) != 0; #endif - if ((size_t) nrecv > len || trunc_flag) - { - char addrbuf[DDSI_LOCSTRLEN]; - ddsi_locator_t tmp; - addr_to_loc (conn->m_base.m_factory, &tmp, &src); - ddsi_locator_to_string (addrbuf, sizeof (addrbuf), &tmp); - GVWARNING ("%s => %d truncated to %d\n", addrbuf, (int) nrecv, (int) len); - } - } - else if (rc != DDS_RETCODE_BAD_PARAMETER && rc != DDS_RETCODE_NO_CONNECTION) + if ((size_t) nrecv > len || trunc_flag) { - GVERROR ("UDP recvmsg sock %d: ret %d retcode %"PRId32"\n", (int) conn->m_sockext.sock, (int) nrecv, rc); - nrecv = -1; + char addrbuf[DDSI_LOCSTRLEN]; + ddsi_locator_t tmp; + addr_to_loc (conn->m_base.m_factory, &tmp, &src); + ddsi_locator_to_string (addrbuf, sizeof (addrbuf), &tmp); + GVWARNING ("%s => %d truncated to %d\n", addrbuf, (int) nrecv, (int) len); } return nrecv; } diff --git a/src/ddsrt/include/dds/ddsrt/sockets.h b/src/ddsrt/include/dds/ddsrt/sockets.h index 9c5e681988..297415342b 100644 --- a/src/ddsrt/include/dds/ddsrt/sockets.h +++ b/src/ddsrt/include/dds/ddsrt/sockets.h @@ -280,7 +280,7 @@ ddsrt_recv( * @param[in] sockext the socket * @param[out] msg the message received * @param[in] flags flags for special options - * @param[out] rcvd number of bytes received + * @param[out] rcvd number of bytes received (>= 0 if return == OK, undefined if return != OK) * @return a DDS_RETCODE (OK, ERROR, TRY_AGAIN, BAD_PARAMETER, NO_CONNECTION, INTERRUPTED, OUT_OF_RESOURCES, ILLEGAL_OPERATION) * * See @ref ddsrt_sendmsg diff --git a/src/ddsrt/src/sockets/windows/socket.c b/src/ddsrt/src/sockets/windows/socket.c index a875d18f03..0458374168 100644 --- a/src/ddsrt/src/sockets/windows/socket.c +++ b/src/ddsrt/src/sockets/windows/socket.c @@ -545,75 +545,86 @@ struct iovec_matches_WSABUF { char len_size_matches[sizeof(((ddsrt_iovec_t *)8)->iov_len) == sizeof(((WSABUF *)8)->len) ? 1 : -1]; }; -dds_return_t -ddsrt_recvmsg( +static dds_return_t +ddsrt_recvmsg_wsarecvmsg( const ddsrt_socket_ext_t *sockext, ddsrt_msghdr_t *msg, int flags, ssize_t *rcvd) { - assert(msg != NULL); - if (sockext->wsarecvmsg) + WSAMSG wsamsg = { + .name = (LPSOCKADDR) msg->msg_name, + .namelen = (INT) msg->msg_namelen, + .lpBuffers = (LPWSABUF) msg->msg_iov, + .dwBufferCount = (DWORD) msg->msg_iovlen, + .Control = { + .len = (ULONG) msg->msg_controllen, + .buf = (CHAR *) msg->msg_control, + }, + .dwFlags = 0 + }; + DWORD n; + int err; + if (sockext->wsarecvmsg (sockext->sock, &wsamsg, &n, NULL, 0) == 0 || (err = WSAGetLastError()) == WSAEMSGSIZE) { - WSAMSG wsamsg = { - .name = (LPSOCKADDR) msg->msg_name, - .namelen = (INT) msg->msg_namelen, - .lpBuffers = (LPWSABUF) msg->msg_iov, - .dwBufferCount = (DWORD) msg->msg_iovlen, - .Control = { - .len = (ULONG) msg->msg_controllen, - .buf = (CHAR *) msg->msg_control, - }, - .dwFlags = 0 - }; - DWORD n; - if (sockext->wsarecvmsg (sockext->sock, &wsamsg, &n, NULL, 0) != 0) - { - int err = WSAGetLastError(); - return recv_error_to_retcode(err); - } - else - { - msg->msg_flags = wsamsg.dwFlags; - msg->msg_controllen = wsamsg.Control.len; - *rcvd = (ssize_t) n; - return DDS_RETCODE_OK; - } + // WSAEMSGSIZE is not an error for us: we look at (msg_flags & MSG_TRUNC) + msg->msg_flags = wsamsg.dwFlags; + msg->msg_controllen = wsamsg.Control.len; + *rcvd = (ssize_t) n; + return DDS_RETCODE_OK; } else { - assert(msg->msg_iovlen == 1); - assert(msg->msg_iov[0].iov_len < INT_MAX); - msg->msg_flags = 0; - int n = recvfrom( - sockext->sock, - msg->msg_iov[0].iov_base, - (int)msg->msg_iov[0].iov_len, - flags, - msg->msg_name, - &msg->msg_namelen); - msg->msg_controllen = 0; - - if (n != -1) { - *rcvd = n; - return DDS_RETCODE_OK; - } + return recv_error_to_retcode(err); + } +} - int err = WSAGetLastError(); - if (err == WSAEMSGSIZE) { - /* Windows returns an error for too-large messages, UNIX expects the - original size and the MSG_TRUNC flag. MSDN states it is truncated, which - presumably means it returned as much of the message as it could. Return - that the message was one byte larger than the available space and set - MSG_TRUNC. */ - *rcvd = msg->msg_iov[0].iov_len + 1; - msg->msg_flags |= MSG_TRUNC; - } +static dds_return_t +ddsrt_recvmsg_recvfrom( + const ddsrt_socket_ext_t *sockext, + ddsrt_msghdr_t *msg, + int flags, + ssize_t *rcvd) +{ + assert(msg->msg_iovlen == 1); + assert(msg->msg_iov[0].iov_len < INT_MAX); + msg->msg_flags = 0; + int n = recvfrom( + sockext->sock, + msg->msg_iov[0].iov_base, + (int)msg->msg_iov[0].iov_len, + flags, + msg->msg_name, + &msg->msg_namelen); + msg->msg_controllen = 0; + *rcvd = n; + if (n != SOCKET_ERROR) + return DDS_RETCODE_OK; + int err = WSAGetLastError(); + if (err == WSAEMSGSIZE) { + // WSAEMSGSIZE is not an error for us: we look at (msg_flags & MSG_TRUNC) + msg->msg_flags |= MSG_TRUNC; + return DDS_RETCODE_OK; + } else { return recv_error_to_retcode(err); } } +dds_return_t +ddsrt_recvmsg( + const ddsrt_socket_ext_t *sockext, + ddsrt_msghdr_t *msg, + int flags, + ssize_t *rcvd) +{ + assert(msg != NULL); + if (sockext->wsarecvmsg) + return ddsrt_recvmsg_wsarecvmsg (sockext, msg, flags, rcvd); + else + return ddsrt_recvmsg_recvfrom (sockext, msg, flags, rcvd); +} + static dds_return_t send_error_to_retcode(int errnum) { From 343d8a2a6d43858e978fc48b1955bd50029391f6 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 1 Jul 2024 14:35:48 +0200 Subject: [PATCH 159/207] Turn off PACKET_DESTINATION_INFO for mingw-w64. The CMSG_* macros used in CycloneDDS are not provided by mingw-w64-gcc (only WSA*). Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_udp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/ddsi/src/ddsi_udp.c b/src/core/ddsi/src/ddsi_udp.c index 788678260d..6fb2aca17b 100644 --- a/src/core/ddsi/src/ddsi_udp.c +++ b/src/core/ddsi/src/ddsi_udp.c @@ -49,6 +49,9 @@ DDSRT_STATIC_ASSERT (DDSI_LOCATOR_UDPv4MCGEN_INDEX_MASK_BITS <= 32 - UDP_MC_ADDR # endif #endif #ifndef PACKET_DESTINATION_INFO +# if defined (__MINGW32__) && !defined (CMSG_SPACE) +# define PACKET_DESTINATION_INFO 0 +# endif # if defined CMSG_SPACE && (defined IP_PKTINFO || (DDSRT_HAVE_IPV6 && defined IPV6_PKTINFO)) # define PACKET_DESTINATION_INFO 1 # else From d9172120ef0f84c7bcc80b93a0595f082d022010 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Tue, 23 Jul 2024 11:24:09 +0200 Subject: [PATCH 160/207] Fix error handling in serdata_default_from_psmx Fixes the error handling in serdata_default_from_psmx: serdata_default_free can't be called on a serdata with a refcount of 1. Signed-off-by: Dennis Potman --- src/core/ddsc/src/dds_serdata_default.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ddsc/src/dds_serdata_default.c b/src/core/ddsc/src/dds_serdata_default.c index 5e01b8485e..243660d4a5 100644 --- a/src/core/ddsc/src/dds_serdata_default.c +++ b/src/core/ddsc/src/dds_serdata_default.c @@ -930,7 +930,7 @@ static struct ddsi_serdata * serdata_default_from_psmx (const struct ddsi_sertyp case DDS_LOANED_SAMPLE_STATE_RAW_DATA: if (d->hdr.identifier != DDSI_RTPS_SAMPLE_NATIVE) { - serdata_default_free (&d->c); + ddsi_serdata_unref (&d->c); return NULL; } d->c.loan = loaned_sample; @@ -945,7 +945,7 @@ static struct ddsi_serdata * serdata_default_from_psmx (const struct ddsi_sertyp // FIXME: how much do we trust PSMX-provided data? If we *really* trust it, we can skip this if (!dds_stream_normalize (loaned_sample->sample_ptr, md->sample_size, false, xcdr_version, &tp->type, just_key, &actual_size)) { - serdata_default_free (&d->c); + ddsi_serdata_unref (&d->c); return NULL; } serdata_default_append_blob (&d, actual_size, loaned_sample->sample_ptr); @@ -953,7 +953,7 @@ static struct ddsi_serdata * serdata_default_from_psmx (const struct ddsi_sertyp dds_istream_init (&is, actual_size, d->data, xcdr_version); if (!gen_serdata_key_from_cdr (&is, &d->key, tp, just_key)) { - serdata_default_free (&d->c); + ddsi_serdata_unref (&d->c); return NULL; } break; From f5ac68cbfed1f606310522f44b63b65fa8dadcd4 Mon Sep 17 00:00:00 2001 From: Thijs Sassen Date: Wed, 14 Aug 2024 14:13:27 +0200 Subject: [PATCH 161/207] Fixes for support of qnx 8.0 --- src/core/ddsi/src/ddsi_raweth.c | 6 +++++- src/ddsrt/src/ifaddrs/posix/ifaddrs.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/ddsi/src/ddsi_raweth.c b/src/core/ddsi/src/ddsi_raweth.c index faee6f7b7c..60b444f89e 100644 --- a/src/core/ddsi/src/ddsi_raweth.c +++ b/src/core/ddsi/src/ddsi_raweth.c @@ -44,8 +44,12 @@ #include #elif defined(__QNXNTO__) #define DDSI_BPF_IS_CLONING_DEV (1) -#include +#include +#if _NTO_VERSION < 800 #include +#else +#include +#endif #endif #include #include diff --git a/src/ddsrt/src/ifaddrs/posix/ifaddrs.c b/src/ddsrt/src/ifaddrs/posix/ifaddrs.c index 6c057a0746..2b7e7488d3 100644 --- a/src/ddsrt/src/ifaddrs/posix/ifaddrs.c +++ b/src/ddsrt/src/ifaddrs/posix/ifaddrs.c @@ -113,7 +113,7 @@ static enum ddsrt_iftype guess_iftype (const struct ifaddrs *sys_ifa) switch (IFM_TYPE (ifmr.ifm_active)) { case IFM_ETHER: -#if !defined __FreeBSD__ +#if !defined __FreeBSD__ && !defined __QNXNTO__ case IFM_TOKEN: case IFM_FDDI: #endif From 565fc6b100c546e5c95b0d57e5fde9b71dd79287 Mon Sep 17 00:00:00 2001 From: MarcelJordense <37329887+MarcelJordense@users.noreply.github.com> Date: Wed, 21 Aug 2024 11:17:01 +0200 Subject: [PATCH 162/207] add option to set realtime priority to iceorix notification thread (linux only) (#2071) * add option to set realtime priority to iceorix notification thread (linux only) Signed-off-by: Marcel Jordense * Iceoryx listener scheduling settings Signed-off-by: Erik Boasson * allow priority 0 when scheduling class is SCHED_OTHER Signed-off-by: Marcel Jordense --------- Signed-off-by: Marcel Jordense Signed-off-by: Erik Boasson Co-authored-by: Erik Boasson --- src/psmx_iox/CMakeLists.txt | 4 +- src/psmx_iox/src/psmx_iox_impl.cpp | 43 ++++++- src/psmx_iox/src/scheduling.cpp | 199 +++++++++++++++++++++++++++++ src/psmx_iox/src/scheduling.hpp | 59 +++++++++ 4 files changed, 299 insertions(+), 6 deletions(-) create mode 100644 src/psmx_iox/src/scheduling.cpp create mode 100644 src/psmx_iox/src/scheduling.hpp diff --git a/src/psmx_iox/CMakeLists.txt b/src/psmx_iox/CMakeLists.txt index 4021e93f31..b9a04887a3 100644 --- a/src/psmx_iox/CMakeLists.txt +++ b/src/psmx_iox/CMakeLists.txt @@ -18,7 +18,9 @@ set(psmx_iox_sources src/psmx_iox_impl.cpp include/psmx_iox_impl.hpp src/machineid.cpp - src/machineid.hpp) + src/machineid.hpp + src/scheduling.hpp + src/scheduling.cpp) if(BUILD_SHARED_LIBS) add_library(psmx_iox SHARED ${psmx_iox_sources}) diff --git a/src/psmx_iox/src/psmx_iox_impl.cpp b/src/psmx_iox/src/psmx_iox_impl.cpp index e105a275cd..322b1bcd1a 100644 --- a/src/psmx_iox/src/psmx_iox_impl.cpp +++ b/src/psmx_iox/src/psmx_iox_impl.cpp @@ -20,6 +20,7 @@ #include "dds/ddsrt/mh3.h" #include "dds/ddsrt/random.h" #include "dds/ddsrt/strtol.h" +#include "dds/ddsrt/threads.h" #include "dds/ddsc/dds_loaned_sample.h" #include "dds/ddsc/dds_psmx.h" @@ -31,6 +32,7 @@ #include "psmx_iox_impl.hpp" #include "machineid.hpp" +#include "scheduling.hpp" #define ERROR_PREFIX "=== [ICEORYX] " @@ -92,7 +94,7 @@ static bool is_wildcard_partition(const char *str) struct iox_psmx : public dds_psmx_t { - iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service_name, const dds_psmx_node_identifier_t& node_id, bool support_keyed_topics, bool allow_nondisc_wr); + iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service_name, const dds_psmx_node_identifier_t& node_id, bool support_keyed_topics, bool allow_nondisc_wr, sched::sched_info sched_info); ~iox_psmx(); bool _support_keyed_topics; bool _allow_nondisc_wr; @@ -100,9 +102,13 @@ struct iox_psmx : public dds_psmx_t std::unique_ptr _listener; //the listener needs to be created after iox runtime has been initialized dds_psmx_node_identifier_t _node_id = { 0 }; std::shared_ptr _node_id_publisher; + sched::sched_info _sched_info; }; -iox_psmx::iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service_name, const dds_psmx_node_identifier_t& node_id, bool support_keyed_topics, bool allow_nondisc_wr) : +// Whether Iceoryx listener thread(s) need to set the priority +static thread_local bool sched_info_set = false; + +iox_psmx::iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service_name, const dds_psmx_node_identifier_t& node_id, bool support_keyed_topics, bool allow_nondisc_wr, sched::sched_info sched_info) : dds_psmx_t { .ops = psmx_ops, .instance_name = dds_string_dup ("CycloneDDS-IOX-PSMX"), @@ -114,7 +120,8 @@ iox_psmx::iox_psmx(dds_psmx_instance_id_t identifier, const std::string& service _support_keyed_topics{support_keyed_topics}, _allow_nondisc_wr{allow_nondisc_wr}, _service_name{iox::capro::IdString_t(iox::cxx::TruncateToCapacity, service_name)}, - _listener{} + _listener{}, + _sched_info{sched_info} { uint64_t instance_hash = (uint64_t) ddsrt_random() << 32 | ddsrt_random(); char iox_runtime_name[64]; @@ -542,6 +549,16 @@ static dds_loaned_sample_t * iox_take(struct dds_psmx_endpoint * psmx_endpoint) static void on_incoming_data_callback(iox::popo::UntypedSubscriber * subscriber, iox_psmx_endpoint * psmx_endpoint) { + assert(psmx_endpoint->psmx_topic); + assert(psmx_endpoint->psmx_topic->psmx_instance); + struct iox_psmx *psmx = static_cast(psmx_endpoint->psmx_topic->psmx_instance); + + if (!sched_info_set) { + sched_info_set = true; + if (!sched_info_apply(psmx->_sched_info)) + std::cerr << ERROR_PREFIX "failed to apply scheduling settings" << std::endl; + } + psmx_endpoint->lock.lock(); while (subscriber->hasData()) { @@ -605,7 +622,7 @@ static void iox_loaned_sample_free(dds_loaned_sample_t *loan) static std::optional get_config_option_value(const char *conf, const char *option_name, bool tolower = false) { char *copy = dds_string_dup (conf), *cursor = copy, *tok; - while ((tok = ddsrt_strsep (&cursor, ",/|;")) != nullptr) + while ((tok = ddsrt_strsep (&cursor, ";")) != nullptr) { if (strlen(tok) == 0) continue; @@ -708,6 +725,22 @@ dds_return_t iox_create_psmx(struct dds_psmx **psmx, dds_psmx_instance_id_t inst return DDS_RETCODE_ERROR; } - *psmx = new iox_psmx::iox_psmx(instance_id, service_name, node_id.value(), keyed_topics, allow_nondisc_wr); + iox_psmx::sched::sched_info si; + auto opt_sched_prio = get_config_option_value(config, "PRIORITY"); + if (opt_sched_prio.has_value()) { + if (!iox_psmx::sched::sched_info_setpriority (si, opt_sched_prio.value())) { + std::cerr << ERROR_PREFIX "invalid value for PRIORITY" << std::endl; + return DDS_RETCODE_ERROR; + } + } + auto opt_sched_affinity = get_config_option_value(config, "AFFINITY"); + if (opt_sched_affinity.has_value()) { + if (!iox_psmx::sched::sched_info_setaffinity (si, opt_sched_affinity.value())) { + std::cerr << ERROR_PREFIX "invalid value for AFFINITY" << std::endl; + return DDS_RETCODE_ERROR; + } + } + + *psmx = new iox_psmx::iox_psmx(instance_id, service_name, node_id.value(), keyed_topics, allow_nondisc_wr, si); return *psmx ? DDS_RETCODE_OK : DDS_RETCODE_ERROR; } diff --git a/src/psmx_iox/src/scheduling.cpp b/src/psmx_iox/src/scheduling.cpp new file mode 100644 index 0000000000..b3e1e16452 --- /dev/null +++ b/src/psmx_iox/src/scheduling.cpp @@ -0,0 +1,199 @@ +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#include +#include +#include +#include +#include +#include + +#include +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/string.h" + +#include "scheduling.hpp" + +namespace iox_psmx { namespace sched { + +#if defined(__linux) || defined(__APPLE__) +static bool valid_priority(prioclass_t cl, int prio) +{ + if (cl == SCHED_OTHER) + return (prio == 0); + return (prio >= sched_get_priority_min(cl) && prio <= sched_get_priority_max(cl)); +} +#elif defined(_WIN32) +static bool valid_priority(prioclass_t cl, int prio) +{ + switch (prio) + { + case THREAD_PRIORITY_ABOVE_NORMAL: + case THREAD_PRIORITY_BELOW_NORMAL: + case THREAD_PRIORITY_HIGHEST: + case THREAD_PRIORITY_IDLE: + case THREAD_PRIORITY_LOWEST: + case THREAD_PRIORITY_NORMAL: + case THREAD_PRIORITY_TIME_CRITICAL: + return true; + case -7: case -6: case -5: case -4: case -3: + case 3: case 4: case 5: case 6: + return (cl == REALTIME_PRIORITY_CLASS); + default: + return false; + } +} +#else +static bool valid_priority(prioclass_t cl, int prio) +{ + static_cast(cl); + static_cast(prio); + return false; +} +#endif + +static void trim(std::string &s) +{ + s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(std::isspace))).base(), s.end()); + s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isspace)))); +} + +bool sched_info_setpriority(sched_info& si, const std::string& x) +{ + size_t priostart = x.find(':'); + prioclass_t cl; +#if defined(__linux) || defined(__APPLE_) + // The reason to raise the priority of the Iceoryx listener thread is to get the latencies + // down, so some a real-time scheduling class seems the most reasonable default + cl = SCHED_FIFO; +#elif defined(_WIN32) + cl = GetPriorityClass(GetCurrentProcess()); +#else + cl = 0; +#endif + if (priostart == x.npos) + priostart = 0; + else + { + std::string cstr = x.substr(0, priostart); + trim(cstr); + std::transform(cstr.begin(), cstr.end(), cstr.begin(), [](unsigned char c){ return std::toupper(c); }); +#if defined(__linux) || defined(__APPLE_) + if (cstr == "OTHER") cl = SCHED_OTHER; + else if (cstr == "FIFO") cl = SCHED_FIFO; + else if (cstr == "RT") cl = SCHED_RR; + else return false; +#else + return false; +#endif + ++priostart; + } + int prio; + try { + prio = std::stoi(x.substr(priostart)); + } catch (std::exception()) { + return false; + } + if (!valid_priority(cl, prio)) + return false; + si.prio = class_prio{cl, prio}; + return true; +} + +static bool cpuset_set(cpuset_t& set, int id) +{ +#if defined(__linux) + if (id < 0 || id >= CPU_SETSIZE) + return false; + CPU_SET(id, &set.x); + return true; +#elif defined(_WIN32) + if (id < 0 || id >= CHAR_BIT * sizeof (uintptr_t)) + return false; + set.mask |= (uintptr_t)1 << id; + return true; +#else + static_cast(set); + static_cast(id); + return false; +#endif +} + +bool sched_info_setaffinity(sched_info& si, const std::string& x) +{ + cpuset_t cpuset; + std::unique_ptr> copy{ddsrt_strdup(x.c_str()), ddsrt_free}; + char *cursor = copy.get(), *tok; + while ((tok = ddsrt_strsep(&cursor, ",")) != nullptr) + { + int v, e, pos; + if (sscanf(tok, "%d-%d%n", &v, &e, &pos) == 2) { + // skip + } else if (sscanf(tok, "%d%n", &v, &pos) == 1) { + e = v; + } else { + return false; + } + if (e < v || tok[pos] != 0) { + return false; + } + for (int i = v; i <= e; i++) { + if (!cpuset_set(cpuset, v)) + return false; + } + } + si.affinity = cpuset; + return true; +} + +static bool set_thread_priority(const class_prio& cp) +{ +#if defined(__linux) || defined(__APPLE__) + struct sched_param param; + memset(static_cast(¶m), 0, sizeof(param)); + param.sched_priority = cp.priority; + if (pthread_setschedparam(pthread_self(), cp.schedclass, ¶m) == 0) + return true; +#elif defined(_WIN32) + if (SetThreadPriority(GetCurrentThread(), cp.priority)) + return true; +#else + static_cast(cp); +#endif + return false; +} + +static bool set_thread_affinity(const cpuset_t& affinity) +{ +#if defined(__linux) + if (pthread_setaffinity_np(pthread_self(), sizeof(affinity.x), &affinity.x) == 0) + return true; +#elif defined(_WIN32) + if (SetThreadAffinityMask(GetCurrentThread(), affinity.mask)) + return true; +#else + static_cast(affinity); +#endif + return false; +} + +bool sched_info_apply(const sched_info& si) +{ + if (si.prio.has_value()) { + if (!set_thread_priority(si.prio.value())) + return false; + } + if (si.affinity.has_value()) { + if (!set_thread_affinity(si.affinity.value())) + return false; + } + return true; +} + +} } // namespace diff --git a/src/psmx_iox/src/scheduling.hpp b/src/psmx_iox/src/scheduling.hpp new file mode 100644 index 0000000000..a17baeca50 --- /dev/null +++ b/src/psmx_iox/src/scheduling.hpp @@ -0,0 +1,59 @@ +// Copyright(c) 2024 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#ifndef SCHEDULING_HPP +#define SCHEDULING_HPP + +#include +#include +#include + +#if defined(__linux) || defined(__APPLE__) +#include +#include +#endif + +namespace iox_psmx { namespace sched { + +struct cpuset_t { +#if defined(__linux) + cpuset_t() { CPU_ZERO (&x); } + cpu_set_t x; +#elif defined(_WIN32) + cpuset_t() : mask(0) { } + uintptr_t mask; +#endif +}; + +#if defined(__linux) || defined(__APPLE__) +typedef int prioclass_t; +#elif defined(_WIN32) +typedef uint32_t prioclass_t; +#else +typedef int prioclass_t; // so we have something +#endif + +struct class_prio { + prioclass_t schedclass; + int priority; +}; + +struct sched_info { + std::optional prio; + std::optional affinity; +}; + +bool sched_info_setpriority(sched_info& si, const std::string& x); +bool sched_info_setaffinity(sched_info& si, const std::string& x); +bool sched_info_apply(const sched_info& x); + +} }; + +#endif /* SCHEDULING_HPP */ From 9051f4de5939dd6e565b336ca0f279af7293ca29 Mon Sep 17 00:00:00 2001 From: Thijs Sassen Date: Thu, 22 Aug 2024 09:43:32 +0200 Subject: [PATCH 163/207] Fix to make version check compatible with older qnx versions --- src/core/ddsi/src/ddsi_raweth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ddsi/src/ddsi_raweth.c b/src/core/ddsi/src/ddsi_raweth.c index 60b444f89e..3257846a2f 100644 --- a/src/core/ddsi/src/ddsi_raweth.c +++ b/src/core/ddsi/src/ddsi_raweth.c @@ -44,7 +44,7 @@ #include #elif defined(__QNXNTO__) #define DDSI_BPF_IS_CLONING_DEV (1) -#include +#include #if _NTO_VERSION < 800 #include #else From 41b1abb82dfe1b9beaffac0f7a502ce18074a359 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 12 Aug 2024 16:02:50 +0200 Subject: [PATCH 164/207] Fix "oneliner" durability_service specification It relied on slashes as separators between the various fields but failed to accept a slash as a terminator for a single value, making it impossible to specify the resource limits. Signed-off-by: Erik Boasson --- src/core/ddsc/tests/test_oneliner.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/ddsc/tests/test_oneliner.c b/src/core/ddsc/tests/test_oneliner.c index d4f0537b6d..eb14da1a99 100644 --- a/src/core/ddsc/tests/test_oneliner.c +++ b/src/core/ddsc/tests/test_oneliner.c @@ -511,9 +511,15 @@ static bool read_kvarg_3len (struct oneliner_lex *l, void *dst) return true; } +static bool read_kvarg_isterm (struct oneliner_lex *l2) +{ + int tok = peektok (l2, NULL); + return tok == ',' || tok == ')' || tok == '/'; +} + static bool read_kvarg (const struct kvarg *ks, size_t sizeof_ks, struct oneliner_lex *l, int *v, void *arg) { - // l points at name, *inp is , or ) terminated; *l unchanged when false + // l points at name, *inp is , or / or ) terminated; *l unchanged when false const struct kvarg *kend = ks + sizeof_ks / sizeof (*ks); struct oneliner_lex l1 = *l; advancetok (&l1); @@ -525,7 +531,7 @@ static bool read_kvarg (const struct kvarg *ks, size_t sizeof_ks, struct oneline { assert (k->arg != 0 && k->def == 0); struct oneliner_lex l2 = l1; - if (k->arg (&l2, arg) && (peektok (&l2, NULL) == ',' || peektok (&l2, NULL) == ')')) + if (k->arg (&l2, arg) && read_kvarg_isterm (&l2)) { *l = l2; return true; @@ -540,7 +546,7 @@ static bool read_kvarg (const struct kvarg *ks, size_t sizeof_ks, struct oneline /* skip symbol */ struct oneliner_lex l2 = l1; l2.inp += k->klen; - if (peektok (&l2, NULL) == ',' || peektok (&l2, NULL) == ')') + if (read_kvarg_isterm (&l2)) { if (k->arg == 0 || k->def != 0) { @@ -551,7 +557,7 @@ static bool read_kvarg (const struct kvarg *ks, size_t sizeof_ks, struct oneline } else if (k->arg != 0 && nexttok (&l2, NULL) == ':') { - if (k->arg (&l2, arg) && (peektok (&l2, NULL) == ',' || peektok (&l2, NULL) == ')')) + if (k->arg (&l2, arg) && read_kvarg_isterm (&l2)) { *l = l2; return true; From 4de86ec4f989f49be9f9869e02e1c580087149fd Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 12 Aug 2024 16:00:37 +0200 Subject: [PATCH 165/207] Add setting for controlling thread affinity This adds a Thread/Scheduling/Affinity option, which is a list of unsigned 32-bit integers indicating in some manner what CPUs to bind the thread to. Silently ignored on platforms that do not support it (or where Cyclone doesn't provide support for it yet). Currently only on Linux, where it is interpreted as a list of CPU ids. Signed-off-by: Erik Boasson --- docs/manual/config/config_file_reference.rst | 24 +++++-- docs/manual/options.md | 20 ++++-- etc/cyclonedds.rnc | 16 +++-- etc/cyclonedds.xsd | 18 ++++-- src/core/ddsi/defconfig.c | 10 +-- src/core/ddsi/include/dds/ddsi/ddsi_config.h | 6 ++ src/core/ddsi/src/ddsi__cfgelems.h | 10 +++ src/core/ddsi/src/ddsi_config.c | 68 ++++++++++++++++++++ src/core/ddsi/src/ddsi_thread.c | 2 + src/ddsrt/include/dds/ddsrt/threads.h | 3 + src/ddsrt/src/threads.c | 3 + src/ddsrt/src/threads/posix/threads.c | 22 +++++++ src/tools/_confgen/_confgen.h | 1 + src/tools/_confgen/generate_defconfig.c | 8 +++ 14 files changed, 184 insertions(+), 27 deletions(-) diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index ffe85c57b5..a526e4da16 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -2520,11 +2520,23 @@ The default value is: ```` //CycloneDDS/Domain/Threads/Thread/Scheduling ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Children: :ref:`Class`, :ref:`Priority` +Children: :ref:`Affinity`, :ref:`Class`, :ref:`Priority` This element configures the scheduling properties of the thread. +.. _`//CycloneDDS/Domain/Threads/Thread/Scheduling/Affinity`: + +//CycloneDDS/Domain/Threads/Thread/Scheduling/Affinity +"""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Text + +This element specifies the thread affinity using a string of comma-separated unsigned 32-bit integers. The notional meaning of the string is that it lists the IDs of the CPU cores to use, but some platforms may use a different mapping. Ignored if unsupported by the platform. + +The default value is: ```` + + .. _`//CycloneDDS/Domain/Threads/Thread/Scheduling/Class`: //CycloneDDS/Domain/Threads/Thread/Scheduling/Class @@ -2704,14 +2716,14 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: ``none`` .. - generated from ddsi_config.h[83ad19f1a665710b0c82b3ac6b861e6c8e83913f] + generated from ddsi_config.h[e6e75c7c07b3b91a92715063cfd8abdd0fbd8b08] generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] - generated from ddsi__cfgelems.h[194217161977869610495a7889bbc1e6bc976ce1] - generated from ddsi_config.c[a439a20e32fe327db26f2f10028d0056e46c1a0b] - generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] + generated from ddsi__cfgelems.h[69679834d0a592a339803ed27e3966adc900d592] + generated from ddsi_config.c[8d7ef0ae962a47cb2138de27ac0f6751e3393c66] + generated from _confgen.h[9554f1d72645c0b8bb66ffbfbc3c0fb664fc1a43] generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] generated from generate_md.c[789b92e422631684352909cfb8bf43f6ceb16a01] generated from generate_rst.c[3c4b523fbb57c8e4a7e247379d06a8021ccc21c4] generated from generate_xsd.c[6b6818d7f17a35d56c376c04ec1410427f34c0f0] - generated from generate_defconfig.c[63ca9d8ae2f1ce2e761c9d4c0510a45eb062d830] + generated from generate_defconfig.c[631cafee70a6f9480e0267db8ffe883d806f5f70] diff --git a/docs/manual/options.md b/docs/manual/options.md index 217bb09790..bd01a1bb4c 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -1754,11 +1754,19 @@ The default value is: `` ##### //CycloneDDS/Domain/Threads/Thread/Scheduling -Children: [Class](#cycloneddsdomainthreadsthreadschedulingclass), [Priority](#cycloneddsdomainthreadsthreadschedulingpriority) +Children: [Affinity](#cycloneddsdomainthreadsthreadschedulingaffinity), [Class](#cycloneddsdomainthreadsthreadschedulingclass), [Priority](#cycloneddsdomainthreadsthreadschedulingpriority) This element configures the scheduling properties of the thread. +###### //CycloneDDS/Domain/Threads/Thread/Scheduling/Affinity +Text + +This element specifies the thread affinity using a string of comma-separated unsigned 32-bit integers. The notional meaning of the string is that it lists the IDs of the CPU cores to use, but some platforms may use a different mapping. Ignored if unsupported by the platform. + +The default value is: `` + + ###### //CycloneDDS/Domain/Threads/Thread/Scheduling/Class One of: realtime, timeshare, default @@ -1898,14 +1906,14 @@ While none prevents any message from being written to a DDSI2 log file. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest. The default value is: `none` - + - - - + + + - + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index f1d4c36265..0370114513 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -1215,6 +1215,12 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==

    This element configures the scheduling properties of the thread.

    """ ] ] element Scheduling { [ a:documentation [ xml:lang="en" """ +

    This element specifies the thread affinity using a string of comma-separated unsigned 32-bit integers. The notional meaning of the string is that it lists the IDs of the CPU cores to use, but some platforms may use a different mapping. Ignored if unsupported by the platform.

    +

    The default value is: <empty>

    """ ] ] + element Affinity { + text + }? + & [ a:documentation [ xml:lang="en" """

    This element specifies the thread scheduling class (realtime, timeshare or default). The user may need special privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.

    The default value is: default

    """ ] ] element Class { @@ -1313,14 +1319,14 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
    duration_inf = xsd:token { pattern = "inf|0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)" } memsize = xsd:token { pattern = "0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B" } } -# generated from ddsi_config.h[83ad19f1a665710b0c82b3ac6b861e6c8e83913f] +# generated from ddsi_config.h[e6e75c7c07b3b91a92715063cfd8abdd0fbd8b08] # generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] -# generated from ddsi__cfgelems.h[194217161977869610495a7889bbc1e6bc976ce1] -# generated from ddsi_config.c[a439a20e32fe327db26f2f10028d0056e46c1a0b] -# generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] +# generated from ddsi__cfgelems.h[69679834d0a592a339803ed27e3966adc900d592] +# generated from ddsi_config.c[8d7ef0ae962a47cb2138de27ac0f6751e3393c66] +# generated from _confgen.h[9554f1d72645c0b8bb66ffbfbc3c0fb664fc1a43] # generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] # generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] # generated from generate_md.c[789b92e422631684352909cfb8bf43f6ceb16a01] # generated from generate_rst.c[3c4b523fbb57c8e4a7e247379d06a8021ccc21c4] # generated from generate_xsd.c[6b6818d7f17a35d56c376c04ec1410427f34c0f0] -# generated from generate_defconfig.c[63ca9d8ae2f1ce2e761c9d4c0510a45eb062d830] +# generated from generate_defconfig.c[631cafee70a6f9480e0267db8ffe883d806f5f70] diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index c314d2fdb2..15e0a9c9c5 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -1813,11 +1813,19 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> +
    + + + +<p>This element specifies the thread affinity using a string of comma-separated unsigned 32-bit integers. The notional meaning of the string is that it lists the IDs of the CPU cores to use, but some platforms may use a different mapping. Ignored if unsupported by the platform.</p> +<p>The default value is: <code>&lt;empty&gt;</code></p> + + @@ -1971,14 +1979,14 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - + - - - + + + - + diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index b84a164347..53614ab3ab 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -99,14 +99,14 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->ssl_min_version.minor = 3; #endif /* DDS_HAS_TCP_TLS */ } -/* generated from ddsi_config.h[83ad19f1a665710b0c82b3ac6b861e6c8e83913f] */ +/* generated from ddsi_config.h[e6e75c7c07b3b91a92715063cfd8abdd0fbd8b08] */ /* generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] */ -/* generated from ddsi__cfgelems.h[194217161977869610495a7889bbc1e6bc976ce1] */ -/* generated from ddsi_config.c[a439a20e32fe327db26f2f10028d0056e46c1a0b] */ -/* generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] */ +/* generated from ddsi__cfgelems.h[69679834d0a592a339803ed27e3966adc900d592] */ +/* generated from ddsi_config.c[8d7ef0ae962a47cb2138de27ac0f6751e3393c66] */ +/* generated from _confgen.h[9554f1d72645c0b8bb66ffbfbc3c0fb664fc1a43] */ /* generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] */ /* generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] */ /* generated from generate_md.c[789b92e422631684352909cfb8bf43f6ceb16a01] */ /* generated from generate_rst.c[3c4b523fbb57c8e4a7e247379d06a8021ccc21c4] */ /* generated from generate_xsd.c[6b6818d7f17a35d56c376c04ec1410427f34c0f0] */ -/* generated from generate_defconfig.c[63ca9d8ae2f1ce2e761c9d4c0510a45eb062d830] */ +/* generated from generate_defconfig.c[631cafee70a6f9480e0267db8ffe883d806f5f70] */ diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_config.h b/src/core/ddsi/include/dds/ddsi/ddsi_config.h index 0abc6fe808..e240e85a72 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_config.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_config.h @@ -120,12 +120,18 @@ struct ddsi_config_maybe_duration { dds_duration_t value; }; +struct ddsi_config_uint32_array { + uint32_t n; + uint32_t *xs; +}; + struct ddsi_config_thread_properties_listelem { struct ddsi_config_thread_properties_listelem *next; char *name; ddsrt_sched_t sched_class; struct ddsi_config_maybe_int32 schedule_priority; struct ddsi_config_maybe_uint32 stack_size; + struct ddsi_config_uint32_array affinity; }; struct ddsi_config_peer_listelem diff --git a/src/core/ddsi/src/ddsi__cfgelems.h b/src/core/ddsi/src/ddsi__cfgelems.h index 2b17969bb6..9f67e84f85 100644 --- a/src/core/ddsi/src/ddsi__cfgelems.h +++ b/src/core/ddsi/src/ddsi__cfgelems.h @@ -846,6 +846,16 @@ static struct cfgelem thread_properties_sched_cfgelems[] = { "special privileges from the underlying operating system to be able to " "assign some of the privileged priorities.

    " )), + STRING("Affinity", NULL, 1, "", + MEMBEROF(ddsi_config_thread_properties_listelem, affinity), + FUNCTIONS(0, uf_uint32_array, ff_uint32_array, pf_uint32_array), + DESCRIPTION( + "

    This element specifies the thread affinity using a string of " + "comma-separated unsigned 32-bit integers. The notional meaning " + "of the string is that it lists the IDs of the CPU cores to use, " + "but some platforms may use a different mapping. Ignored if " + "unsupported by the platform.

    " + )), END_MARKER }; diff --git a/src/core/ddsi/src/ddsi_config.c b/src/core/ddsi/src/ddsi_config.c index 4db60cf602..40c97a178b 100644 --- a/src/core/ddsi/src/ddsi_config.c +++ b/src/core/ddsi/src/ddsi_config.c @@ -192,6 +192,7 @@ DU(deaf_mute); DUPF(min_tls_version); #endif DUPF(shm_loglevel); +DUPF(uint32_array); #undef DUPF #undef DU #undef PF @@ -199,6 +200,7 @@ DUPF(shm_loglevel); #define DF(fname) static void fname (struct ddsi_cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) DF(ff_free); DF(ff_networkAddresses); +DF(ff_uint32_array); #undef DF #define DI(fname) static int fname (struct ddsi_cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) @@ -1595,6 +1597,72 @@ static enum update_result uf_deaf_mute (struct ddsi_cfgst *cfgst, void *parent, return uf_boolean (cfgst, parent, cfgelem, first, value); } +static enum update_result uf_uint32_array (struct ddsi_cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + struct ddsi_config_uint32_array * const elem = cfg_address (cfgst, parent, cfgelem); + if (*value == 0) // Short-circuit the common, trivial case of an empty string + { + elem->n = 0; + elem->xs = NULL; + return URES_SUCCESS; + } + else + { + const char *v = strchr (value, ','); + uint32_t maxn = 1; + while (v) + { + maxn++; + v = strchr (v + 1, ','); + } + uint32_t *xs = ddsrt_malloc (maxn * sizeof (*xs)); + uint32_t idx = 0; + char *valuecopy = ddsrt_strdup (value), *cursor = valuecopy, *tok; + while ((tok = ddsrt_strsep (&cursor, ",")) != NULL) + { + assert (idx < maxn); + int64_t i64; + enum update_result res = uf_int64_unit (cfgst, &i64, tok, NULL, 1, 0, UINT32_MAX); + if (res != URES_SUCCESS) + { + ddsrt_free (valuecopy); + ddsrt_free (xs); + return res; + } + assert (i64 >= 0 && i64 <= UINT32_MAX); + xs[idx++] = (uint32_t) i64; + } + elem->n = idx; + elem->xs = xs; + ddsrt_free (valuecopy); + return URES_SUCCESS; + } +} + +static void ff_uint32_array (struct ddsi_cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + struct ddsi_config_uint32_array * const elem = cfg_address (cfgst, parent, cfgelem); + ddsrt_free (elem->xs); +} + +static void pf_uint32_array (struct ddsi_cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources) +{ + struct ddsi_config_uint32_array const * const elem = cfg_address (cfgst, parent, cfgelem); + size_t bufsize = 11 * elem->n + 1; + char *buf = ddsrt_malloc (bufsize); + size_t pos = 0; + buf[0] = 0; + // pos < bufsize by construction (uint32_t: 10 digits + 1 for a comma, the extra byte is there for the n = 0 case) + for (uint32_t i = 0; i < elem->n; i++) + { + int n = snprintf (buf + pos, bufsize - pos, "%s%"PRIu32, (i > 0 ? "," : ""), elem->xs[i]); + if (n > 0) + pos += (size_t) n; + } + cfg_logelem (cfgst, sources, "%s", buf); + ddsrt_free (buf); +} + static struct ddsi_cfgst_node *lookup_or_create_elem_record (struct ddsi_cfgst *cfgst, struct cfgelem const * const cfgelem, void *parent, uint32_t source) { struct ddsi_cfgst_node *n; diff --git a/src/core/ddsi/src/ddsi_thread.c b/src/core/ddsi/src/ddsi_thread.c index 5f9b0e3bf2..b2d30b28d8 100644 --- a/src/core/ddsi/src/ddsi_thread.c +++ b/src/core/ddsi/src/ddsi_thread.c @@ -334,6 +334,8 @@ static dds_return_t create_thread_int (struct ddsi_thread_state **ts1_out, const tattr.schedClass = tprops->sched_class; /* explicit default value in the enum */ if (!tprops->stack_size.isdefault) tattr.stackSize = tprops->stack_size.value; + tattr.schedAffinityN = tprops->affinity.n; + tattr.schedAffinitySet = tprops->affinity.xs; } if (gv) { diff --git a/src/ddsrt/include/dds/ddsrt/threads.h b/src/ddsrt/include/dds/ddsrt/threads.h index 0b3bb94428..d6b937f021 100644 --- a/src/ddsrt/include/dds/ddsrt/threads.h +++ b/src/ddsrt/include/dds/ddsrt/threads.h @@ -68,6 +68,9 @@ typedef struct { ddsrt_sched_t schedClass; /** Specifies the thread priority */ int32_t schedPriority; + /** Specifies thread affinity, N = 0, Set = NULL or N > 0 and Set[0..N-1] contains N CPU ids */ + uint32_t schedAffinityN; + uint32_t *schedAffinitySet; /** Specifies the thread stack size */ uint32_t stackSize; } ddsrt_threadattr_t; diff --git a/src/ddsrt/src/threads.c b/src/ddsrt/src/threads.c index 902ba8676f..6631467d70 100644 --- a/src/ddsrt/src/threads.c +++ b/src/ddsrt/src/threads.c @@ -11,6 +11,7 @@ #include #include "dds/ddsrt/threads.h" +#include "dds/ddsrt/heap.h" void ddsrt_threadattr_init ( @@ -19,5 +20,7 @@ ddsrt_threadattr_init ( assert(attr != NULL); attr->schedClass = DDSRT_SCHED_DEFAULT; attr->schedPriority = 0; + attr->schedAffinityN = 0; + attr->schedAffinitySet = NULL; attr->stackSize = 0; } diff --git a/src/ddsrt/src/threads/posix/threads.c b/src/ddsrt/src/threads/posix/threads.c index 466a0a646e..b3d7398abc 100644 --- a/src/ddsrt/src/threads/posix/threads.c +++ b/src/ddsrt/src/threads/posix/threads.c @@ -410,6 +410,28 @@ ddsrt_thread_create ( } #endif } + +#if defined __linux + if (tattr.schedAffinityN > 0) + { + cpu_set_t cpuset; + CPU_ZERO (&cpuset); + for (uint32_t i = 0; i < tattr.schedAffinityN; i++) + { + if (tattr.schedAffinitySet[i] >= CPU_SETSIZE) + { + DDS_ERROR ("os_threadCreate(%s): CPU id %"PRIu32" out of range when setting affinity\n", name, tattr.schedAffinitySet[i]); + goto err; + } + CPU_SET(tattr.schedAffinitySet[i], &cpuset); + } + if ((result = pthread_attr_setaffinity_np (&pattr, sizeof (cpuset), &cpuset)) != 0) + { + DDS_ERROR("ddsrt_thread_create(%s): pthread_attr_setinheritsched(EXPLICIT) failed with error %d\n", name, result); + goto err; + } + } +#endif /* Construct context structure & start thread */ ctx = ddsrt_malloc (sizeof (thread_context_t)); diff --git a/src/tools/_confgen/_confgen.h b/src/tools/_confgen/_confgen.h index cd64e8ae90..aa25fc9077 100644 --- a/src/tools/_confgen/_confgen.h +++ b/src/tools/_confgen/_confgen.h @@ -53,6 +53,7 @@ void gendef_pf_transport_selector (FILE *fp, void *parent, struct cfgelem const void gendef_pf_many_sockets_mode (FILE *fp, void *parent, struct cfgelem const * const cfgelem); void gendef_pf_standards_conformance (FILE *fp, void *parent, struct cfgelem const * const cfgelem); void gendef_pf_shm_loglevel (FILE *fp, void *parent, struct cfgelem const * const cfgelem); +void gendef_pf_uint32_array (FILE *out, void *parent, struct cfgelem const * const cfgelem); struct cfgunit { const char *name; diff --git a/src/tools/_confgen/generate_defconfig.c b/src/tools/_confgen/generate_defconfig.c index 1122998307..b0924a43b8 100644 --- a/src/tools/_confgen/generate_defconfig.c +++ b/src/tools/_confgen/generate_defconfig.c @@ -193,6 +193,14 @@ void gendef_pf_standards_conformance (FILE *out, void *parent, struct cfgelem co void gendef_pf_shm_loglevel (FILE *out, void *parent, struct cfgelem const * const cfgelem) { gendef_pf_int (out, parent, cfgelem); } +void gendef_pf_uint32_array (FILE *out, void *parent, struct cfgelem const * const cfgelem) { + (void) out; + struct ddsi_config_uint32_array const * const p = cfg_address (parent, cfgelem); + if (p->n != 0) { + fprintf (stderr, "generate_defconfig internal error: non-empty uint32_array not handled\n"); + abort (); + } +} static void gen_defaults (FILE *out, void *parent, struct cfgelem const * const cfgelem) { From b53c54a981a1193a430ffb4bb504efef157671ee Mon Sep 17 00:00:00 2001 From: Marcel Jordense Date: Thu, 22 Aug 2024 11:29:14 +0200 Subject: [PATCH 166/207] fix compilation issue on qnx Signed-off-by: Marcel Jordense --- src/psmx_iox/src/scheduling.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/psmx_iox/src/scheduling.cpp b/src/psmx_iox/src/scheduling.cpp index b3e1e16452..6cb1cfa910 100644 --- a/src/psmx_iox/src/scheduling.cpp +++ b/src/psmx_iox/src/scheduling.cpp @@ -60,8 +60,8 @@ static bool valid_priority(prioclass_t cl, int prio) static void trim(std::string &s) { - s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(std::isspace))).base(), s.end()); - s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isspace)))); + s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {return !std::isspace(ch);}).base(), s.end()); + s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {return !std::isspace(ch);})); } bool sched_info_setpriority(sched_info& si, const std::string& x) From 4c0a3f0c1d49f86b58172421ff90736cd32ba883 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Wed, 4 Dec 2019 14:03:10 +0100 Subject: [PATCH 167/207] expose-seqnum-via-sampleinfo Signed-off-by: TheFixer --- src/core/ddsc/include/dds/dds.h | 2 ++ src/core/ddsc/src/dds_rhc_default.c | 2 ++ src/core/ddsi/include/dds/ddsi/ddsi_serdata.h | 1 + src/core/ddsi/src/ddsi_receive.c | 9 +++++---- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/ddsc/include/dds/dds.h b/src/core/ddsc/include/dds/dds.h index 96db93bbc6..65f05b43dc 100644 --- a/src/core/ddsc/include/dds/dds.h +++ b/src/core/ddsc/include/dds/dds.h @@ -322,6 +322,8 @@ typedef struct dds_sample_info uint32_t generation_rank; /** difference in generations between the sample and most recent sample of the same instance when read/take was called */ uint32_t absolute_generation_rank; + /** sequence number of the data (relative to the publisher); always 0 for invalid samples */ + int64_t seq_no; } dds_sample_info_t; diff --git a/src/core/ddsc/src/dds_rhc_default.c b/src/core/ddsc/src/dds_rhc_default.c index 42ed2378bc..6e2b1c0149 100644 --- a/src/core/ddsc/src/dds_rhc_default.c +++ b/src/core/ddsc/src/dds_rhc_default.c @@ -1956,6 +1956,7 @@ static void make_sample_info (dds_sample_info_t *si, const struct rhc_instance * si->absolute_generation_rank = get_absolute_generation_rank (inst, sample); si->valid_data = true; si->source_timestamp = sample->sample->timestamp.v; + si->seq_no = sample->sample->seq_no; } static void make_sample_info_invsample (dds_sample_info_t *si, const struct rhc_instance *inst) @@ -1972,6 +1973,7 @@ static void make_sample_info_invsample (dds_sample_info_t *si, const struct rhc_ si->absolute_generation_rank = 0; si->valid_data = false; si->source_timestamp = inst->tstamp.v; + si->seq_no = 0; /* sequence number for invalid sample is meaningless; use 0 in this case */ } static bool read_sample_update_conditions (struct dds_rhc_default *rhc, struct trigger_info_pre *pre, struct trigger_info_post *post, struct trigger_info_qcond *trig_qc, struct rhc_instance *inst, dds_querycond_mask_t conds, bool sample_wasread) diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h index c75607d6c4..daded109f8 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h @@ -41,6 +41,7 @@ struct ddsi_serdata { /* these get set by generic code after creating the serdata */ ddsrt_wctime_t timestamp; uint32_t statusinfo; + ddsi_seqno_t seq_no; /* FIXME: can I get rid of this one? */ ddsrt_mtime_t twrite; /* write time, not source timestamp, set post-throttling */ diff --git a/src/core/ddsi/src/ddsi_receive.c b/src/core/ddsi/src/ddsi_receive.c index e96de5901d..1cb274ed18 100644 --- a/src/core/ddsi/src/ddsi_receive.c +++ b/src/core/ddsi/src/ddsi_receive.c @@ -1974,13 +1974,14 @@ static int handle_Gap (struct ddsi_receiver_state *rst, ddsrt_etime_t tnow, stru return 1; } -static struct ddsi_serdata *get_serdata (struct ddsi_sertype const * const type, const struct ddsi_rdata *fragchain, uint32_t sz, int justkey, unsigned statusinfo, ddsrt_wctime_t tstamp) +static struct ddsi_serdata *get_serdata (struct ddsi_sertype const * const type, const struct ddsi_rdata *fragchain, uint32_t sz, int justkey, unsigned statusinfo, ddsrt_wctime_t tstamp, ddsi_seqno_t seq_no) { struct ddsi_serdata *sd = ddsi_serdata_from_ser (type, justkey ? SDK_KEY : SDK_DATA, fragchain, sz); if (sd) { sd->statusinfo = statusinfo; sd->timestamp = tstamp; + sd->seq_no = seq_no; } return sd; } @@ -2025,7 +2026,7 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, si->data_smhdr_flags, sampleinfo->size); return NULL; } - sample = get_serdata (type, fragchain, sampleinfo->size, 0, statusinfo, tstamp); + sample = get_serdata (type, fragchain, sampleinfo->size, 0, statusinfo, tstamp, sampleinfo->seq); } else if (sampleinfo->size) { @@ -2034,12 +2035,12 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, as one would expect to receive */ if (data_smhdr_flags & DDSI_DATA_FLAG_KEYFLAG) { - sample = get_serdata (type, fragchain, sampleinfo->size, 1, statusinfo, tstamp); + sample = get_serdata (type, fragchain, sampleinfo->size, 1, statusinfo, tstamp, sampleinfo->seq); } else { assert (data_smhdr_flags & DDSI_DATA_FLAG_DATAFLAG); - sample = get_serdata (type, fragchain, sampleinfo->size, 0, statusinfo, tstamp); + sample = get_serdata (type, fragchain, sampleinfo->size, 0, statusinfo, tstamp, sampleinfo->seq); } } else if (data_smhdr_flags & DDSI_DATA_FLAG_INLINE_QOS) From dc3352353823cd3357d342b67da47c75f1cccb05 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 18 Nov 2022 13:51:59 +0100 Subject: [PATCH 168/207] Use seqno_t as type for sequence numbers (which is defined as uint64_t) Signed-off-by: TheFixer --- src/core/ddsc/include/dds/dds.h | 2 +- src/core/ddsi/include/dds/ddsi/ddsi_serdata.h | 2 +- src/core/ddsi/src/ddsi_receive.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ddsc/include/dds/dds.h b/src/core/ddsc/include/dds/dds.h index 65f05b43dc..6653dd4b5f 100644 --- a/src/core/ddsc/include/dds/dds.h +++ b/src/core/ddsc/include/dds/dds.h @@ -323,7 +323,7 @@ typedef struct dds_sample_info /** difference in generations between the sample and most recent sample of the same instance when read/take was called */ uint32_t absolute_generation_rank; /** sequence number of the data (relative to the publisher); always 0 for invalid samples */ - int64_t seq_no; + uint64_t seq_no; } dds_sample_info_t; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h index daded109f8..b960d85705 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h @@ -41,7 +41,7 @@ struct ddsi_serdata { /* these get set by generic code after creating the serdata */ ddsrt_wctime_t timestamp; uint32_t statusinfo; - ddsi_seqno_t seq_no; + ddsi_seqno_t sequence_number; /* FIXME: can I get rid of this one? */ ddsrt_mtime_t twrite; /* write time, not source timestamp, set post-throttling */ diff --git a/src/core/ddsi/src/ddsi_receive.c b/src/core/ddsi/src/ddsi_receive.c index 1cb274ed18..72eae50e6c 100644 --- a/src/core/ddsi/src/ddsi_receive.c +++ b/src/core/ddsi/src/ddsi_receive.c @@ -1981,7 +1981,7 @@ static struct ddsi_serdata *get_serdata (struct ddsi_sertype const * const type, { sd->statusinfo = statusinfo; sd->timestamp = tstamp; - sd->seq_no = seq_no; + sd->sequence_number = seq_no; } return sd; } From ae0dc840cfad8bd845383b033d4bdad99b1c1a15 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Wed, 21 Dec 2022 15:08:28 +0100 Subject: [PATCH 169/207] Removed seq_no from dds_sampleinfo_t and add sequence_number to ddsi_serdata Signed-off-by: TheFixer --- src/core/ddsc/include/dds/dds.h | 2 -- src/core/ddsc/src/dds_rhc_default.c | 2 -- src/core/ddsi/src/ddsi_discovery.c | 1 + src/core/ddsi/src/ddsi_receive.c | 1 + src/core/ddsi/src/ddsi_serdata.c | 2 ++ 5 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/ddsc/include/dds/dds.h b/src/core/ddsc/include/dds/dds.h index 6653dd4b5f..96db93bbc6 100644 --- a/src/core/ddsc/include/dds/dds.h +++ b/src/core/ddsc/include/dds/dds.h @@ -322,8 +322,6 @@ typedef struct dds_sample_info uint32_t generation_rank; /** difference in generations between the sample and most recent sample of the same instance when read/take was called */ uint32_t absolute_generation_rank; - /** sequence number of the data (relative to the publisher); always 0 for invalid samples */ - uint64_t seq_no; } dds_sample_info_t; diff --git a/src/core/ddsc/src/dds_rhc_default.c b/src/core/ddsc/src/dds_rhc_default.c index 6e2b1c0149..42ed2378bc 100644 --- a/src/core/ddsc/src/dds_rhc_default.c +++ b/src/core/ddsc/src/dds_rhc_default.c @@ -1956,7 +1956,6 @@ static void make_sample_info (dds_sample_info_t *si, const struct rhc_instance * si->absolute_generation_rank = get_absolute_generation_rank (inst, sample); si->valid_data = true; si->source_timestamp = sample->sample->timestamp.v; - si->seq_no = sample->sample->seq_no; } static void make_sample_info_invsample (dds_sample_info_t *si, const struct rhc_instance *inst) @@ -1973,7 +1972,6 @@ static void make_sample_info_invsample (dds_sample_info_t *si, const struct rhc_ si->absolute_generation_rank = 0; si->valid_data = false; si->source_timestamp = inst->tstamp.v; - si->seq_no = 0; /* sequence number for invalid sample is meaningless; use 0 in this case */ } static bool read_sample_update_conditions (struct dds_rhc_default *rhc, struct trigger_info_pre *pre, struct trigger_info_post *post, struct trigger_info_qcond *trig_qc, struct rhc_instance *inst, dds_querycond_mask_t conds, bool sample_wasread) diff --git a/src/core/ddsi/src/ddsi_discovery.c b/src/core/ddsi/src/ddsi_discovery.c index 9d8eb0dbe8..c99a438df7 100644 --- a/src/core/ddsi/src/ddsi_discovery.c +++ b/src/core/ddsi/src/ddsi_discovery.c @@ -427,6 +427,7 @@ int ddsi_builtins_dqueue_handler (const struct ddsi_rsample_info *sampleinfo, co d->timestamp = (sampleinfo->timestamp.v != DDSRT_WCTIME_INVALID.v) ? sampleinfo->timestamp : ddsrt_time_wallclock (); d->statusinfo = statusinfo; + d->sequence_number = sampleinfo->seq; // set protocol version & vendor id for plist types // FIXME: find a better way then fixing these up afterward if (d->ops == &ddsi_serdata_ops_plist) diff --git a/src/core/ddsi/src/ddsi_receive.c b/src/core/ddsi/src/ddsi_receive.c index 72eae50e6c..9c43e4ebe1 100644 --- a/src/core/ddsi/src/ddsi_receive.c +++ b/src/core/ddsi/src/ddsi_receive.c @@ -2063,6 +2063,7 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, { sample->statusinfo = statusinfo; sample->timestamp = tstamp; + sample->sequence_number = sampleinfo->seq; } } else diff --git a/src/core/ddsi/src/ddsi_serdata.c b/src/core/ddsi/src/ddsi_serdata.c index 6b015e380c..36f8a16b2b 100644 --- a/src/core/ddsi/src/ddsi_serdata.c +++ b/src/core/ddsi/src/ddsi_serdata.c @@ -27,6 +27,7 @@ void ddsi_serdata_init (struct ddsi_serdata *d, const struct ddsi_sertype *tp, e d->hash = 0; d->statusinfo = 0; d->timestamp.v = INT64_MIN; + d->sequence_number = 0; d->twrite.v = INT64_MIN; d->loan = NULL; ddsrt_atomic_st32 (&d->refc, 1); @@ -42,6 +43,7 @@ struct ddsi_serdata *ddsi_serdata_copy_as_type (const struct ddsi_sertype *type, { converted->statusinfo = serdata->statusinfo; converted->timestamp = serdata->timestamp; + converted->sequence_number = serdata->sequence_number; } ddsi_serdata_to_ser_unref (tmpref, &iov); return converted; From 6ca74324a17cb4aa0e5625c3337e53d325816a27 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Mon, 23 Jan 2023 09:13:02 +0100 Subject: [PATCH 170/207] Add .get_sequencenumber function to ddsi_serdata_ops interface, so that the sequence number can be retrieved from serdata Signed-off-by: TheFixer --- src/core/ddsc/src/dds_serdata_builtintopic.c | 2 ++ src/core/ddsc/src/dds_serdata_default.c | 10 ++++++++++ src/core/ddsc/tests/cdr.c | 3 ++- src/core/ddsi/include/dds/ddsi/ddsi_serdata.h | 12 ++++++++++++ src/core/ddsi/src/ddsi_serdata_cdr.c | 1 + src/core/ddsi/src/ddsi_serdata_plist.c | 3 ++- src/core/ddsi/src/ddsi_serdata_pserop.c | 3 ++- 7 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/core/ddsc/src/dds_serdata_builtintopic.c b/src/core/ddsc/src/dds_serdata_builtintopic.c index 303183f49d..c3d7038efc 100644 --- a/src/core/ddsc/src/dds_serdata_builtintopic.c +++ b/src/core/ddsc/src/dds_serdata_builtintopic.c @@ -444,6 +444,7 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_builtintopic = { .untyped_to_sample = serdata_builtin_untyped_to_sample, .print = serdata_builtin_type_print, .get_keyhash = NULL, + .get_sequencenumber = NULL, .from_loaned_sample = NULL, .from_psmx = NULL }; @@ -501,6 +502,7 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_builtintopic_topic = { .untyped_to_sample = serdata_builtin_untyped_to_sample, .print = serdata_builtin_type_print, .get_keyhash = NULL, + .get_sequencenumber = NULL, .from_loaned_sample = NULL, .from_psmx = NULL }; diff --git a/src/core/ddsc/src/dds_serdata_default.c b/src/core/ddsc/src/dds_serdata_default.c index 243660d4a5..4f1a0abc40 100644 --- a/src/core/ddsc/src/dds_serdata_default.c +++ b/src/core/ddsc/src/dds_serdata_default.c @@ -159,6 +159,12 @@ static uint32_t serdata_default_get_size(const struct ddsi_serdata *dcmn) return d->pos + (uint32_t)sizeof (struct dds_cdr_header); } +static uint64_t serdata_default_get_sequencenumber(const struct ddsi_serdata *dcmn) +{ + const struct dds_serdata_default *d = (const struct dds_serdata_default *) dcmn; + return d->c.sequence_number; +} + static bool serdata_default_eqkey(const struct ddsi_serdata *acmn, const struct ddsi_serdata *bcmn) { const struct dds_serdata_default *a = (const struct dds_serdata_default *)acmn; @@ -983,6 +989,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_cdr = { .untyped_to_sample = serdata_default_untyped_to_sample_cdr, .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, + .get_sequencenumber = serdata_default_get_sequencenumber, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; @@ -1003,6 +1010,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_xcdr2 = { .untyped_to_sample = serdata_default_untyped_to_sample_cdr, .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, + .get_sequencenumber = serdata_default_get_sequencenumber, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; @@ -1023,6 +1031,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_cdr_nokey = { .untyped_to_sample = serdata_default_untyped_to_sample_cdr_nokey, .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, + .get_sequencenumber = serdata_default_get_sequencenumber, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; @@ -1043,6 +1052,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_xcdr2_nokey = { .untyped_to_sample = serdata_default_untyped_to_sample_cdr_nokey, .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, + .get_sequencenumber = serdata_default_get_sequencenumber, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; diff --git a/src/core/ddsc/tests/cdr.c b/src/core/ddsc/tests/cdr.c index ae0b2f625c..c73b7124ad 100644 --- a/src/core/ddsc/tests/cdr.c +++ b/src/core/ddsc/tests/cdr.c @@ -461,7 +461,8 @@ static const struct ddsi_serdata_ops sd_ops = { .to_untyped = sd_to_untyped, .untyped_to_sample = sd_untyped_to_sample, .print = sd_print, - .get_keyhash = sd_get_keyhash + .get_keyhash = sd_get_keyhash, + .get_sequencenumber = 0 }; /*---------------------------------------------------------------- diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h index b960d85705..704aee4bd7 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h @@ -160,6 +160,9 @@ typedef size_t (*ddsi_serdata_print_t) (const struct ddsi_sertype *type, const s typedef void (*ddsi_serdata_get_keyhash_t) (const struct ddsi_serdata *d, struct ddsi_keyhash *buf, bool force_md5) ddsrt_nonnull_all; +/* Sequence number of the sample as advertised by the publisher */ +typedef uint64_t (*ddsi_serdata_get_sequencenumber_t) (const struct ddsi_serdata *d); + // Used for taking a loaned sample and constructing a serdata around this // takes over ownership of loan on success (leaves it unchanged on failure) typedef struct ddsi_serdata* (*ddsi_serdata_from_loan_t) (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const char *sample, struct dds_loaned_sample *loaned_sample, bool will_require_cdr) @@ -185,6 +188,7 @@ struct ddsi_serdata_ops { ddsi_serdata_free_t free; ddsi_serdata_print_t print; ddsi_serdata_get_keyhash_t get_keyhash; + ddsi_serdata_get_sequencenumber_t get_sequencenumber; ddsi_serdata_from_loan_t from_loaned_sample; ddsi_serdata_from_psmx_t from_psmx; }; @@ -284,6 +288,14 @@ inline struct ddsi_serdata *ddsi_serdata_from_ser (const struct ddsi_sertype *ty return type->serdata_ops->from_ser (type, kind, fragchain, size); } +/** @component typesupport_if */ +DDS_INLINE_EXPORT inline uint64_t ddsi_serdata_sequencenumber(const struct ddsi_serdata *d) + ddsrt_nonnull_all; + +inline uint64_t ddsi_serdata_sequencenumber(const struct ddsi_serdata *d) { + return d->ops->get_sequencenumber (d); +} + /** @component typesupport_if */ DDS_INLINE_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_ser_iov (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, ddsrt_msg_iovlen_t niov, const ddsrt_iovec_t *iov, size_t size) ddsrt_nonnull_all ddsrt_attribute_warn_unused_result; diff --git a/src/core/ddsi/src/ddsi_serdata_cdr.c b/src/core/ddsi/src/ddsi_serdata_cdr.c index 64df0aac46..a68f6c24ad 100644 --- a/src/core/ddsi/src/ddsi_serdata_cdr.c +++ b/src/core/ddsi/src/ddsi_serdata_cdr.c @@ -355,5 +355,6 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_cdr = { .to_untyped = serdata_cdr_to_untyped, .untyped_to_sample = serdata_cdr_untyped_to_sample_cdr, .print = serdata_cdr_print_cdr, + .get_sequencenumber = 0, .get_keyhash = 0 }; diff --git a/src/core/ddsi/src/ddsi_serdata_plist.c b/src/core/ddsi/src/ddsi_serdata_plist.c index 34c3869d15..02c4fb43d5 100644 --- a/src/core/ddsi/src/ddsi_serdata_plist.c +++ b/src/core/ddsi/src/ddsi_serdata_plist.c @@ -326,5 +326,6 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_plist = { .to_untyped = serdata_plist_to_untyped, .untyped_to_sample = serdata_plist_untyped_to_sample, .print = serdata_plist_print_plist, - .get_keyhash = serdata_plist_get_keyhash + .get_keyhash = serdata_plist_get_keyhash, + .get_sequencenumber = 0 }; diff --git a/src/core/ddsi/src/ddsi_serdata_pserop.c b/src/core/ddsi/src/ddsi_serdata_pserop.c index 3bee78e371..0a73a13809 100644 --- a/src/core/ddsi/src/ddsi_serdata_pserop.c +++ b/src/core/ddsi/src/ddsi_serdata_pserop.c @@ -309,5 +309,6 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_pserop = { .to_untyped = serdata_pserop_to_untyped, .untyped_to_sample = serdata_pserop_untyped_to_sample, .print = serdata_pserop_print_pserop, - .get_keyhash = serdata_pserop_get_keyhash + .get_keyhash = serdata_pserop_get_keyhash, + .get_sequencenumber = 0 }; From 45a6636c700c8578e7dd54a263be93f290dd9a26 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Mon, 1 May 2023 09:23:32 +0200 Subject: [PATCH 171/207] First attempt to add writer guid to serdata interface Signed-off-by: TheFixer --- src/core/ddsc/src/dds_serdata_builtintopic.c | 2 + src/core/ddsc/src/dds_serdata_default.c | 10 +++++ src/core/ddsc/tests/cdr.c | 3 +- src/core/ddsi/include/dds/ddsi/ddsi_serdata.h | 13 ++++++ src/core/ddsi/src/ddsi_receive.c | 40 ++++++------------- src/core/ddsi/src/ddsi_serdata_cdr.c | 3 +- src/core/ddsi/src/ddsi_serdata_plist.c | 3 +- src/core/ddsi/src/ddsi_serdata_pserop.c | 3 +- 8 files changed, 46 insertions(+), 31 deletions(-) diff --git a/src/core/ddsc/src/dds_serdata_builtintopic.c b/src/core/ddsc/src/dds_serdata_builtintopic.c index c3d7038efc..a4b7fd3c78 100644 --- a/src/core/ddsc/src/dds_serdata_builtintopic.c +++ b/src/core/ddsc/src/dds_serdata_builtintopic.c @@ -445,6 +445,7 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_builtintopic = { .print = serdata_builtin_type_print, .get_keyhash = NULL, .get_sequencenumber = NULL, + .get_writer_guid = NULL, .from_loaned_sample = NULL, .from_psmx = NULL }; @@ -503,6 +504,7 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_builtintopic_topic = { .print = serdata_builtin_type_print, .get_keyhash = NULL, .get_sequencenumber = NULL, + .get_writer_guid = NULL, .from_loaned_sample = NULL, .from_psmx = NULL }; diff --git a/src/core/ddsc/src/dds_serdata_default.c b/src/core/ddsc/src/dds_serdata_default.c index 4f1a0abc40..2436f30763 100644 --- a/src/core/ddsc/src/dds_serdata_default.c +++ b/src/core/ddsc/src/dds_serdata_default.c @@ -165,6 +165,12 @@ static uint64_t serdata_default_get_sequencenumber(const struct ddsi_serdata *dc return d->c.sequence_number; } +static ddsi_guid_t *serdata_default_get_writer_guid(const struct ddsi_serdata *dcmn) +{ + struct dds_serdata_default *d = (struct dds_serdata_default *) dcmn; + return &d->c.writer_guid; +} + static bool serdata_default_eqkey(const struct ddsi_serdata *acmn, const struct ddsi_serdata *bcmn) { const struct dds_serdata_default *a = (const struct dds_serdata_default *)acmn; @@ -990,6 +996,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_cdr = { .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, .get_sequencenumber = serdata_default_get_sequencenumber, + .get_writer_guid = serdata_default_get_writer_guid, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; @@ -1011,6 +1018,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_xcdr2 = { .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, .get_sequencenumber = serdata_default_get_sequencenumber, + .get_writer_guid = serdata_default_get_writer_guid, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; @@ -1032,6 +1040,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_cdr_nokey = { .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, .get_sequencenumber = serdata_default_get_sequencenumber, + .get_writer_guid = serdata_default_get_writer_guid, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; @@ -1053,6 +1062,7 @@ const struct ddsi_serdata_ops dds_serdata_ops_xcdr2_nokey = { .print = serdata_default_print_cdr, .get_keyhash = serdata_default_get_keyhash, .get_sequencenumber = serdata_default_get_sequencenumber, + .get_writer_guid = serdata_default_get_writer_guid, .from_loaned_sample = serdata_default_from_loaned_sample, .from_psmx = serdata_default_from_psmx }; diff --git a/src/core/ddsc/tests/cdr.c b/src/core/ddsc/tests/cdr.c index c73b7124ad..28c5429b6a 100644 --- a/src/core/ddsc/tests/cdr.c +++ b/src/core/ddsc/tests/cdr.c @@ -462,7 +462,8 @@ static const struct ddsi_serdata_ops sd_ops = { .untyped_to_sample = sd_untyped_to_sample, .print = sd_print, .get_keyhash = sd_get_keyhash, - .get_sequencenumber = 0 + .get_sequencenumber = 0, + .get_writer_guid = 0 }; /*---------------------------------------------------------------- diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h index 704aee4bd7..2a6b7aa1f0 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_serdata.h @@ -42,6 +42,7 @@ struct ddsi_serdata { ddsrt_wctime_t timestamp; uint32_t statusinfo; ddsi_seqno_t sequence_number; + ddsi_guid_t writer_guid; /* FIXME: can I get rid of this one? */ ddsrt_mtime_t twrite; /* write time, not source timestamp, set post-throttling */ @@ -163,6 +164,9 @@ typedef void (*ddsi_serdata_get_keyhash_t) (const struct ddsi_serdata *d, struct /* Sequence number of the sample as advertised by the publisher */ typedef uint64_t (*ddsi_serdata_get_sequencenumber_t) (const struct ddsi_serdata *d); +/* Get the reference to the guid of the writer that published the serdata */ +typedef ddsi_guid_t * (*ddsi_serdata_get_writer_guid_t) (const struct ddsi_serdata *d); + // Used for taking a loaned sample and constructing a serdata around this // takes over ownership of loan on success (leaves it unchanged on failure) typedef struct ddsi_serdata* (*ddsi_serdata_from_loan_t) (const struct ddsi_sertype *type, enum ddsi_serdata_kind kind, const char *sample, struct dds_loaned_sample *loaned_sample, bool will_require_cdr) @@ -189,6 +193,7 @@ struct ddsi_serdata_ops { ddsi_serdata_print_t print; ddsi_serdata_get_keyhash_t get_keyhash; ddsi_serdata_get_sequencenumber_t get_sequencenumber; + ddsi_serdata_get_writer_guid_t get_writer_guid; ddsi_serdata_from_loan_t from_loaned_sample; ddsi_serdata_from_psmx_t from_psmx; }; @@ -288,6 +293,14 @@ inline struct ddsi_serdata *ddsi_serdata_from_ser (const struct ddsi_sertype *ty return type->serdata_ops->from_ser (type, kind, fragchain, size); } +/** @component typesupport_if */ +DDS_INLINE_EXPORT inline ddsi_guid_t *ddsi_serdata_writer_guid(const struct ddsi_serdata *d) + ddsrt_nonnull_all; + +inline ddsi_guid_t *ddsi_serdata_writer_guid(const struct ddsi_serdata *d) { + return d->ops->get_writer_guid (d); +} + /** @component typesupport_if */ DDS_INLINE_EXPORT inline uint64_t ddsi_serdata_sequencenumber(const struct ddsi_serdata *d) ddsrt_nonnull_all; diff --git a/src/core/ddsi/src/ddsi_receive.c b/src/core/ddsi/src/ddsi_receive.c index 9c43e4ebe1..3bf103031f 100644 --- a/src/core/ddsi/src/ddsi_receive.c +++ b/src/core/ddsi/src/ddsi_receive.c @@ -1974,15 +1974,9 @@ static int handle_Gap (struct ddsi_receiver_state *rst, ddsrt_etime_t tnow, stru return 1; } -static struct ddsi_serdata *get_serdata (struct ddsi_sertype const * const type, const struct ddsi_rdata *fragchain, uint32_t sz, int justkey, unsigned statusinfo, ddsrt_wctime_t tstamp, ddsi_seqno_t seq_no) +static struct ddsi_serdata *get_serdata (struct ddsi_sertype const * const type, const struct ddsi_rdata *fragchain, uint32_t sz, int justkey) { struct ddsi_serdata *sd = ddsi_serdata_from_ser (type, justkey ? SDK_KEY : SDK_DATA, fragchain, sz); - if (sd) - { - sd->statusinfo = statusinfo; - sd->timestamp = tstamp; - sd->sequence_number = seq_no; - } return sd; } @@ -2008,17 +2002,16 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, const ddsi_plist_t * __restrict qos = si->qos; const char *failmsg = NULL; struct ddsi_serdata *sample = NULL; + const struct ddsi_proxy_writer *pwr = sampleinfo->pwr; + ddsi_seqno_t seq = sampleinfo->seq; + ddsi_guid_t guid; + if (pwr) guid = pwr->e.guid; else memset (&guid, 0, sizeof (guid)); if (si->statusinfo == 0) { /* normal write */ if (!(data_smhdr_flags & DDSI_DATA_FLAG_DATAFLAG) || sampleinfo->size == 0) { - const struct ddsi_proxy_writer *pwr = sampleinfo->pwr; - ddsi_guid_t guid; - /* pwr can't currently be null, but that might change some day, and this being - an error path, it doesn't hurt to survive that */ - if (pwr) guid = pwr->e.guid; else memset (&guid, 0, sizeof (guid)); DDS_CTRACE (&gv->logconfig, "data(application, vendor %u.%u): "PGUIDFMT" #%"PRIu64": write without proper payload (data_smhdr_flags 0x%x size %"PRIu32")\n", sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], @@ -2026,7 +2019,7 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, si->data_smhdr_flags, sampleinfo->size); return NULL; } - sample = get_serdata (type, fragchain, sampleinfo->size, 0, statusinfo, tstamp, sampleinfo->seq); + sample = get_serdata (type, fragchain, sampleinfo->size, 0); } else if (sampleinfo->size) { @@ -2035,12 +2028,12 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, as one would expect to receive */ if (data_smhdr_flags & DDSI_DATA_FLAG_KEYFLAG) { - sample = get_serdata (type, fragchain, sampleinfo->size, 1, statusinfo, tstamp, sampleinfo->seq); + sample = get_serdata (type, fragchain, sampleinfo->size, 1); } else { assert (data_smhdr_flags & DDSI_DATA_FLAG_DATAFLAG); - sample = get_serdata (type, fragchain, sampleinfo->size, 0, statusinfo, tstamp, sampleinfo->seq); + sample = get_serdata (type, fragchain, sampleinfo->size, 0); } } else if (data_smhdr_flags & DDSI_DATA_FLAG_INLINE_QOS) @@ -2059,12 +2052,6 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, } else if ((sample = ddsi_serdata_from_keyhash (type, &qos->keyhash)) == NULL) failmsg = "keyhash is MD5 and can't be converted to key value"; - else - { - sample->statusinfo = statusinfo; - sample->timestamp = tstamp; - sample->sequence_number = sampleinfo->seq; - } } else { @@ -2073,9 +2060,6 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, if (sample == NULL) { /* No message => error out */ - const struct ddsi_proxy_writer *pwr = sampleinfo->pwr; - ddsi_guid_t guid; - if (pwr) guid = pwr->e.guid; else memset (&guid, 0, sizeof (guid)); DDS_CWARNING (&gv->logconfig, "data(application, vendor %u.%u): "PGUIDFMT" #%"PRIu64": deserialization %s/%s failed (%s)\n", sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], @@ -2085,6 +2069,11 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, } else { + sample->statusinfo = statusinfo; + sample->timestamp = tstamp; + sample->sequence_number = seq; + memcpy(&sample->writer_guid, &guid, sizeof(sample->writer_guid)); + if ((*tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, sample)) == NULL) { ddsi_serdata_unref (sample); @@ -2092,14 +2081,11 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk, } else if (gv->logconfig.c.mask & DDS_LC_TRACE) { - const struct ddsi_proxy_writer *pwr = sampleinfo->pwr; - ddsi_guid_t guid; char tmp[1024]; size_t res = 0; tmp[0] = 0; if (gv->logconfig.c.mask & DDS_LC_CONTENT) res = ddsi_serdata_print (sample, tmp, sizeof (tmp)); - if (pwr) guid = pwr->e.guid; else memset (&guid, 0, sizeof (guid)); GVTRACE ("data(application, vendor %u.%u): "PGUIDFMT" #%"PRIu64": ST%"PRIx32" %s/%s:%s%s", sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], PGUID (guid), sampleinfo->seq, statusinfo, diff --git a/src/core/ddsi/src/ddsi_serdata_cdr.c b/src/core/ddsi/src/ddsi_serdata_cdr.c index a68f6c24ad..2a80222acf 100644 --- a/src/core/ddsi/src/ddsi_serdata_cdr.c +++ b/src/core/ddsi/src/ddsi_serdata_cdr.c @@ -355,6 +355,7 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_cdr = { .to_untyped = serdata_cdr_to_untyped, .untyped_to_sample = serdata_cdr_untyped_to_sample_cdr, .print = serdata_cdr_print_cdr, + .get_keyhash = 0, .get_sequencenumber = 0, - .get_keyhash = 0 + .get_writer_guid = 0 }; diff --git a/src/core/ddsi/src/ddsi_serdata_plist.c b/src/core/ddsi/src/ddsi_serdata_plist.c index 02c4fb43d5..953e5d2225 100644 --- a/src/core/ddsi/src/ddsi_serdata_plist.c +++ b/src/core/ddsi/src/ddsi_serdata_plist.c @@ -327,5 +327,6 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_plist = { .untyped_to_sample = serdata_plist_untyped_to_sample, .print = serdata_plist_print_plist, .get_keyhash = serdata_plist_get_keyhash, - .get_sequencenumber = 0 + .get_sequencenumber = 0, + .get_writer_guid = 0 }; diff --git a/src/core/ddsi/src/ddsi_serdata_pserop.c b/src/core/ddsi/src/ddsi_serdata_pserop.c index 0a73a13809..50bf1f5386 100644 --- a/src/core/ddsi/src/ddsi_serdata_pserop.c +++ b/src/core/ddsi/src/ddsi_serdata_pserop.c @@ -310,5 +310,6 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_pserop = { .untyped_to_sample = serdata_pserop_untyped_to_sample, .print = serdata_pserop_print_pserop, .get_keyhash = serdata_pserop_get_keyhash, - .get_sequencenumber = 0 + .get_sequencenumber = 0, + .get_writer_guid = 0 }; From 5e19507959632ede1c34235ddd65f9d33ff8ee16 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Thu, 1 Jun 2023 11:08:56 +0200 Subject: [PATCH 172/207] Implement function dds_reader_store_historical_data() to deliver serdata to reader rhc Signed-off-by: TheFixer --- src/core/ddsc/include/dds/dds.h | 3 ++ src/core/ddsc/src/dds_reader.c | 78 +++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/src/core/ddsc/include/dds/dds.h b/src/core/ddsc/include/dds/dds.h index 96db93bbc6..6dfc3e8f41 100644 --- a/src/core/ddsc/include/dds/dds.h +++ b/src/core/ddsc/include/dds/dds.h @@ -1884,6 +1884,9 @@ dds_wait_for_acks(dds_entity_t publisher_or_writer, dds_duration_t timeout); * DOC_TODO The reader is a DDS Entity */ +DDS_EXPORT dds_return_t +dds_reader_store_historical_serdata (dds_entity_t reader, dds_guid_t guid, bool autodispose, struct ddsi_serdata *serdata); + /** * @brief Creates a new instance of a DDS reader. * @ingroup reader diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index fc76c17cb4..7b94d509af 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -40,6 +40,17 @@ #include "dds__builtin.h" #include "dds__statistics.h" #include "dds__psmx.h" +/* LH: likely some of the following includes can go */ +#if 0 +#include "dds__data_allocator.h" +#include "dds/ddsi/ddsi_sertype.h" +#include "dds/ddsi/ddsi_entity_index.h" +#include "dds/ddsi/ddsi_security_omg.h" +#include "dds/ddsi/ddsi_statistics.h" +#include "dds/ddsi/ddsi_endpoint_match.h" +#include "dds/ddsi/ddsi_serdata.h" +#include "dds/ddsi/ddsi_tkmap.h" +#endif DECL_ENTITY_LOCK_UNLOCK (dds_reader) @@ -484,6 +495,73 @@ const struct dds_entity_deriver dds_entity_deriver_reader = { .invoke_cbs_for_pending_events = dds_reader_invoke_cbs_for_pending_events }; +dds_return_t dds_reader_store_historical_serdata (dds_entity_t reader, dds_guid_t guid, bool autodispose, struct ddsi_serdata *serdata) +{ + dds_return_t ret; + dds_entity * e; + if ((ret = dds_entity_pin (reader, &e)) < 0) + return ret; + else if (dds_entity_kind (e) != DDS_KIND_READER) + { + dds_entity_unpin (e); + return DDS_RETCODE_ILLEGAL_OPERATION; + } + + dds_reader *dds_rd = (dds_reader *) e; + struct ddsi_reader *rd = dds_rd->m_rd; + struct ddsi_domaingv *gv = rd->e.gv; + + /* The serdata->writer_info contains the ddsi guid in BE format. + * To compare this with the guid we'll transfer the guid + * to the right format and compare both. + * LH: It feels a bit weird having to do this transformation, + * but it seems to work. However, I do have a difficulty in explaining + * why this is necessary. */ + struct ddsi_guid ddsiguid, tmp; + memcpy(&tmp, &guid, 16); + ddsiguid = ddsi_ntoh_guid(tmp); + + ddsi_thread_state_awake (ddsi_lookup_thread_state (), gv); + ddsrt_mutex_lock (&rd->e.lock); + + /* retrieve the topic key map used to get the instance id of the serdata */ + struct ddsi_tkmap_instance * tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata); + if (tk == NULL) { + ret = DDS_RETCODE_BAD_PARAMETER; + goto fail_get_writer_info; + } + + /* historical data is always unregistered */ + serdata->statusinfo |= DDSI_STATUSINFO_UNREGISTER; + /* set the writer guid of the serdata */ + serdata->writer_guid = ddsiguid; + /* timestamp and seqnum have already been set in the serdata by the caller */ + + /* We'll use the lowest possible strength when inserting historical data + * to ensure that live writers which are stronger always take precedence. + * We'll still need to figure out how to ensure that a live writer takes + * precedence in case the live writer also has the lowest possible strength. + */ + struct ddsi_writer_info wi; + wi.guid = ddsiguid; + wi.ownership_strength = INT32_MIN; /* use the lowest possible strength to ensure that live writers with a */ + wi.auto_dispose = autodispose; + wi.iid = tk->m_iid; + if (!dds_rhc_store (dds_rd->m_rhc, &wi, serdata, tk)) + { + ret = DDS_RETCODE_ERROR; + goto fail_rhc_store; + } + +fail_rhc_store: + ddsi_tkmap_instance_unref (gv->m_tkmap, tk); +fail_get_writer_info: + ddsrt_mutex_unlock (&rd->e.lock); + ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); + dds_entity_unpin (e); + return ret; +} + static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscriber, dds_entity_t topic, dds_guid_t *guid, const dds_qos_t *qos, const dds_listener_t *listener, struct dds_rhc *rhc) { dds_subscriber *sub = NULL; From 5484e8c9e8b70aad06cca8929716afca96f34cb9 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 7 Jul 2023 09:12:08 +0200 Subject: [PATCH 173/207] Use lifespan set to DDSRT_MTIME_NEVER when adding historical serdata to the rhc of a durable reader Signed-off-by: TheFixer --- src/core/ddsc/src/dds_reader.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index 7b94d509af..fa235c7086 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -510,7 +510,6 @@ dds_return_t dds_reader_store_historical_serdata (dds_entity_t reader, dds_guid_ dds_reader *dds_rd = (dds_reader *) e; struct ddsi_reader *rd = dds_rd->m_rd; struct ddsi_domaingv *gv = rd->e.gv; - /* The serdata->writer_info contains the ddsi guid in BE format. * To compare this with the guid we'll transfer the guid * to the right format and compare both. @@ -520,19 +519,24 @@ dds_return_t dds_reader_store_historical_serdata (dds_entity_t reader, dds_guid_ struct ddsi_guid ddsiguid, tmp; memcpy(&tmp, &guid, 16); ddsiguid = ddsi_ntoh_guid(tmp); - ddsi_thread_state_awake (ddsi_lookup_thread_state (), gv); ddsrt_mutex_lock (&rd->e.lock); - /* retrieve the topic key map used to get the instance id of the serdata */ - struct ddsi_tkmap_instance * tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata); + struct ddsi_tkmap_instance *tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata); if (tk == NULL) { ret = DDS_RETCODE_BAD_PARAMETER; - goto fail_get_writer_info; + goto fail_tkmap_lookup; + } + /* retrieve the builtin key map to get the iid for the writer */ + struct ddsi_tkmap_instance *tk_builtin = ddsi_builtintopic_get_tkmap_entry(gv->builtin_topic_interface, &ddsiguid); + if (tk_builtin == NULL) { + ret = DDS_RETCODE_BAD_PARAMETER; + goto fail_tk_builtin; } - /* historical data is always unregistered */ - serdata->statusinfo |= DDSI_STATUSINFO_UNREGISTER; + if (!ddsi_builtintopic_is_visible(gv->builtin_topic_interface, &ddsiguid, ddsi_get_entity_vendorid(&rd->e))) { + serdata->statusinfo |= DDSI_STATUSINFO_UNREGISTER; + } /* set the writer guid of the serdata */ serdata->writer_guid = ddsiguid; /* timestamp and seqnum have already been set in the serdata by the caller */ @@ -544,9 +548,12 @@ dds_return_t dds_reader_store_historical_serdata (dds_entity_t reader, dds_guid_ */ struct ddsi_writer_info wi; wi.guid = ddsiguid; - wi.ownership_strength = INT32_MIN; /* use the lowest possible strength to ensure that live writers with a */ + wi.ownership_strength = INT32_MIN; /* use the lowest possible strength to ensure that live writers always take precedence */ wi.auto_dispose = autodispose; - wi.iid = tk->m_iid; + wi.iid = tk_builtin->m_iid; +#ifdef DDS_HAS_LIFESPAN + wi.lifespan_exp = DDSRT_MTIME_NEVER; +#endif if (!dds_rhc_store (dds_rd->m_rhc, &wi, serdata, tk)) { ret = DDS_RETCODE_ERROR; @@ -554,8 +561,10 @@ dds_return_t dds_reader_store_historical_serdata (dds_entity_t reader, dds_guid_ } fail_rhc_store: + ddsi_tkmap_instance_unref (gv->m_tkmap, tk_builtin); +fail_tk_builtin: ddsi_tkmap_instance_unref (gv->m_tkmap, tk); -fail_get_writer_info: +fail_tkmap_lookup: ddsrt_mutex_unlock (&rd->e.lock); ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); dds_entity_unpin (e); From 1e71cd8dca584a627dd303639ac0d8b9c0e4934b Mon Sep 17 00:00:00 2001 From: TheFixer Date: Thu, 14 Sep 2023 16:27:21 +0200 Subject: [PATCH 174/207] create cmake infrastructure for durability Signed-off-by: TheFixer --- src/CMakeLists.txt | 13 ++++++ src/core/CMakeLists.txt | 4 ++ src/core/ddsc/src/dds_domain.c | 9 ++++ src/ddsrt/CMakeLists.txt | 2 +- src/ddsrt/include/dds/features.h.in | 3 ++ src/durability/CMakeLists.txt | 36 +++++++++++++++ .../include/dds/durability/dds_durability.h | 37 ++++++++++++++++ src/durability/src/dds_durability.c | 44 +++++++++++++++++++ 8 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 src/durability/CMakeLists.txt create mode 100644 src/durability/include/dds/durability/dds_durability.h create mode 100644 src/durability/src/dds_durability.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 00b0a19206..3c74cc5d1b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,6 +22,12 @@ function(PREPEND var prefix) set(${var} "${listVar}" PARENT_SCOPE) endfunction() +# Durable support is currently under development (beta). +# Therefore it is disabled by default. To enable durable support +# in CycloneDDS use the build option '-DENABLE_DURABILITY' +# when building CycloneDDS + +option(ENABLE_DURABILITY "Enable Durable support" OFF) option(ENABLE_SECURITY "Enable OMG DDS Security support" ON) option(ENABLE_LIFESPAN "Enable Lifespan QoS support" ON) option(ENABLE_DEADLINE_MISSED "Enable Deadline Missed QoS support" ON) @@ -113,6 +119,10 @@ if(ENABLE_ICEORYX) endif() endif() +if(ENABLE_DURABILITY) + message(STATUS "Building with Durable support") +endif() + if(BUILD_TESTING) add_subdirectory(ucunit) endif() @@ -125,4 +135,7 @@ add_subdirectory(security) if(ENABLE_ICEORYX) add_subdirectory(psmx_iox) endif() +if(ENABLE_DURABILITY) + add_subdirectory(durability) +endif() add_subdirectory(core) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index d4d23a49f5..638316912c 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -58,6 +58,10 @@ if(ENABLE_SECURITY) $>) endif() +if(ENABLE_DURABILITY) + target_link_libraries(ddsc PRIVATE "$") +endif() + include(cdr/CMakeLists.txt) include(ddsi/CMakeLists.txt) include(ddsc/CMakeLists.txt) diff --git a/src/core/ddsc/src/dds_domain.c b/src/core/ddsc/src/dds_domain.c index 68a332553b..6a5c356998 100644 --- a/src/core/ddsc/src/dds_domain.c +++ b/src/core/ddsc/src/dds_domain.c @@ -32,6 +32,10 @@ #include "dds__serdata_default.h" #include "dds__psmx.h" +#ifdef DDS_HAS_DURABILITY +#include "dds/durability/dds_durability.h" +#endif + static dds_return_t dds_domain_free (dds_entity *vdomain); const struct dds_entity_deriver dds_entity_deriver_domain = { @@ -302,6 +306,11 @@ dds_entity_t dds_create_domain (const dds_domainid_t domain, const char *config) const struct config_source config_src = { .kind = CFGKIND_XML, .u = { .xml = config } }; ret = dds_domain_create_internal_xml_or_raw (&dom, domain, false, &config_src); dds_entity_unpin_and_drop_ref (&dds_global.m_entity); + +#ifdef DDS_HAS_DURABILITY + dds_durability_init2(&dom->gv); +#endif + return ret; } diff --git a/src/ddsrt/CMakeLists.txt b/src/ddsrt/CMakeLists.txt index 3a2d5169e3..e553f8566c 100644 --- a/src/ddsrt/CMakeLists.txt +++ b/src/ddsrt/CMakeLists.txt @@ -356,7 +356,7 @@ set(DDSRT_WITH_LWIP ${WITH_LWIP}) set(DDSRT_WITH_FREERTOS ${WITH_FREERTOS}) foreach(feature TCP_TLS SECURITY LIFESPAN DEADLINE_MISSED NETWORK_PARTITIONS - TYPELIB TYPE_DISCOVERY TOPIC_DISCOVERY QOS_PROVIDER) + TYPELIB TYPE_DISCOVERY TOPIC_DISCOVERY QOS_PROVIDER DURABILITY) set(DDS_HAS_${feature} ${ENABLE_${feature}}) endforeach() diff --git a/src/ddsrt/include/dds/features.h.in b/src/ddsrt/include/dds/features.h.in index a294df19bf..2fb1021b0c 100644 --- a/src/ddsrt/include/dds/features.h.in +++ b/src/ddsrt/include/dds/features.h.in @@ -38,6 +38,9 @@ /* Not for general use, specificly for testing psmx Cyclone DDS plugin */ #cmakedefine DDS_ALLOW_NESTED_DOMAIN 1 +/* Whether or not durable support is included */ +#cmakedefine DDS_HAS_DURABILITY 1 + /* Not intended for general use, whether building a static library, specifically testing psmx and security */ #cmakedefine DDS_IS_STATIC_LIBRARY 1 diff --git a/src/durability/CMakeLists.txt b/src/durability/CMakeLists.txt new file mode 100644 index 0000000000..30cba56886 --- /dev/null +++ b/src/durability/CMakeLists.txt @@ -0,0 +1,36 @@ +# Copyright(c) 2006 to 2021 ZettaScale Technology and others +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Public License v. 2.0 which is available at +# http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +# v. 1.0 which is available at +# http://www.eclipse.org/org/documents/edl-v10.php. +# +# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause +# +set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}") +set(binary_dir "${CMAKE_CURRENT_BINARY_DIR}") + +add_library(durability INTERFACE) + +target_include_directories( + durability INTERFACE + "$" + "$" + "$") + +set(headers + "${source_dir}/include/dds/durability/dds_durability.h") + +set(sources + "${source_dir}/src/dds_durability.c") + +target_sources(durability INTERFACE ${headers} ${sources}) + +install( + DIRECTORY + "${source_dir}/include/" + "${binary_dir}/include/" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + COMPONENT dev + FILES_MATCHING PATTERN "*.h") \ No newline at end of file diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h new file mode 100644 index 0000000000..65cf52600e --- /dev/null +++ b/src/durability/include/dds/durability/dds_durability.h @@ -0,0 +1,37 @@ +// Copyright(c) 2006 to 2020 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#ifndef DDS_DURABILITY_H +#define DDS_DURABILITY_H + +#include "dds/ddsi/ddsi_domaingv.h" +#include "dds/ddsrt/retcode.h" +#include "ddsc/dds.h" +#include "dds__types.h" +#include "dds/ddsc/dds_rhc.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/* Integration functions for durability plugins */ +typedef int (*plugin_init)(const char *argument, void **context, struct ddsi_domaingv *gv); +typedef int (*plugin_finalize)(void *context); + +dds_return_t dds_durability_init2 (struct ddsi_domaingv* gv); +dds_return_t dds_durability_fini2 (void); +void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc); +void dds_durability_wait_for_ds (uint32_t quorum, dds_time_t timeout); + +#if defined (__cplusplus) +} +#endif + +#endif /* DDS_DURABILITY_H */ diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c new file mode 100644 index 0000000000..471c12ea50 --- /dev/null +++ b/src/durability/src/dds_durability.c @@ -0,0 +1,44 @@ +/* + * Copyright(c) 2006 to 2019 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +#include "dds/durability/dds_durability.h" +#include "ddsc/dds.h" + + +dds_return_t dds_durability_init2 (struct ddsi_domaingv* gv) +{ + printf("!!!!!!!!!!!!!!!!!!! src/durability/core/src/dds_durability_init()\n"); + return DDS_RETCODE_OK; +} + +dds_return_t dds_durability_fini2 (void) +{ + printf("!!!!!!!!!!!!!!!!!!! src/durability/core/src/dds_durability_fini()\n"); + return DDS_RETCODE_OK; +} + +void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc) +{ + /* create the administration to store transient data */ + /* create a durability reader that sucks and stores it in the store */ + + DDSRT_UNUSED_ARG(reader); + return; +} + +void dds_durability_wait_for_ds (uint32_t quorum, dds_time_t timeout) +{ + (void)quorum; + (void)timeout; + return; +} + + From 2ffb6592a90e75cedf7b02ae9d3b074efbb7fa34 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 10 Oct 2023 11:03:10 +0200 Subject: [PATCH 175/207] Add durability as a trace category and initialize durability when the first participant is created Signed-off-by: TheFixer --- docs/manual/config/config_file_reference.rst | 3 +- docs/manual/options.md | 3 +- etc/cyclonedds.rnc | 3 +- etc/cyclonedds.xsd | 3 +- src/core/ddsc/src/dds_domain.c | 8 - src/core/ddsc/src/dds_participant.c | 15 + src/core/ddsc/src/dds_write.c | 12 + src/core/ddsi/src/ddsi__cfgelems.h | 4 +- src/core/ddsi/src/ddsi_config.c | 4 +- src/ddsrt/include/dds/ddsrt/log.h | 5 +- src/durability/CMakeLists.txt | 6 +- .../dds/durability/client_durability.h | 223 ++++++ .../include/dds/durability/dds_durability.h | 7 +- src/durability/src/client_durability.c | 606 ++++++++++++++++ src/durability/src/dds_durability.c | 677 +++++++++++++++++- 15 files changed, 1547 insertions(+), 32 deletions(-) create mode 100644 src/durability/include/dds/durability/client_durability.h create mode 100644 src/durability/src/client_durability.c diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index a526e4da16..8afbd11780 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -2603,7 +2603,7 @@ The default value is: ``false`` ------------------------------------ One of: -* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, content, malformed, trace, user, user1, user2, user3 +* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, content, malformed, durability, trace, user, user1, user2, user3 * Or empty This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are: @@ -2639,6 +2639,7 @@ This element enables individual logging categories. These are enabled in additio * topic: tracing of topic definitions * plist: tracing of discovery parameter list interpretation + * durability: tracing of durable data * content: tracing of sample contents diff --git a/docs/manual/options.md b/docs/manual/options.md index bd01a1bb4c..b8c021b593 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -1809,7 +1809,7 @@ The default value is: `false` #### //CycloneDDS/Domain/Tracing/Category One of: -* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, content, malformed, trace, user, user1, user2, user3 +* Comma-separated list of: fatal, error, warning, info, config, discovery, data, radmin, timing, traffic, topic, tcp, plist, whc, throttle, rhc, content, malformed, durability, trace, user, user1, user2, user3 * Or empty This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are: @@ -1845,6 +1845,7 @@ This element enables individual logging categories. These are enabled in additio * topic: tracing of topic definitions * plist: tracing of discovery parameter list interpretation + * durability: tracing of durable data * content: tracing of sample contents diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index 0370114513..e7e1b1799a 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -1272,6 +1272,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
  • plist: tracing of discovery parameter list interpretation
  • content: tracing of sample contents
  • malformed: dump malformed full packet as warning
  • +
  • durability: tracing of durable data
  • user: all user-defined tracing categories
  • user1: user-defined tracing category 1
  • user2: user-defined tracing category 2
  • @@ -1281,7 +1282,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==

    The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is trace.

    The default value is: <empty>

    """ ] ] element Category { - xsd:token { pattern = "((fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|malformed|trace|user|user1|user2|user3)(,(fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|malformed|trace|user|user1|user2|user3))*)|" } + xsd:token { pattern = "((fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|malformed|trace|user|user1|user2|user3)(,(fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|malformed|durability|trace|user|user1|user2|user3))*)|" } }? & [ a:documentation [ xml:lang="en" """

    This option specifies where the logging is printed to. Note that stdout and stderr are treated as special values, representing "standard out" and "standard error" respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings.

    diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index 15e0a9c9c5..8ae1f49816 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -1900,6 +1900,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> <li><i>plist</i>: tracing of discovery parameter list interpretation</li> <li><i>content</i>: tracing of sample contents</li> <li><i>malformed</i>: dump malformed full packet as warning</li> +<li><i>durability</i>: tracing of durable data</li></li> <li><i>user</i>: all user-defined tracing categories</li> <li><i>user1</i>: user-defined tracing category 1</li> <li><i>user2</i>: user-defined tracing category 2</li> @@ -1911,7 +1912,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br>
    - +
    diff --git a/src/core/ddsc/src/dds_domain.c b/src/core/ddsc/src/dds_domain.c index 6a5c356998..d2612033d7 100644 --- a/src/core/ddsc/src/dds_domain.c +++ b/src/core/ddsc/src/dds_domain.c @@ -32,10 +32,6 @@ #include "dds__serdata_default.h" #include "dds__psmx.h" -#ifdef DDS_HAS_DURABILITY -#include "dds/durability/dds_durability.h" -#endif - static dds_return_t dds_domain_free (dds_entity *vdomain); const struct dds_entity_deriver dds_entity_deriver_domain = { @@ -307,10 +303,6 @@ dds_entity_t dds_create_domain (const dds_domainid_t domain, const char *config) ret = dds_domain_create_internal_xml_or_raw (&dom, domain, false, &config_src); dds_entity_unpin_and_drop_ref (&dds_global.m_entity); -#ifdef DDS_HAS_DURABILITY - dds_durability_init2(&dom->gv); -#endif - return ret; } diff --git a/src/core/ddsc/src/dds_participant.c b/src/core/ddsc/src/dds_participant.c index a3551d1b6f..dcdcf0f7db 100644 --- a/src/core/ddsc/src/dds_participant.c +++ b/src/core/ddsc/src/dds_participant.c @@ -28,6 +28,10 @@ #include "dds__builtin.h" #include "dds__qos.h" +#ifdef DDS_HAS_DURABILITY +#include "dds/durability/dds_durability.h" +#endif + DECL_ENTITY_LOCK_UNLOCK (dds_participant) #define DDS_PARTICIPANT_STATUS_MASK (0u) @@ -58,6 +62,11 @@ static dds_return_t dds_participant_delete (dds_entity *e) if ((ret = ddsi_delete_participant (&e->m_domain->gv, &e->m_guid)) < 0) DDS_CERROR (&e->m_domain->gv.logconfig, "dds_participant_delete: internal error %"PRId32"\n", ret); ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); + +#ifdef DDS_HAS_DURABILITY + dds_durability_fini(); +#endif + return DDS_RETCODE_OK; } @@ -167,9 +176,15 @@ static dds_entity_t create_participant_flags_guid (const dds_domainid_t domain, ddsrt_mutex_unlock (&dom->m_entity.m_mutex); dds_entity_init_complete (&pp->m_entity); + /* drop temporary extra ref to domain, dds_init */ dds_entity_unpin_and_drop_ref (&dom->m_entity); dds_entity_unpin_and_drop_ref (&dds_global.m_entity); + +#ifdef DDS_HAS_DURABILITY + dds_durability_init (domain, &dom->gv); +#endif + return ret; err_entity_init: diff --git a/src/core/ddsc/src/dds_write.c b/src/core/ddsc/src/dds_write.c index 7f51867bb9..9e70d9cc89 100644 --- a/src/core/ddsc/src/dds_write.c +++ b/src/core/ddsc/src/dds_write.c @@ -31,6 +31,10 @@ #include "dds__loaned_sample.h" #include "dds__psmx.h" +#ifdef DDS_HAS_DURABILITY +#include "dds/durability/dds_durability.h" +#endif + struct ddsi_serdata_plain { struct ddsi_serdata p; }; struct ddsi_serdata_any { struct ddsi_serdata a; }; @@ -772,6 +776,14 @@ dds_return_t dds_write_impl (dds_writer *wr, const void *data, dds_time_t timest if (!evaluate_topic_filter (wr, data, sdkind)) return DDS_RETCODE_OK; +#ifdef DDS_HAS_DURABILITY + if ((ddsi_wr->xqos->durability.kind == DDS_DURABILITY_TRANSIENT) || (ddsi_wr->xqos->durability.kind == DDS_DURABILITY_PERSISTENT)) { + if ((ret = dds_durability_check_quorum_reached(wr)) != DDS_RETCODE_OK) { + return DDS_RETCODE_PRECONDITION_NOT_MET; + } + } +#endif + // I. psmx loan => assert (psmx && is_memcpy_safe) // a. psmx only // - no need for a serdata, so skip everything and deliver loan via PSMX diff --git a/src/core/ddsi/src/ddsi__cfgelems.h b/src/core/ddsi/src/ddsi__cfgelems.h index 9f67e84f85..97d243e9fa 100644 --- a/src/core/ddsi/src/ddsi__cfgelems.h +++ b/src/core/ddsi/src/ddsi__cfgelems.h @@ -169,7 +169,6 @@ static struct cfgelem entity_autonaming_attributes[] = { END_MARKER }; - static struct cfgelem general_cfgelems[] = { STRING("MulticastRecvNetworkInterfaceAddresses", NULL, 1, "preferred", MEMBER(networkRecvAddressStrings), @@ -2023,6 +2022,7 @@ static struct cfgelem tracing_cfgelems[] = { "
  • plist: tracing of discovery parameter list interpretation
  • \n" "
  • content: tracing of sample contents
  • \n" "
  • malformed: dump malformed full packet as warning
  • \n" + "
  • durability: tracing of durable data
  • \n" "
  • user: all user-defined tracing categories
  • \n" "
  • user1: user-defined tracing category 1
  • \n" "
  • user2: user-defined tracing category 2
  • \n" @@ -2040,7 +2040,7 @@ static struct cfgelem tracing_cfgelems[] = { VALUES( "fatal","error","warning","info","config","discovery","data","radmin", "timing","traffic","topic","tcp","plist","whc","throttle","rhc", - "content","malformed","trace","user","user1","user2","user3" + "content","malformed","durability","trace","user","user1","user2","user3" )), ENUM("Verbosity", NULL, 1, "none", NOMEMBER, diff --git a/src/core/ddsi/src/ddsi_config.c b/src/core/ddsi/src/ddsi_config.c index 40c97a178b..a3b5c50fbc 100644 --- a/src/core/ddsi/src/ddsi_config.c +++ b/src/core/ddsi/src/ddsi_config.c @@ -1009,10 +1009,10 @@ GENERIC_ENUM_CTYPE (shm_loglevel, enum ddsi_shm_loglevel) /* "trace" is special: it enables (nearly) everything */ static const char *tracemask_names[] = { - "fatal", "error", "warning", "info", "config", "discovery", "data", "radmin", "timing", "traffic", "topic", "tcp", "plist", "whc", "throttle", "rhc", "content", "malformed", "user1", "user2", "user3", "user", "trace", NULL + "fatal", "error", "warning", "info", "config", "discovery", "data", "radmin", "timing", "traffic", "topic", "tcp", "plist", "whc", "throttle", "rhc", "content", "malformed", "durability", "user1", "user2", "user3", "user", "trace", NULL }; static const uint32_t tracemask_codes[] = { - DDS_LC_FATAL, DDS_LC_ERROR, DDS_LC_WARNING, DDS_LC_INFO, DDS_LC_CONFIG, DDS_LC_DISCOVERY, DDS_LC_DATA, DDS_LC_RADMIN, DDS_LC_TIMING, DDS_LC_TRAFFIC, DDS_LC_TOPIC, DDS_LC_TCP, DDS_LC_PLIST, DDS_LC_WHC, DDS_LC_THROTTLE, DDS_LC_RHC, DDS_LC_CONTENT, DDS_LC_MALFORMED, DDS_LC_USER1, DDS_LC_USER2, DDS_LC_USER3, DDS_LC_USER, DDS_LC_ALL + DDS_LC_FATAL, DDS_LC_ERROR, DDS_LC_WARNING, DDS_LC_INFO, DDS_LC_CONFIG, DDS_LC_DISCOVERY, DDS_LC_DATA, DDS_LC_RADMIN, DDS_LC_TIMING, DDS_LC_TRAFFIC, DDS_LC_TOPIC, DDS_LC_TCP, DDS_LC_PLIST, DDS_LC_WHC, DDS_LC_THROTTLE, DDS_LC_RHC, DDS_LC_CONTENT, DDS_LC_MALFORMED, DDS_LC_DUR, DDS_LC_USER1, DDS_LC_USER2, DDS_LC_USER3, DDS_LC_USER, DDS_LC_ALL }; static enum update_result uf_tracemask (struct ddsi_cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) diff --git a/src/ddsrt/include/dds/ddsrt/log.h b/src/ddsrt/include/dds/ddsrt/log.h index a22d312927..c33709cfc7 100644 --- a/src/ddsrt/include/dds/ddsrt/log.h +++ b/src/ddsrt/include/dds/ddsrt/log.h @@ -82,6 +82,9 @@ extern "C" { #define DDS_LC_SYSDEF (524288u) /** Debug/trace messages related to qos provider. */ #define DDS_LC_QOSPROV (1048576u) +/** Debug/trace messages related to durable support */ +#define DDS_LC_DUR (2097152u) + /** Reserved for user defined log categories (e.g. user application that uses Cyclone logger) */ #define DDS_LC_USER1 (1u << 29) #define DDS_LC_USER2 (1u << 30) @@ -93,7 +96,7 @@ extern "C" { (DDS_LC_FATAL | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_INFO | \ DDS_LC_CONFIG | DDS_LC_DISCOVERY | DDS_LC_DATA | DDS_LC_TRACE | \ DDS_LC_TIMING | DDS_LC_TRAFFIC | DDS_LC_TCP | DDS_LC_THROTTLE | \ - DDS_LC_CONTENT | DDS_LC_USER) + DDS_LC_CONTENT | DDS_LC_DUR | DDS_LC_USER) /** @}*/ #define DDS_LOG_MASK \ diff --git a/src/durability/CMakeLists.txt b/src/durability/CMakeLists.txt index 30cba56886..aec416df73 100644 --- a/src/durability/CMakeLists.txt +++ b/src/durability/CMakeLists.txt @@ -20,10 +20,12 @@ target_include_directories( "$") set(headers - "${source_dir}/include/dds/durability/dds_durability.h") + "${source_dir}/include/dds/durability/dds_durability.h" + "${source_dir}/include/dds/durability/client_durability.h") set(sources - "${source_dir}/src/dds_durability.c") + "${source_dir}/src/dds_durability.c" + "${source_dir}/src/client_durability.c") target_sources(durability INTERFACE ${headers} ${sources}) diff --git a/src/durability/include/dds/durability/client_durability.h b/src/durability/include/dds/durability/client_durability.h new file mode 100644 index 0000000000..5f2649c6b3 --- /dev/null +++ b/src/durability/include/dds/durability/client_durability.h @@ -0,0 +1,223 @@ +/**************************************************************** + + IMPORTANT: + + The file contains the definitions for the client durability related topics. + This file is partially copied from the output generated by durabledupport.idl + because we cannot generate code from an idl file due to cyclic dependencies + in idlc_generate(). + +*****************************************************************/ +#ifndef CLIENT_DURABILITY_H +#define CLIENT_DURABILITY_H + +#include "dds/ddsc/dds_public_impl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint8_t DurableSupport_id_t[16]; + +#define DurableSupport_id_t__alloc() \ +((DurableSupport_id_t*) dds_alloc (sizeof (DurableSupport_id_t))); + +typedef uint64_t DurableSupport_session_id_t; + +#define DurableSupport_session_id_t__alloc() \ +((DurableSupport_session_id_t*) dds_alloc (sizeof (DurableSupport_session_id_t))); + +typedef uint16_t DurableSupport_session_kind_t; + +#define DurableSupport_session_kind_t__alloc() \ +((DurableSupport_session_kind_t*) dds_alloc (sizeof (DurableSupport_session_kind_t))); + +typedef uint16_t DurableSupport_beadtype_t; + +#define DurableSupport_beadtype_t__alloc() \ +((DurableSupport_beadtype_t*) dds_alloc (sizeof (DurableSupport_beadtype_t))); + +typedef struct DurableSupport_status +{ + DurableSupport_id_t id; + char * hostname; + char * name; +} DurableSupport_status; + +extern const dds_topic_descriptor_t DurableSupport_status_desc; + +#define DurableSupport_status__alloc() \ +((DurableSupport_status*) dds_alloc (sizeof (DurableSupport_status))); + +#define DurableSupport_status_free(d,o) \ +dds_sample_free ((d), &DurableSupport_status_desc, (o)) + +typedef struct DurableSupport_request_id_t +{ + DurableSupport_id_t client; + uint64_t seq; +} DurableSupport_request_id_t; + +extern const dds_topic_descriptor_t DurableSupport_request_id_t_desc; + +#define DurableSupport_request_id_t__alloc() \ +((DurableSupport_request_id_t*) dds_alloc (sizeof (DurableSupport_request_id_t))); + +#define DurableSupport_request_id_t_free(d,o) \ +dds_sample_free ((d), &DurableSupport_request_id_t_desc, (o)) + +#ifndef DDS_SEQUENCE_STRING_DEFINED +#define DDS_SEQUENCE_STRING_DEFINED +typedef struct dds_sequence_string +{ + uint32_t _maximum; + uint32_t _length; + char **_buffer; + bool _release; +} dds_sequence_string; + +#define dds_sequence_string__alloc() \ +((dds_sequence_string*) dds_alloc (sizeof (dds_sequence_string))); + +#define dds_sequence_string_allocbuf(l) \ +((char **) dds_alloc ((l) * sizeof (char*))) +#endif /* DDS_SEQUENCE_STRING_DEFINED */ + +typedef struct DurableSupport_request +{ + struct DurableSupport_request_id_t requestid; + char * partition; + char * tpname; + dds_sequence_string alignment_partition; +} DurableSupport_request; + +extern const dds_topic_descriptor_t DurableSupport_request_desc; + +#define DurableSupport_request__alloc() \ +((DurableSupport_request*) dds_alloc (sizeof (DurableSupport_request))); + +#define DurableSupport_request_free(d,o) \ +dds_sample_free ((d), &DurableSupport_request_desc, (o)) + +#define DurableSupport_BEADTYPE_SESSION 1 +#define DurableSupport_BEADTYPE_SET 2 +#define DurableSupport_BEADTYPE_WRITER 3 +#define DurableSupport_BEADTYPE_DATA 4 +#define DurableSupport_SESSION_KIND_START 1 +#define DurableSupport_SESSION_KIND_END 2 +#define DurableSupport_SESSION_KIND_ABORT 3 + +typedef struct DurableSupport_session_t +{ + DurableSupport_session_kind_t kind; + DurableSupport_session_id_t session_id; +} DurableSupport_session_t; + +#ifndef DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED +#define DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED +typedef struct dds_sequence_DurableSupport_id_t +{ + uint32_t _maximum; + uint32_t _length; + DurableSupport_id_t *_buffer; + bool _release; +} dds_sequence_DurableSupport_id_t; + +#define dds_sequence_DurableSupport_id_t__alloc() \ +((dds_sequence_DurableSupport_id_t*) dds_alloc (sizeof (dds_sequence_DurableSupport_id_t))); + +#define dds_sequence_DurableSupport_id_t_allocbuf(l) \ +((DurableSupport_id_t *) dds_alloc ((l) * sizeof (DurableSupport_id_t))) +#endif /* DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED */ + +typedef struct DurableSupport_set_t +{ + char * partition; + char * tpname; + uint32_t flags; + dds_sequence_DurableSupport_id_t addressees; +} DurableSupport_set_t; + +typedef struct DurableSupport_range +{ + uint64_t lb; + uint64_t ub; +} DurableSupport_range; + +#ifndef DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED +#define DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED +typedef struct dds_sequence_DurableSupport_range +{ + uint32_t _maximum; + uint32_t _length; + struct DurableSupport_range *_buffer; + bool _release; +} dds_sequence_DurableSupport_range; + +#define dds_sequence_DurableSupport_range__alloc() \ +((dds_sequence_DurableSupport_range*) dds_alloc (sizeof (dds_sequence_DurableSupport_range))); + +#define dds_sequence_DurableSupport_range_allocbuf(l) \ +((struct DurableSupport_range *) dds_alloc ((l) * sizeof (struct DurableSupport_range))) +#endif /* DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED */ + +typedef struct DurableSupport_writer_t +{ + DurableSupport_id_t id; + uint32_t flags; + dds_sequence_DurableSupport_range ranges; +} DurableSupport_writer_t; + +#ifndef DDS_SEQUENCE_OCTET_DEFINED +#define DDS_SEQUENCE_OCTET_DEFINED +typedef struct dds_sequence_octet +{ + uint32_t _maximum; + uint32_t _length; + uint8_t *_buffer; + bool _release; +} dds_sequence_octet; + +#define dds_sequence_octet__alloc() \ +((dds_sequence_octet*) dds_alloc (sizeof (dds_sequence_octet))); + +#define dds_sequence_octet_allocbuf(l) \ +((uint8_t *) dds_alloc ((l) * sizeof (uint8_t))) +#endif /* DDS_SEQUENCE_OCTET_DEFINED */ + +typedef struct DurableSupport_data_t +{ + dds_sequence_octet blob; +} DurableSupport_data_t; + +typedef struct DurableSupport_content +{ + DurableSupport_beadtype_t _d; + union + { + struct DurableSupport_session_t session; + struct DurableSupport_set_t set; + struct DurableSupport_writer_t writer; + struct DurableSupport_data_t data; + } _u; +} DurableSupport_content; + +typedef struct DurableSupport_bead +{ + DurableSupport_id_t id; + struct DurableSupport_content body; +} DurableSupport_bead; + +extern const dds_topic_descriptor_t DurableSupport_bead_desc; + +#define DurableSupport_bead__alloc() \ +((DurableSupport_bead*) dds_alloc (sizeof (DurableSupport_bead))); + +#define DurableSupport_bead_free(d,o) \ +dds_sample_free ((d), &DurableSupport_bead_desc, (o)) + +#ifdef __cplusplus +} +#endif + +#endif /* CLIENT_DURABILITY_H */ diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h index 65cf52600e..c7b8a1f5cf 100644 --- a/src/durability/include/dds/durability/dds_durability.h +++ b/src/durability/include/dds/durability/dds_durability.h @@ -25,10 +25,11 @@ extern "C" { typedef int (*plugin_init)(const char *argument, void **context, struct ddsi_domaingv *gv); typedef int (*plugin_finalize)(void *context); -dds_return_t dds_durability_init2 (struct ddsi_domaingv* gv); -dds_return_t dds_durability_fini2 (void); +dds_return_t dds_durability_init (const dds_domainid_t domain, struct ddsi_domaingv *gv); +dds_return_t dds_durability_fini (void); void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc); -void dds_durability_wait_for_ds (uint32_t quorum, dds_time_t timeout); +dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer); +bool dds_durability_is_terminating (void); #if defined (__cplusplus) } diff --git a/src/durability/src/client_durability.c b/src/durability/src/client_durability.c new file mode 100644 index 0000000000..ea5429a4d8 --- /dev/null +++ b/src/durability/src/client_durability.c @@ -0,0 +1,606 @@ +/**************************************************************** + + IMPORTANT: + + The file contains the definitions for the client durability related topics. + This file is partially copied from the output generated by durabledupport.idl + because we cannot generate code from an idl file due to cyclic dependencies + in idlc_generate(). + +*****************************************************************/ +#include "../include/dds/durability/client_durability.h" + +static const uint32_t DurableSupport_status_ops [] = +{ + /* status */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_status, id), 16u, + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_status, hostname), + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_status, name), + DDS_OP_RTS, + + /* key: id */ + DDS_OP_KOF | 1, 1u /* order: 0 */ +}; + +static const dds_key_descriptor_t DurableSupport_status_keys[1] = +{ + { "id", 9, 0 } +}; + +/* Type Information: + [MINIMAL 1609a972dd9ffc746226aaae0ce7] (#deps: 1) + - [MINIMAL 43f53a2be35b432cc735e9431a89] + [COMPLETE 3ae8d3b6272f54c8257bf018eda8] (#deps: 1) + - [COMPLETE aca4d5a256d39713924333e85c6d] +*/ +#define TYPE_INFO_CDR_DurableSupport_status (const unsigned char []){ \ + 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x16, 0x09, 0xa9, 0x72, 0xdd, 0x9f, 0xfc, 0x74, 0x62, 0x26, 0xaa, \ + 0xae, 0x0c, 0xe7, 0x00, 0x58, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x3a, 0xe8, 0xd3, \ + 0xb6, 0x27, 0x2f, 0x54, 0xc8, 0x25, 0x7b, 0xf0, 0x18, 0xed, 0xa8, 0x00, 0x8f, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ + 0x40, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_status 148u +#define TYPE_MAP_CDR_DurableSupport_status (const unsigned char []){ \ + 0x9a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0x16, 0x09, 0xa9, 0x72, 0xdd, 0x9f, 0xfc, \ + 0x74, 0x62, 0x26, 0xaa, 0xae, 0x0c, 0xe7, 0x00, 0x54, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x08, 0x97, 0xac, 0xf4, \ + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0xb0, 0x68, 0x93, 0x1c, \ + 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ + 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ + 0xf4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf2, 0x3a, 0xe8, 0xd3, 0xb6, 0x27, 0x2f, 0x54, \ + 0xc8, 0x25, 0x7b, 0xf0, 0x18, 0xed, 0xa8, 0x00, 0x8b, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x74, 0x61, 0x74, \ + 0x75, 0x73, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x09, 0x00, 0x00, 0x00, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, \ + 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ + 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0xf2, 0x3a, 0xe8, 0xd3, 0xb6, 0x27, 0x2f, 0x54, 0xc8, 0x25, 0x7b, 0xf0, 0x18, 0xed, 0xa8, 0xf1, \ + 0x16, 0x09, 0xa9, 0x72, 0xdd, 0x9f, 0xfc, 0x74, 0x62, 0x26, 0xaa, 0xae, 0x0c, 0xe7, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_status 476u +const dds_topic_descriptor_t DurableSupport_status_desc = +{ + .m_size = sizeof (DurableSupport_status), + .m_align = dds_alignof (DurableSupport_status), + .m_flagset = DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 1u, + .m_typename = "DurableSupport::status", + .m_keys = DurableSupport_status_keys, + .m_nops = 5, + .m_ops = DurableSupport_status_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_status, .sz = TYPE_INFO_CDR_SZ_DurableSupport_status }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_status, .sz = TYPE_MAP_CDR_SZ_DurableSupport_status } +}; + +static const uint32_t DurableSupport_request_id_t_ops [] = +{ + /* request_id_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), + DDS_OP_RTS +}; + +/* Type Information: + [MINIMAL 28dabddcc42d4b6a3d640fd522a4] (#deps: 1) + - [MINIMAL 43f53a2be35b432cc735e9431a89] + [COMPLETE 852fffc913b7ee54aadae7a1859a] (#deps: 1) + - [COMPLETE aca4d5a256d39713924333e85c6d] +*/ +#define TYPE_INFO_CDR_DurableSupport_request_id_t (const unsigned char []){ \ + 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, \ + 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, \ + 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ + 0x40, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_request_id_t 148u +#define TYPE_MAP_CDR_DurableSupport_request_id_t (const unsigned char []){ \ + 0x8a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ + 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, \ + 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, \ + 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ + 0xe4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ + 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ + 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0xf1, \ + 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_request_id_t 444u +const dds_topic_descriptor_t DurableSupport_request_id_t_desc = +{ + .m_size = sizeof (DurableSupport_request_id_t), + .m_align = dds_alignof (DurableSupport_request_id_t), + .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 0u, + .m_typename = "DurableSupport::request_id_t", + .m_keys = NULL, + .m_nops = 4, + .m_ops = DurableSupport_request_id_t_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request_id_t, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request_id_t }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request_id_t, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request_id_t } +}; + +static const uint32_t DurableSupport_request_ops [] = +{ + /* request */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_EXT, offsetof (DurableSupport_request, requestid), (3u << 16u) + 10u /* request_id_t */, + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, partition), + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STR, offsetof (DurableSupport_request, alignment_partition), + DDS_OP_RTS, + + /* request_id_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), + DDS_OP_RTS, + + /* key: requestid.client */ + DDS_OP_KOF | 2, 1u /* order: 0 */, 1u /* order: 0 */, + + /* key: requestid.seq */ + DDS_OP_KOF | 2, 1u /* order: 0 */, 4u /* order: 1 */ +}; + +static const dds_key_descriptor_t DurableSupport_request_keys[2] = +{ + { "requestid.client", 18, 0 }, + { "requestid.seq", 21, 1 } +}; + +/* Type Information: + [MINIMAL 54af0d70dd88f2a169924dd8b880] (#deps: 2) + - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] + - [MINIMAL 43f53a2be35b432cc735e9431a89] + [COMPLETE 77ef4931b703e23e4f8f33c76508] (#deps: 2) + - [COMPLETE 852fffc913b7ee54aadae7a1859a] + - [COMPLETE aca4d5a256d39713924333e85c6d] +*/ +#define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ + 0xc0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x54, 0xaf, 0x0d, 0x70, 0xdd, 0x88, 0xf2, 0xa1, 0x69, 0x92, 0x4d, \ + 0xd8, 0xb8, 0x80, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ + 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x77, 0xef, 0x49, 0x31, 0xb7, 0x03, 0xe2, 0x3e, 0x4f, 0x8f, 0x33, \ + 0xc7, 0x65, 0x08, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ + 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ + 0x40, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_request 196u +#define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ + 0x06, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0x54, 0xaf, 0x0d, 0x70, 0xdd, 0x88, 0xf2, \ + 0xa1, 0x69, 0x92, 0x4d, 0xd8, 0xb8, 0x80, 0x00, 0x69, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, \ + 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x3c, 0xb0, 0x21, 0x74, 0x00, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ + 0x11, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, \ + 0x00, 0xd8, 0xc7, 0x47, 0x1e, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, \ + 0x0f, 0xd5, 0x22, 0xa4, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, \ + 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, \ + 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ + 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xbc, 0x01, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0xf2, 0x77, 0xef, 0x49, 0x31, 0xb7, 0x03, 0xe2, 0x3e, 0x4f, 0x8f, 0x33, \ + 0xc7, 0x65, 0x08, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x00, \ + 0x96, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, \ + 0x9a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, \ + 0x64, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, \ + 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, \ + 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x02, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ + 0x46, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0xf2, 0x77, 0xef, 0x49, 0x31, 0xb7, 0x03, 0xe2, 0x3e, 0x4f, 0x8f, 0x33, \ + 0xc7, 0x65, 0x08, 0xf1, 0x54, 0xaf, 0x0d, 0x70, 0xdd, 0x88, 0xf2, 0xa1, 0x69, 0x92, 0x4d, 0xd8, \ + 0xb8, 0x80, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, \ + 0x9a, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, \ + 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_request 814u +const dds_topic_descriptor_t DurableSupport_request_desc = +{ + .m_size = sizeof (DurableSupport_request), + .m_align = dds_alignof (DurableSupport_request), + .m_flagset = DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 2u, + .m_typename = "DurableSupport::request", + .m_keys = DurableSupport_request_keys, + .m_nops = 10, + .m_ops = DurableSupport_request_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request } +}; + +static const uint32_t DurableSupport_bead_ops [] = +{ + /* bead */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_bead, id), 16u, + DDS_OP_ADR | DDS_OP_TYPE_EXT, offsetof (DurableSupport_bead, body), (3u << 16u) + 4u /* content */, + DDS_OP_RTS, + + /* content */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_content, _d), 4u, (20u << 16u) + 4u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 17 /* session_t */, 1, offsetof (DurableSupport_content, _u.session), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 19 /* set_t */, 2, offsetof (DurableSupport_content, _u.set), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 31 /* writer_t */, 3, offsetof (DurableSupport_content, _u.writer), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 44 /* data_t */, 4, offsetof (DurableSupport_content, _u.data), 0u, + DDS_OP_RTS, + + /* session_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_2BY, offsetof (DurableSupport_session_t, kind), + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_session_t, session_id), + DDS_OP_RTS, + + /* set_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, partition), + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, tpname), + DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_set_t, flags), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_ARR, offsetof (DurableSupport_set_t, addressees), sizeof (DurableSupport_id_t), (8u << 16u) + 4u, + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, 0u, 16u, + DDS_OP_RTS, + DDS_OP_RTS, + + /* writer_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_writer_t, id), 16u, + DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_writer_t, flags), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_writer_t, ranges), sizeof (DurableSupport_range), (4u << 16u) + 5u /* range */, + DDS_OP_RTS, + + /* range */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, lb), + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, ub), + DDS_OP_RTS, + + /* data_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_data_t, blob), + DDS_OP_RTS, + + /* key: id */ + DDS_OP_KOF | 1, 1u /* order: 0 */ +}; + +static const dds_key_descriptor_t DurableSupport_bead_keys[1] = +{ + { "id", 73, 0 } +}; + +/* Type Information: + [MINIMAL 1915eb63b1ad4283c95c42298512] (#deps: 9) + - [MINIMAL 43f53a2be35b432cc735e9431a89] + - [MINIMAL 219813f96895eb7a5bddfe02219f] + - [MINIMAL 80455e796dd3437163cb532089da] + - [MINIMAL 7fe2256248fb0dc7c6a9b6c616fb] + - [MINIMAL d8398b259af5a04792e296996c27] + - [MINIMAL 0d686e35dcd446cd843b793a485c] + - [MINIMAL 2f19a070996d925b553ac288a028] + - [MINIMAL ef038b7b19448c9ce27fa1c268cd] + - [MINIMAL a580b28d8a19d4a49d2794aae844] + [COMPLETE a89c569f6d508f3372a8c6407126] (#deps: 10) + - [COMPLETE aca4d5a256d39713924333e85c6d] + - [COMPLETE 28eef02baeaad008f0cda9febf47] + - [COMPLETE 105e7fa73d9700c1960716873c88] + - [COMPLETE 5de973c540260a829429a905efcd] + - [COMPLETE 838f13c80cfd7a0061fb91f88e49] + - [COMPLETE 9c5d42ec81585355d169823828eb] + - [COMPLETE dd9a1bfb3c68ff5066e4b763a939] + - [COMPLETE 1b62cfe76a5bdbc5e39d9f6d3975] + - [COMPLETE d8d43c2295c185a21b9591a7126c] + - [COMPLETE a092964f6f76e3d643846ba36f9b] +*/ +#define TYPE_INFO_CDR_DurableSupport_bead (const unsigned char []){ \ + 0x28, 0x02, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x00, 0x01, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x19, 0x15, 0xeb, 0x63, 0xb1, 0xad, 0x42, 0x83, 0xc9, 0x5c, 0x42, \ + 0x29, 0x85, 0x12, 0x00, 0x55, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, \ + 0x09, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x21, 0x98, 0x13, 0xf9, 0x68, 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0x00, \ + 0xcc, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ + 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0x00, \ + 0x55, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ + 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, \ + 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, \ + 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, 0x28, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, \ + 0x37, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, \ + 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0x18, 0x01, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa8, 0x9c, 0x56, \ + 0x9f, 0x6d, 0x50, 0x8f, 0x33, 0x72, 0xa8, 0xc6, 0x40, 0x71, 0x26, 0x00, 0x83, 0x00, 0x00, 0x00, \ + 0x0a, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ + 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x28, 0xee, 0xf0, 0x2b, 0xae, 0xaa, 0xd0, \ + 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, 0x47, 0x00, 0x13, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, \ + 0x39, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, \ + 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, \ + 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, \ + 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0x00, \ + 0xb5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, 0x5b, 0xdb, \ + 0xc5, 0xe3, 0x9d, 0x9f, 0x6d, 0x39, 0x75, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, \ + 0x61, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, \ + 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x00, 0x4f, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_bead 556u +#define TYPE_MAP_CDR_DurableSupport_bead (const unsigned char []){ \ + 0xc0, 0x03, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xf1, 0x19, 0x15, 0xeb, 0x63, 0xb1, 0xad, 0x42, \ + 0x83, 0xc9, 0x5c, 0x42, 0x29, 0x85, 0x12, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x21, 0x98, 0x13, 0xf9, 0x68, \ + 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ + 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x21, 0x98, 0x13, 0xf9, 0x68, \ + 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, \ + 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ + 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ + 0xa4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, \ + 0xfb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0xd6, 0xf4, 0x0c, \ + 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, \ + 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf1, 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, \ + 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xa8, 0x2f, 0xee, 0xe3, \ + 0x24, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ + 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ + 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x7f, 0xe2, 0x25, 0x62, \ + 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x80, \ + 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xd9, 0x39, 0xaa, \ + 0xf7, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ + 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x7f, 0xc8, 0xef, \ + 0x54, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, \ + 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x06, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ + 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, 0x46, 0xcd, \ + 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ + 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ + 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ + 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x73, 0xed, \ + 0xc9, 0x6c, 0xf1, 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, \ + 0x28, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, \ + 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, \ + 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x8d, 0x81, 0x02, 0xfb, 0xf1, 0xef, \ + 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x00, 0x00, \ + 0x33, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x08, 0x26, 0x40, 0x3e, 0xc6, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x08, 0x1c, 0x78, 0xb4, 0x86, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, \ + 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \ + 0xee, 0x26, 0x90, 0x8b, 0xcf, 0x05, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xf2, 0xa8, 0x9c, 0x56, \ + 0x9f, 0x6d, 0x50, 0x8f, 0x33, 0x72, 0xa8, 0xc6, 0x40, 0x71, 0x26, 0x00, 0x7f, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x62, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0x28, 0xee, 0xf0, 0x2b, 0xae, 0xaa, 0xd0, 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, \ + 0x47, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, \ + 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, \ + 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ + 0xf2, 0x28, 0xee, 0xf0, 0x2b, 0xae, 0xaa, 0xd0, 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, 0x47, 0x00, \ + 0x0f, 0x01, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x00, 0x13, 0x00, 0x00, 0x00, \ + 0x11, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, \ + 0x88, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, \ + 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x08, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, \ + 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, \ + 0x5b, 0xdb, 0xc5, 0xe3, 0x9d, 0x9f, 0x6d, 0x39, 0x75, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xa0, \ + 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, \ + 0x00, 0x00, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, \ + 0x3c, 0x88, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x62, 0x65, 0x61, 0x64, 0x74, 0x79, 0x70, 0x65, \ + 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x5d, 0xe9, \ + 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x89, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x83, \ + 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x6b, 0x69, 0x6e, 0x64, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, \ + 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, \ + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, \ + 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, \ + 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, \ + 0x82, 0x38, 0x28, 0xeb, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, \ + 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, \ + 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, \ + 0xb1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, \ + 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, \ + 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, \ + 0x5c, 0x6d, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, \ + 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, 0x5b, 0xdb, 0xc5, 0xe3, 0x9d, \ + 0x9f, 0x6d, 0x39, 0x75, 0xa1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, \ + 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, \ + 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x5d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x61, 0x6e, 0x67, \ + 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6c, 0x62, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, \ + 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x4b, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x61, 0x74, 0x61, \ + 0x5f, 0x74, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, \ + 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0xf2, 0xa8, 0x9c, 0x56, 0x9f, 0x6d, 0x50, 0x8f, 0x33, 0x72, 0xa8, 0xc6, 0x40, 0x71, 0x26, 0xf1, \ + 0x19, 0x15, 0xeb, 0x63, 0xb1, 0xad, 0x42, 0x83, 0xc9, 0x5c, 0x42, 0x29, 0x85, 0x12, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x28, 0xee, 0xf0, \ + 0x2b, 0xae, 0xaa, 0xd0, 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, 0x47, 0xf1, 0x21, 0x98, 0x13, 0xf9, \ + 0x68, 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, \ + 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, \ + 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, \ + 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, \ + 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, \ + 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, \ + 0x53, 0x20, 0x89, 0xda, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, \ + 0x38, 0x28, 0xeb, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ + 0x6c, 0x27, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, \ + 0x39, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, \ + 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, 0x5b, 0xdb, 0xc5, 0xe3, 0x9d, 0x9f, 0x6d, 0x39, 0x75, 0xf1, \ + 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, 0x28, 0xf2, 0xd8, \ + 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, 0xef, 0x03, \ + 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0xf2, 0xa0, 0x92, 0x96, \ + 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, \ + 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_bead 2794u +const dds_topic_descriptor_t DurableSupport_bead_desc = +{ + .m_size = sizeof (DurableSupport_bead), + .m_align = dds_alignof (DurableSupport_bead), + .m_flagset = DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 1u, + .m_typename = "DurableSupport::bead", + .m_keys = DurableSupport_bead_keys, + .m_nops = 35, + .m_ops = DurableSupport_bead_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_bead, .sz = TYPE_INFO_CDR_SZ_DurableSupport_bead }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_bead, .sz = TYPE_MAP_CDR_SZ_DurableSupport_bead } +}; diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 471c12ea50..d48bf8494a 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -9,36 +9,693 @@ * * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ +#include "dds/ddsi/ddsi_domaingv.h" #include "dds/durability/dds_durability.h" +#include "dds/durability/client_durability.h" +#include "dds/ddsrt/atomics.h" +#include "dds/ddsrt/string.h" +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/threads.h" +#include "dds/ddsrt/log.h" #include "ddsc/dds.h" +#include +#define TRACE(...) DDS_CLOG (DDS_LC_DUR, &domaingv->logconfig, __VA_ARGS__) -dds_return_t dds_durability_init2 (struct ddsi_domaingv* gv) +struct known_ds_t { + ddsrt_avl_node_t node; + DurableSupport_id_t id; /* id key */ + char id_str[37]; /* cached string representation of the id */ + char *hostname; /* advertised hostname */ + char *name; /* human readable name */ +}; + +static char *dc_stringify_id(const DurableSupport_id_t id, char *buf) +{ + assert(buf); + snprintf (buf, 37, "%02x%02x%02x%02x\055%02x%02x\055%02x%02x\055%02x%02x\055%02x%02x%02x%02x%02x%02x", + id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], + id[8], id[9], id[10], id[11], id[12], id[13], id[14], id[15]); + return buf; +} + +static int cmp_known_ds (const void *a, const void *b) +{ + return memcmp(a, b, 16); +} + +static void cleanup_known_ds (void *n) +{ + struct known_ds_t *known_ds = (struct known_ds_t *)n; + ddsrt_free(known_ds->hostname); + ddsrt_free(known_ds->name); + ddsrt_free(known_ds); +} + +static const ddsrt_avl_ctreedef_t known_ds_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct known_ds_t, node), offsetof (struct known_ds_t, id), cmp_known_ds, 0); + +struct com_t { + dds_entity_t participant; /* durable client participant */ + dds_entity_t status_subscriber; /* subscriber used to receive status messages */ + dds_entity_t request_publisher; /* publisher to send requests */ + dds_entity_t response_subscriber; /* subscriber used to receive response messages */ + dds_entity_t tp_status; /* status topic */ + dds_entity_t rd_status; /* status reader */ + dds_entity_t rc_status; /* status read condition */ + dds_entity_t tp_request; /* request topic */ + dds_entity_t wr_request; /* request writer */ + dds_entity_t tp_response; /* response topic */ + dds_entity_t rd_response; /* response reader */ + dds_entity_t rc_response; /* response read condition */ + dds_listener_t *status_listener; /* listener on status topic */ + dds_entity_t ws; +}; + +/* This struct contains the main durable client administration. + * This struct is initialized when an application creates the first participant, and + * deinitialized when the last participant is deleted. + * In case an application tries to create multiple participants at once (e.q., + * using different threads), we only want to initialize the durable client + * administration only once. For that purpose, we keep an atomic refcount to + * that tracks how many participants are created. + * we only want a + */ +struct dc_t { + struct { + char *request_partition; /* partition to send requests too; by default same as */ + uint32_t quorum; /*quorum of durable services needed to unblock durable writers */ + } cfg; + ddsrt_atomic_uint32_t refcount; /* refcount, increased/decreased when a participant is created/deleted */ + struct ddsi_domaingv *gv; /* reference to ddsi domain settings */ + struct com_t *com; /* ptr to durable client communication infra structure */ + bool quorum_reached; + ddsrt_thread_t recv_tid; /* receiver thread */ + ddsrt_threadattr_t recv_tattr; /* receiver thread attributes */ + ddsrt_mutex_t recv_mutex; /* recv mutex */ + ddsrt_cond_t recv_cond; /* recv condition */ + ddsrt_atomic_uint32_t termflag; /* termination flag, initialized to 0 */ + ddsrt_avl_ctree_t known_ds; /* tree containing all known ds's */ +}; + +static struct dc_t dc = { 0 }; /* static durable client structure */ + +static unsigned split_string (const char ***p_ps, char **p_bufcopy, const char *buf, const char delimiter) +{ + const char *b; + const char **ps; + char *bufcopy, *bc; + unsigned i, nps; + nps = 1; + for (b = buf; *b; b++) { + nps += (*b == delimiter); + } + ps = dds_alloc(nps * sizeof(*ps)); + bufcopy = ddsrt_strdup(buf); + i = 0; + bc = bufcopy; + while (1) { + ps[i++] = bc; + while (*bc && *bc != delimiter) bc++; + if (*bc == 0) break; + *bc++ = 0; + } + assert(i == nps); + *p_ps = ps; + *p_bufcopy = bufcopy; + return nps; +} + +#if 0 +/* callback function to update the sequence number administration of a container + * and to optionally monitor the contents of data containers */ +static void default_data_available_cb (dds_entity_t rd, void *arg) +{ +#define MAX_SAMPLES 100 + int samplecount; + static void *samples[MAX_SAMPLES]; + dds_sample_info_t info[MAX_SAMPLES]; + + (void)arg; + + samplecount = dds_read_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ALIVE_INSTANCE_STATE); + printf("LH *** samplecount = %d\n", samplecount); + if (samplecount < 0) { + printf("LH *** dds_read_mask for status reader failed: %s", dds_strretcode(-samplecount)); + goto samplecount_err; + } + for (int j = 0; j < samplecount; j++) { + DurableSupport_status *status = (DurableSupport_status *)samples[j]; + printf("LH *** recv status(): name=%s\n", status->name); + info[j].publication_handle(); + + } +samplecount_err: +#undef MAX_SAMPLES + return; +} +#endif + +static void evaluate_quorum_reached (struct dc_t *dc, const uint32_t cnt) +{ + if (dc->quorum_reached) { + if (cnt < dc->cfg.quorum) { + /* quorum changed from reached to not reached */ + dc->quorum_reached = false; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum droppped below threshold (%" PRIu32 ")\n", dc->cfg.quorum); + } + } else { + if (cnt >= dc->cfg.quorum) { + /* quorum changed from not reached to reached */ + dc->quorum_reached = true; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum threshold (%" PRIu32 ") reached\n", dc->cfg.quorum); + } + } +} + +static struct known_ds_t *create_known_ds (struct dc_t *dc, DurableSupport_id_t id, const char *name, const char *hostname) +{ + struct known_ds_t *known_ds; + char id_str[37]; /* guid */ + + assert(name); + assert(hostname); + /* the ds is not known yet by the dc, let's create it */ + if ((known_ds = (struct known_ds_t *)ddsrt_malloc(sizeof(struct known_ds_t))) == NULL) { + goto err_alloc_known_ds; + } + memcpy(known_ds->id, id, 16); + dc_stringify_id(known_ds->id, known_ds->id_str); + known_ds->name = ddsrt_strdup(name); + known_ds->hostname = ddsrt_strdup(hostname); + ddsrt_avl_cinsert(&known_ds_td, &dc->known_ds, known_ds); + return known_ds; + +err_alloc_known_ds: + DDS_ERROR("Failed to create ds for id \"%s\"\n", dc_stringify_id(id, id_str)); + return NULL; +} + +static int get_host_specific_partition_name (char *buf, size_t len) +{ + char hostname[256]; + dds_return_t ret; + int l; + + if ((len == 0) || (buf == NULL)) { + DDS_ERROR("No storage for hostname available, unable to determine the host specific partition\n"); + return -1; + } + if ((ret = ddsrt_gethostname(hostname, 256)) < 0) { + DDS_ERROR("Hostname limit of 256 exceeded, unable to determine the host specific partition [%s]\n", dds_strretcode(ret)); + return -1; + } + if ((l = snprintf(buf, len, "%s", hostname)) < 0) { + DDS_ERROR("Failed to construct the host specific partition name [%s]\n", dds_strretcode(ret)); + return -1; + } + if (len <= (size_t)l) { + DDS_ERROR("Host specific partition name '%s' too long\n", buf); + return -1; + } + return 0; +} + +/* add a participant specific partition to the configured partition for client requests */ +/* create a comma separated list consisting of the 'hostname' followed by the + * list configured by cfg->request_partition. + * The combined length may not exceed 1024 characters (including the '\0' terminator) */ +static int create_request_partition_expression (struct com_t *com, char **request_partition) +{ + char req_pname[1024] = { 0 }; + int result = 0; + + (void)com; + if ((result = get_host_specific_partition_name(req_pname, 1024)) < 0) { + DDS_ERROR("Failed to create request partition expression\n"); + return -1; + } + /* todo: perhaps add a configurable set of request partitions */ + /* set the request partition*/ + *request_partition = ddsrt_strdup(req_pname); + return 0; +} + + +/* set up durable client infrastructure */ +static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, struct ddsi_domaingv *gv) +{ + struct com_t *com; + dds_qos_t *tqos = NULL; + dds_qos_t *status_sqos = NULL, *status_rqos = NULL; + dds_qos_t *request_pqos = NULL, *request_wqos = NULL; + dds_qos_t *response_sqos = NULL, *response_rqos = NULL; + const char **ps1, **ps2; + char *bufcopy1, *bufcopy2; + unsigned nps; + dds_return_t ret; + char *request_partition = NULL; + + (void)dc; + if ((com = (struct com_t *)ddsrt_malloc(sizeof(struct com_t))) == NULL) { + DDS_ERROR("failed to allocate dc communication infrastructure\n"); + goto err_alloc_com; + } + /* create participant, subscriber and publisher for durable client support */ + if ((com->participant = dds_create_participant(domainid, NULL, NULL)) < 0) { + DDS_ERROR("failed to create dc participant [%s]\n", dds_strretcode(-com->participant)); + goto err_create_participant; + } + if ((status_sqos = dds_create_qos()) == NULL) { + DDS_ERROR("failed to create the dc status subscriber qos\n"); + goto err_alloc_status_sqos; + } + /* todo: LH make the partition used to receive status message configurable */ + nps = split_string(&ps1, &bufcopy1, "durable_support", ','); + dds_qset_partition (status_sqos, nps, ps1); + if ((com->status_subscriber = dds_create_subscriber(com->participant, status_sqos, NULL)) < 0) { + DDS_ERROR("failed to create dc status subscriber [%s]\n", dds_strretcode(-com->status_subscriber)); + goto err_status_subscriber; + } + /* create status reader */ + if ((tqos = dds_create_qos()) == NULL) { + DDS_ERROR("failed to create the dc status topic qos\n"); + goto err_alloc_tqos; + } + dds_qset_durability(tqos, DDS_DURABILITY_TRANSIENT_LOCAL); + dds_qset_reliability(tqos, DDS_RELIABILITY_RELIABLE, DDS_SECS (1)); + dds_qset_destination_order(tqos, DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP); + dds_qset_history(tqos, DDS_HISTORY_KEEP_LAST, 1); + dds_qset_ignorelocal (tqos, DDS_IGNORELOCAL_PARTICIPANT); + if ((com->tp_status = dds_create_topic (com->participant, &DurableSupport_status_desc, "ds_status", tqos, NULL)) < 0) { + DDS_ERROR("failed to create dc status topic [%s]\n", dds_strretcode(-com->tp_status)); + goto err_tp_status; + } + if ((status_rqos = dds_create_qos()) == NULL) { + DDS_ERROR("failed to create dc status reader qos\n"); + goto err_alloc_status_rqos; + } + if ((ret = dds_copy_qos(status_rqos, tqos)) < DDS_RETCODE_OK) { + DDS_ERROR("failed to copy dc status topic qos [%s]\n", dds_strretcode(-ret)); + goto err_copy_status_rqos; + } + if ((com->rd_status = dds_create_reader(com->status_subscriber, com->tp_status, status_rqos, NULL)) < 0) { + DDS_ERROR("failed to create dc status reader [%s]\n", dds_strretcode(-com->rd_status)); + goto err_rd_status; + } + if ((com->rc_status = dds_create_readcondition (com->rd_status, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE)) < 0) { + DDS_ERROR("failed to create dc status read condition [%s]\n", dds_strretcode(-com->rc_status)); + goto err_rc_status; + } + /* create dc_request writer */ + if (create_request_partition_expression(com, &request_partition) < 0) { + DDS_ERROR("failed to create dc request partition\n"); + goto err_request_partition; + } + nps = split_string(&ps2, &bufcopy2, request_partition, ','); + assert(nps > 0); + if ((request_pqos = dds_create_qos()) == NULL) { + DDS_ERROR("failed to create dc publisher qos for request topic\n"); + goto err_alloc_request_pqos; + } + dds_qset_partition (request_pqos, nps, ps2); + if ((com->request_publisher = dds_create_publisher(com->participant, request_pqos, NULL)) < 0) { + DDS_ERROR("Failed to create dc publisher for request topic [%s]\n", dds_strretcode(-com->request_publisher)); + goto err_request_publisher; + } + dds_qset_durability(tqos, DDS_DURABILITY_VOLATILE); + dds_qset_history(tqos, DDS_HISTORY_KEEP_ALL, DDS_LENGTH_UNLIMITED); + if ((com->tp_request = dds_create_topic (com->participant, &DurableSupport_request_desc, "dc_request", tqos, NULL)) < 0) { + DDS_ERROR("failed to create the dc request topic [%s]\n", dds_strretcode(-com->tp_request)); + goto err_tp_request; + } + if ((request_wqos = dds_create_qos()) == NULL) { + DDS_ERROR("failed to create dc request writer qos\n"); + goto err_alloc_request_wqos; + } + if ((ret = dds_copy_qos(request_wqos, tqos)) < DDS_RETCODE_OK) { + DDS_ERROR("failed to copy dc request topic qos [%s]\n", dds_strretcode(-ret)); + goto err_copy_request_wqos; + } + if ((com->wr_request = dds_create_writer(com->request_publisher, com->tp_request, request_wqos, NULL)) < 0) { + DDS_ERROR("failed to create dc request writer [%s]\n", dds_strretcode(-com->wr_request)); + goto err_wr_request; + } + /* create dc_response reader */ + if ((response_sqos = dds_create_qos()) == NULL) { + DDS_ERROR("failed to create the dc response subscriber qos qos\n"); + goto err_alloc_response_sqos; + } + dds_qset_partition (response_sqos, nps, ps2); + if ((com->response_subscriber = dds_create_subscriber(com->participant, response_sqos, NULL)) < 0) { + DDS_ERROR("failed to create dc response subscriber [%s]\n", dds_strretcode(-com->response_subscriber)); + goto err_response_subscriber; + } + if ((com->tp_response = dds_create_topic (com->participant, &DurableSupport_bead_desc, "dc_response", tqos, NULL)) < 0) { + DDS_ERROR("failed to create dc response topic [%s]\n", dds_strretcode(-com->tp_response)); + goto err_tp_response; + } + if ((response_rqos = dds_create_qos()) == NULL) { + DDS_ERROR("failed to create dc response reader qos\n"); + goto err_alloc_response_rqos; + } + if ((ret = dds_copy_qos(response_rqos, tqos)) < DDS_RETCODE_OK) { + DDS_ERROR("failed to copy dc response topic qos [%s]\n", dds_strretcode(-ret)); + goto err_copy_response_rqos; + } + if ((com->rd_response = dds_create_reader(com->response_subscriber, com->tp_response, response_rqos, NULL)) < 0) { + DDS_ERROR("failed to create dc response reader [%s]\n", dds_strretcode(-com->rd_response)); + goto err_rd_response; + } + if ((com->rc_response = dds_create_readcondition (com->rd_response, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE)) < 0) { + DDS_ERROR("failed to create dc response read condition [%s]\n", dds_strretcode(-com->rc_response)); + goto err_rc_response; + } + /* create waitset and attach read conditions */ + if ((com->ws = dds_create_waitset(com->participant)) < 0) { + DDS_ERROR("failed to create dc waitset [%s]\n", dds_strretcode(-com->ws)); + goto err_waitset; + } + if ((ret = dds_waitset_attach (com->ws, com->rc_status, com->rd_status)) < 0) { + DDS_ERROR("failed to attach dc status reader to waitset [%s]\n", dds_strretcode(-ret)); + goto err_attach_rd_status; + } + if ((ret = dds_waitset_attach (com->ws, com->rc_response, com->rd_response)) < 0) { + DDS_ERROR("failed to attach dc response reader to waitset [%s]\n", dds_strretcode(-ret)); + goto err_attach_rd_response; + } + if ((ret = dds_waitset_attach (com->ws, com->ws, com->ws)) < 0) { + DDS_ERROR("failed to attach waitset to itself [%s]\n", dds_strretcode(-ret)); + goto err_attach_ws; + } + DDS_CLOG(DDS_LC_DUR, &gv->logconfig, "dc infrastructure created\n"); + dds_free(request_partition); + dds_delete_qos(tqos); + dds_delete_qos(status_sqos); + dds_delete_qos(status_rqos); + dds_delete_qos(request_pqos); + dds_delete_qos(request_wqos); + dds_delete_qos(response_sqos); + dds_delete_qos(response_rqos); + dds_free(bufcopy1); + dds_free(bufcopy2); + dds_free(ps1); + dds_free(ps2); + return com; + +err_attach_ws: + dds_waitset_detach(com->ws, com->rc_response); +err_attach_rd_response: + dds_waitset_detach(com->ws, com->rc_status); +err_attach_rd_status: + dds_delete(com->ws); +err_waitset: + dds_delete(com->rc_response); +err_rc_response: + dds_delete(com->rd_response); +err_rd_response: +err_copy_response_rqos: + dds_delete_qos(response_rqos); +err_alloc_response_rqos: + dds_delete(com->tp_response); +err_tp_response: + dds_delete(com->response_subscriber); +err_response_subscriber : + dds_delete_qos(response_sqos); +err_alloc_response_sqos: + dds_delete(com->wr_request); +err_wr_request: +err_copy_request_wqos: + dds_delete_qos(request_wqos); +err_alloc_request_wqos: + dds_delete(com->tp_request); +err_tp_request: + dds_delete(com->request_publisher); +err_request_publisher: + dds_delete_qos(request_pqos); +err_alloc_request_pqos: + dds_free(request_partition); + dds_free(bufcopy2); + dds_free(ps2); +err_request_partition: + dds_delete(com->rc_status); +err_rc_status: + dds_delete(com->rd_status); +err_rd_status: +err_copy_status_rqos: + dds_delete_qos(status_rqos); +err_alloc_status_rqos: + dds_delete(com->tp_status); +err_tp_status: + dds_delete_qos(tqos); +err_alloc_tqos: + dds_delete(com->status_subscriber); +err_status_subscriber: + dds_delete_qos(status_sqos); + dds_free(bufcopy1); + dds_free(ps1); +err_alloc_status_sqos: + dds_delete(com->participant); +err_create_participant: + ddsrt_free(com); +err_alloc_com: + return NULL; +} + +static void dc_com_free (struct com_t *com) +{ + assert(com); + DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "destroying dc infrastructure\n"); + dds_delete(com->participant); + ddsrt_free(com); + dc.com = NULL; + return; +} + +static void dc_lost_ds (struct dc_t *dc, DurableSupport_status *status) +{ + struct known_ds_t *known_ds; + uint32_t total; + + /* lookup the ds entry in the list of available ds's */ + if ((known_ds = ddsrt_avl_clookup (&known_ds_td, &dc->known_ds, status->id)) == NULL) { + /* ds not known, so nothing lost */ + return; + } + ddsrt_avl_cdelete(&known_ds_td, &dc->known_ds, known_ds); + total = (uint32_t)ddsrt_avl_ccount(&dc->known_ds); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "durable service \"%s\" (%s@%s) lost (total: %" PRIu32 ")\n", known_ds->id_str, known_ds->name, known_ds->hostname, total); + cleanup_known_ds(known_ds); + /* a ds has been removed. + * we might have to reevaluate the quorum */ + evaluate_quorum_reached(dc, total); +} + +static void dc_ds_discovered (struct dc_t *dc, DurableSupport_status *status) +{ + struct known_ds_t *known_ds; + uint32_t total; + + /* lookup the ds entry in the list of available ds's */ + if ((known_ds = ddsrt_avl_clookup (&known_ds_td, &dc->known_ds, status->id)) != NULL) { + /* ds already known */ + return; + } + known_ds = create_known_ds(dc, status->id, status->name, status->hostname); + total = (uint32_t)ddsrt_avl_ccount(&dc->known_ds); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "durable service \"%s\" (%s@%s) discovered (total: %" PRIu32 ")\n", known_ds->id_str, known_ds->name, known_ds->hostname, total); + /* reevalute if the quorum has been reached */ + evaluate_quorum_reached(dc, total); +} + +static int dc_process_status (dds_entity_t rd, struct dc_t *dc) { - printf("!!!!!!!!!!!!!!!!!!! src/durability/core/src/dds_durability_init()\n"); +#define MAX_SAMPLES 100 + + static void *samples[MAX_SAMPLES]; + static dds_sample_info_t info[MAX_SAMPLES]; + int samplecount; + int j; + + samplecount = dds_take_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE); + if (samplecount < 0) { + DDS_ERROR("durable client failed to take ds_status [%s]", dds_strretcode(-samplecount)); + } else { + /* call the handler function to process the status sample */ + for (j = 0; !dds_triggered(dc->com->ws) && j < samplecount; j++) { + DurableSupport_status *status = (DurableSupport_status *)samples[j]; + if ((info[j].instance_state == DDS_IST_NOT_ALIVE_DISPOSED) || (info[j].instance_state == DDS_IST_NOT_ALIVE_NO_WRITERS)) { + /* a DS is not available any more, remove from the list of known DS's */ + dc_lost_ds(dc, status); + } else if (info[j].valid_data) { + /* a DS is available */ + + /* todo: check if the participant of the status topic contains the IDENT, + * so we are sure that this is a durable . This prevents that the client + * is fooled that a ds is present when some malicious node sends a + * status without the IDENT. However, for testing purposes we actually + * might want to fool a client. + * + * We might want to use dds_get_matched_publication_data() to retrieve the + * builtin endpoint for the writer that wrote the data, and check it's + * participant for the presence of the IDENT. */ + + dc_ds_discovered(dc, status); + } + } + } + return samplecount; +#undef MAX_SAMPLES +} + + +static uint32_t recv_handler (void *a) +{ + struct dc_t *dc = (struct dc_t *)a; + dds_duration_t timeout = DDS_INFINITY; + dds_attach_t wsresults[1]; + size_t wsresultsize = sizeof(wsresults)/sizeof(wsresults[0]); + int n; + int j; + + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "start durable client thread\n"); + while (!dds_triggered(dc->com->ws)) { + n = dds_waitset_wait_until (dc->com->ws, wsresults, wsresultsize, timeout); + if (n < 0) { + DDS_ERROR("Error in dds_waitset_wait_until [%s]\n", dds_strretcode(n)); + } else if (n > 0) { + for (j=0; j < n && (size_t)j < wsresultsize; j++) { + if (wsresults[j] == dc->com->rd_status) { + dc_process_status(dc->com->rd_status, dc); + } + } + } + } + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "stop durable client thread\n"); + return 0; +} + +dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_domaingv *gv) +{ + dds_return_t rc; + + /* a participant is created, increase the refcount. + * If this is not the first participant, then there is + * no reason to initialize the durable client */ + if (ddsrt_atomic_inc32_nv(&dc.refcount) > 1) { + return DDS_RETCODE_OK; + } + /* This is the first participant, so let's create a durable client (dc). + * The dc will also create a new participant, therefore + * increase the refcount for this participant as well. */ + ddsrt_atomic_inc32(&dc.refcount); + dc.gv = gv; + /* LH: the quorum is now initialized to 0. + * if set to 1, the transient_publisher cannot terminate if it has writers that are blocked. + * This is because the writers are only unblocked when dds_durability_fini(), + * but this function never gets called because the blocking transient_publisher application + * keeps a participant alive. */ + dc.cfg.quorum = 1; + ddsrt_avl_cinit(&known_ds_td, &dc.known_ds); + if ((dc.com = dc_com_new(&dc, domainid, gv))== NULL) { + DDS_ERROR("failed to initialize the durable client infrastructure\n"); + goto err_com_new; + } + /* start a thread to process messages coming from a ds */ + ddsrt_threadattr_init(&dc.recv_tattr); + if ((rc = ddsrt_thread_create(&dc.recv_tid, "dc", &dc.recv_tattr, recv_handler, &dc)) != DDS_RETCODE_OK) { + goto err_recv_thread; + } return DDS_RETCODE_OK; + +err_recv_thread: + dc.com = NULL; +err_com_new: + ddsrt_avl_cfree(&known_ds_td, &dc.known_ds, cleanup_known_ds); + return DDS_RETCODE_ERROR; } -dds_return_t dds_durability_fini2 (void) +/* make sure that dc terminates when the last participant is destroyed */ +dds_return_t dds_durability_fini (void) { - printf("!!!!!!!!!!!!!!!!!!! src/durability/core/src/dds_durability_fini()\n"); + dds_return_t rc; + uint32_t refcount; + + /* The durable client is deinitialized when the last participant is about + * to be removed. Note that the durable client itself also has a partition, + * so there are in fact 2 partitions (the last "real" partition, and the durable + * client partition. */ + refcount = ddsrt_atomic_dec32_nv(&dc.refcount); + if (refcount != 2) { + /* skip */ + return DDS_RETCODE_OK; + } + if (dc.com) { + /* indicate the the durable client is teminating */ + ddsrt_atomic_st32 (&dc.termflag, 1); + /* force the dc thread to terminate */ + if ((rc = dds_waitset_set_trigger(dc.com->ws, true)) < 0) { + DDS_ERROR("failed to trigger dc recv thread [%s]", dds_strretcode(rc)); + } + /* wait until the recv thread is terminated */ + if ((rc = ddsrt_thread_join(dc.recv_tid, NULL)) < 0) { + DDS_ERROR("failed to join the dc recv thread [%s]", dds_strretcode(rc)); + } + dc_com_free(dc.com); + ddsrt_avl_cfree(&known_ds_td, &dc.known_ds, cleanup_known_ds); + } return DDS_RETCODE_OK; } +bool dds_durability_is_terminating (void) +{ + return (ddsrt_atomic_ld32(&dc.termflag) > 0); +} + void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc) { /* create the administration to store transient data */ /* create a durability reader that sucks and stores it in the store */ - DDSRT_UNUSED_ARG(reader); + (void)rhc; + (void)reader; return; } -void dds_durability_wait_for_ds (uint32_t quorum, dds_time_t timeout) +/* This function checks if the writer has reached the quorum of matching durable containers + * + * It is NOT sufficient to verify if the quorum of durable services is reached. + * If a writer would unblock when the quorum of durable services is reached, then + * it is by no means certain that the durable writer has discovered the corresponding + * data containers of these durable services. Data that has is published before the + * data containers have been discovered by the writers, would not be delivered to + * the data containers. + * + * For this reason, the quorum must be calculated based on the number of discovered + * data containers for a writer. This also implies that if a writer has reached a quorum, + * some other writer may not have reached the quorum yet. + * + * return + * DDS_RETCODE_OK if quorum is reached + * DDS_PRECONDITION_NOT_MET otherwise + */ +dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer) { - (void)quorum; - (void)timeout; - return; -} +/* temporarily disabled */ +(void)writer; +#if 0 + uint32_t nds; + + if (writer == NULL) { + return DDS_RETCODE_PRECONDITION_NOT_MET; + } + /* quorum not reached if the number of discovered ds's is less than the quorum */ + if ((nds = (uint32_t)ddsrt_avl_ccount(&dc.known_ds)) < dc.cfg.quorum) { + printf("LH *** not enough ds\n"); + return DDS_RETCODE_PRECONDITION_NOT_MET; + } + /* */ +#endif + return DDS_RETCODE_OK; +} From 45a18053fece215d2c36cb2c52ea2dceb6855703 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 10 Oct 2023 11:23:52 +0200 Subject: [PATCH 176/207] Do send a nack if a gap for durable data i detected Signed-off-by: TheFixer --- src/core/ddsi/src/ddsi_receive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ddsi/src/ddsi_receive.c b/src/core/ddsi/src/ddsi_receive.c index 3bf103031f..bab118f08e 100644 --- a/src/core/ddsi/src/ddsi_receive.c +++ b/src/core/ddsi/src/ddsi_receive.c @@ -1000,7 +1000,7 @@ static int handle_AckNack (struct ddsi_receiver_state *rst, ddsrt_etime_t tnow, enqueued = 1; seq_xmit = ddsi_writer_read_seq_xmit (wr); ddsi_gap_info_init(&gi); - const bool gap_for_already_acked = ddsi_vendor_is_eclipse (rst->vendor) && prd->c.xqos->durability.kind == DDS_DURABILITY_VOLATILE && seqbase <= rn->seq; + const bool gap_for_already_acked = ddsi_vendor_is_eclipse (rst->vendor) && prd->c.xqos->durability.kind != DDS_DURABILITY_TRANSIENT_LOCAL && seqbase <= rn->seq; const ddsi_seqno_t min_seq_to_rexmit = gap_for_already_acked ? rn->seq + 1 : 0; uint32_t limit = wr->rexmit_burst_size_limit; for (uint32_t i = 0; i < numbits && seqbase + i <= seq_xmit && enqueued && limit > 0; i++) From 839ef4b433a61af4144c453ee46f03905da23e02 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 13 Oct 2023 16:26:38 +0200 Subject: [PATCH 177/207] Quorum implementation based on subscription matched for durable writers Signed-off-by: TheFixer --- src/core/ddsc/src/dds__types.h | 4 + src/core/ddsc/src/dds_write.c | 9 +- src/core/ddsc/src/dds_writer.c | 13 + .../include/dds/durability/dds_durability.h | 2 + src/durability/src/dds_durability.c | 600 +++++++++++++++--- 5 files changed, 526 insertions(+), 102 deletions(-) diff --git a/src/core/ddsc/src/dds__types.h b/src/core/ddsc/src/dds__types.h index 3c8bbfa721..9048246181 100644 --- a/src/core/ddsc/src/dds__types.h +++ b/src/core/ddsc/src/dds__types.h @@ -414,6 +414,10 @@ typedef struct dds_writer { bool whc_batch; /* FIXME: channels + latency budget */ struct dds_loan_pool *m_loans; /* administration of associated loans */ +#ifdef DDS_HAS_DURABILITY + bool quorum_reached; /* quorum reached indicator for durable writer; when false, publication of data is not permitted */ +#endif + /* Status metrics */ dds_liveliness_lost_status_t m_liveliness_lost_status; diff --git a/src/core/ddsc/src/dds_write.c b/src/core/ddsc/src/dds_write.c index 9e70d9cc89..58a21f9561 100644 --- a/src/core/ddsc/src/dds_write.c +++ b/src/core/ddsc/src/dds_write.c @@ -777,8 +777,15 @@ dds_return_t dds_write_impl (dds_writer *wr, const void *data, dds_time_t timest return DDS_RETCODE_OK; #ifdef DDS_HAS_DURABILITY + /* check if the quorum of durable services for the writer is fulfilled + * + * LH: + * todo this currently is solution to handle the case when the quorum is not yet reached. + * A better solution would be to use the max_blocking_time and use it to figure out + * if the quorum is reached within this time frame. The headbang period would then be + * used to check if the quorum is met. */ if ((ddsi_wr->xqos->durability.kind == DDS_DURABILITY_TRANSIENT) || (ddsi_wr->xqos->durability.kind == DDS_DURABILITY_PERSISTENT)) { - if ((ret = dds_durability_check_quorum_reached(wr)) != DDS_RETCODE_OK) { + if (!wr->quorum_reached) { return DDS_RETCODE_PRECONDITION_NOT_MET; } } diff --git a/src/core/ddsc/src/dds_writer.c b/src/core/ddsc/src/dds_writer.c index 96928fcb30..a4e71d864e 100644 --- a/src/core/ddsc/src/dds_writer.c +++ b/src/core/ddsc/src/dds_writer.c @@ -39,6 +39,10 @@ #include "dds__statistics.h" #include "dds__psmx.h" +#ifdef DDS_HAS_DURABILITY +#include "dds/durability/dds_durability.h" +#endif + DECL_ENTITY_LOCK_UNLOCK (dds_writer) #define DDS_WRITER_STATUS_MASK \ @@ -424,6 +428,11 @@ static dds_entity_t dds_create_writer_int (dds_entity_t participant_or_publisher if ((rc = dds_endpoint_add_psmx_endpoint (&wr->m_endpoint, wqos, &tp->m_ktopic->psmx_topics, DDS_PSMX_ENDPOINT_TYPE_WRITER)) != DDS_RETCODE_OK) goto err_pipe_open; +#if DDS_HAS_DURABILITY + /* quorum applies only to durable writers, initially quorum is not reached */ + wr->quorum_reached = (wqos->durability.kind <= DDS_DURABILITY_VOLATILE) ? true : false; +#endif + struct ddsi_sertype *sertype = ddsi_sertype_derive_sertype (tp->m_stype, data_representation, wqos->present & DDSI_QP_TYPE_CONSISTENCY_ENFORCEMENT ? wqos->type_consistency : ddsi_default_qos_topic.type_consistency); if (!sertype) @@ -461,6 +470,10 @@ static dds_entity_t dds_create_writer_int (dds_entity_t participant_or_publisher dds_topic_unpin (tp); dds_publisher_unlock (pub); +#ifdef DDS_HAS_DURABILITY + dds_durability_new_local_writer(writer); +#endif + // start async thread if not already started and the latency budget is non zero ddsrt_mutex_lock (&gv->sendq_running_lock); if (async_mode && !gv->sendq_running) { diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h index c7b8a1f5cf..af8a6ab7c0 100644 --- a/src/durability/include/dds/durability/dds_durability.h +++ b/src/durability/include/dds/durability/dds_durability.h @@ -28,9 +28,11 @@ typedef int (*plugin_finalize)(void *context); dds_return_t dds_durability_init (const dds_domainid_t domain, struct ddsi_domaingv *gv); dds_return_t dds_durability_fini (void); void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc); +dds_return_t dds_durability_new_local_writer (dds_entity_t writer); dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer); bool dds_durability_is_terminating (void); + #if defined (__cplusplus) } #endif diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index d48bf8494a..2f32307361 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -19,16 +19,13 @@ #include "dds/ddsrt/log.h" #include "ddsc/dds.h" #include +#include "dds__writer.h" -#define TRACE(...) DDS_CLOG (DDS_LC_DUR, &domaingv->logconfig, __VA_ARGS__) +#define DEFAULT_QOURUM 1 +#define DEFAULT_IDENT "durable_support" -struct known_ds_t { - ddsrt_avl_node_t node; - DurableSupport_id_t id; /* id key */ - char id_str[37]; /* cached string representation of the id */ - char *hostname; /* advertised hostname */ - char *name; /* human readable name */ -}; + +#define TRACE(...) DDS_CLOG (DDS_LC_DUR, &domaingv->logconfig, __VA_ARGS__) static char *dc_stringify_id(const DurableSupport_id_t id, char *buf) { @@ -39,20 +36,94 @@ static char *dc_stringify_id(const DurableSupport_id_t id, char *buf) return buf; } -static int cmp_known_ds (const void *a, const void *b) + +struct server_t { + ddsrt_avl_node_t node; + DurableSupport_id_t id; /* id key */ + char id_str[37]; /* cached string representation of the id */ + char *hostname; /* advertised hostname */ + char *name; /* human readable name */ +}; + +static int cmp_server (const void *a, const void *b) { return memcmp(a, b, 16); } -static void cleanup_known_ds (void *n) +static void cleanup_server (void *n) +{ + struct server_t *server = (struct server_t *)n; + ddsrt_free(server->hostname); + ddsrt_free(server->name); + ddsrt_free(server); +} + +static const ddsrt_avl_ctreedef_t server_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct server_t, node), offsetof (struct server_t, id), cmp_server, 0); + + +struct quorum_entry_key_t { + char *partition; /* the partition of the data container; should be a singleton */ + char *tpname; /* topic name */ + /* LH: todo: add a type id to support xtypes */ +}; + +struct quorum_entry_t { + ddsrt_avl_node_t node; + struct quorum_entry_key_t key; + uint32_t cnt; /* the number of data containers found for this partition/topic combination */ +}; + +static int cmp_quorum_entry (const void *a, const void *b) +{ + struct quorum_entry_key_t *qk1 = (struct quorum_entry_key_t *)a; + struct quorum_entry_key_t *qk2 = (struct quorum_entry_key_t *)b; + int cmp; + + if ((cmp = strcmp(qk1->partition, qk2->partition)) < 0) { + return -1; + } else if (cmp > 0) { + return 1; + } else if ((cmp = strcmp(qk1->tpname, qk2->tpname)) < 0) { + return -1; + } else if (cmp > 0) { + return 1; + } else { + return 0; + } +} + +static void cleanup_quorum_entry (void *n) { - struct known_ds_t *known_ds = (struct known_ds_t *)n; - ddsrt_free(known_ds->hostname); - ddsrt_free(known_ds->name); - ddsrt_free(known_ds); + struct quorum_entry_t *qe = (struct quorum_entry_t *)n; + ddsrt_free(qe->key.partition); + ddsrt_free(qe->key.tpname); + ddsrt_free(qe); } -static const ddsrt_avl_ctreedef_t known_ds_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct known_ds_t, node), offsetof (struct known_ds_t, id), cmp_known_ds, 0); +static const ddsrt_avl_ctreedef_t quorum_entry_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct quorum_entry_t, node), offsetof (struct quorum_entry_t, key), cmp_quorum_entry, 0); + +struct handle_to_quorum_entry_t { + ddsrt_avl_node_t node; + dds_instance_handle_t ih; + struct quorum_entry_t *qe_ref; /* reference to quorum entry */ +}; + +static int cmp_instance_handle (const void *a, const void *b) +{ + dds_instance_handle_t *ih1 = (dds_instance_handle_t *)a; + dds_instance_handle_t *ih2 = (dds_instance_handle_t *)b; + + return (*ih1 < *ih2) ? -1 : ((*ih1 > *ih2) ? 1 : 0); +} + +static void cleanup_handle_to_quorum_entry (void *n) +{ + struct handle_to_quorum_entry_t *hqe = (struct handle_to_quorum_entry_t *)n; + + ddsrt_free(hqe); +} + +static const ddsrt_avl_ctreedef_t handle_to_quorum_entry_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct handle_to_quorum_entry_t, node), offsetof (struct handle_to_quorum_entry_t, ih), cmp_instance_handle, 0); struct com_t { dds_entity_t participant; /* durable client participant */ @@ -67,6 +138,9 @@ struct com_t { dds_entity_t tp_response; /* response topic */ dds_entity_t rd_response; /* response reader */ dds_entity_t rc_response; /* response read condition */ + dds_entity_t rd_participant; /* participant reader */ + dds_entity_t rd_subinfo; /* DCPSSubscription reader */ + dds_entity_t rc_subinfo; /* DCPSSubscription read condition */ dds_listener_t *status_listener; /* listener on status topic */ dds_entity_t ws; }; @@ -84,6 +158,7 @@ struct dc_t { struct { char *request_partition; /* partition to send requests too; by default same as */ uint32_t quorum; /*quorum of durable services needed to unblock durable writers */ + char *ident; /* ds identification */ } cfg; ddsrt_atomic_uint32_t refcount; /* refcount, increased/decreased when a participant is created/deleted */ struct ddsi_domaingv *gv; /* reference to ddsi domain settings */ @@ -94,7 +169,11 @@ struct dc_t { ddsrt_mutex_t recv_mutex; /* recv mutex */ ddsrt_cond_t recv_cond; /* recv condition */ ddsrt_atomic_uint32_t termflag; /* termination flag, initialized to 0 */ - ddsrt_avl_ctree_t known_ds; /* tree containing all known ds's */ + ddsrt_avl_ctree_t servers; /* tree containing all discovered durable servers */ + dds_listener_t *subinfo_listener; /* listener to detect remote containers */ + dds_listener_t *quorum_listener; /* listener to check if a quorum is reached */ + ddsrt_avl_ctree_t quorum_entries; /* tree containing quora for all discovered data containers */ + ddsrt_avl_ctree_t handle_to_quorum_entries; /* tree that maps subscription handles to references to quorum entries */ }; static struct dc_t dc = { 0 }; /* static durable client structure */ @@ -155,42 +234,25 @@ static void default_data_available_cb (dds_entity_t rd, void *arg) } #endif -static void evaluate_quorum_reached (struct dc_t *dc, const uint32_t cnt) +static struct server_t *create_server (struct dc_t *dc, DurableSupport_id_t id, const char *name, const char *hostname) { - if (dc->quorum_reached) { - if (cnt < dc->cfg.quorum) { - /* quorum changed from reached to not reached */ - dc->quorum_reached = false; - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum droppped below threshold (%" PRIu32 ")\n", dc->cfg.quorum); - } - } else { - if (cnt >= dc->cfg.quorum) { - /* quorum changed from not reached to reached */ - dc->quorum_reached = true; - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum threshold (%" PRIu32 ") reached\n", dc->cfg.quorum); - } - } -} - -static struct known_ds_t *create_known_ds (struct dc_t *dc, DurableSupport_id_t id, const char *name, const char *hostname) -{ - struct known_ds_t *known_ds; + struct server_t *server; char id_str[37]; /* guid */ assert(name); assert(hostname); /* the ds is not known yet by the dc, let's create it */ - if ((known_ds = (struct known_ds_t *)ddsrt_malloc(sizeof(struct known_ds_t))) == NULL) { - goto err_alloc_known_ds; + if ((server = (struct server_t *)ddsrt_malloc(sizeof(struct server_t))) == NULL) { + goto err_alloc_server; } - memcpy(known_ds->id, id, 16); - dc_stringify_id(known_ds->id, known_ds->id_str); - known_ds->name = ddsrt_strdup(name); - known_ds->hostname = ddsrt_strdup(hostname); - ddsrt_avl_cinsert(&known_ds_td, &dc->known_ds, known_ds); - return known_ds; + memcpy(server->id, id, 16); + dc_stringify_id(server->id, server->id_str); + server->name = ddsrt_strdup(name); + server->hostname = ddsrt_strdup(hostname); + ddsrt_avl_cinsert(&server_td, &dc->servers, server); + return server; -err_alloc_known_ds: +err_alloc_server: DDS_ERROR("Failed to create ds for id \"%s\"\n", dc_stringify_id(id, id_str)); return NULL; } @@ -370,6 +432,20 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc response read condition [%s]\n", dds_strretcode(-com->rc_response)); goto err_rc_response; } + /* create participant reader (to discover participants of remote durable services) */ + if ((com->rd_participant = dds_create_reader(com->participant, DDS_BUILTIN_TOPIC_DCPSPARTICIPANT, NULL, NULL)) < 0) { + DDS_ERROR("failed to create dc participant reader [%s]\n", dds_strretcode(-com->rd_participant)); + goto err_rd_participant; + } + /* subinfo reader and listener to detect remote data containers */ + if ((com->rd_subinfo = dds_create_reader(com->participant, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL)) < 0) { + DDS_ERROR("failed to create dc subinfo reader [%s]\n", dds_strretcode(-com->rd_subinfo)); + goto err_rd_subinfo; + } + if ((com->rc_subinfo = dds_create_readcondition(com->rd_subinfo, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE)) < 0) { + DDS_ERROR("failed to create dc subinfo read condition [%s]\n", dds_strretcode(-com->rc_subinfo)); + goto err_rc_subinfo; + } /* create waitset and attach read conditions */ if ((com->ws = dds_create_waitset(com->participant)) < 0) { DDS_ERROR("failed to create dc waitset [%s]\n", dds_strretcode(-com->ws)); @@ -409,6 +485,12 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, err_attach_rd_status: dds_delete(com->ws); err_waitset: + dds_delete(com->rc_subinfo); +err_rc_subinfo: + dds_delete(com->rd_subinfo); +err_rd_subinfo: + dds_delete(com->rd_participant); +err_rd_participant: dds_delete(com->rc_response); err_rc_response: dds_delete(com->rd_response); @@ -471,40 +553,35 @@ static void dc_com_free (struct com_t *com) return; } -static void dc_lost_ds (struct dc_t *dc, DurableSupport_status *status) +static void dc_server_lost (struct dc_t *dc, DurableSupport_status *status) { - struct known_ds_t *known_ds; + struct server_t *server; uint32_t total; /* lookup the ds entry in the list of available ds's */ - if ((known_ds = ddsrt_avl_clookup (&known_ds_td, &dc->known_ds, status->id)) == NULL) { + if ((server = ddsrt_avl_clookup (&server_td, &dc->servers, status->id)) == NULL) { /* ds not known, so nothing lost */ return; } - ddsrt_avl_cdelete(&known_ds_td, &dc->known_ds, known_ds); - total = (uint32_t)ddsrt_avl_ccount(&dc->known_ds); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "durable service \"%s\" (%s@%s) lost (total: %" PRIu32 ")\n", known_ds->id_str, known_ds->name, known_ds->hostname, total); - cleanup_known_ds(known_ds); - /* a ds has been removed. - * we might have to reevaluate the quorum */ - evaluate_quorum_reached(dc, total); + ddsrt_avl_cdelete(&server_td, &dc->servers, server); + total = (uint32_t)ddsrt_avl_ccount(&dc->servers); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "durable service \"%s\" (%s@%s) lost (total: %" PRIu32 ")\n", server->id_str, server->name, server->hostname, total); + cleanup_server(server); } -static void dc_ds_discovered (struct dc_t *dc, DurableSupport_status *status) +static void dc_server_discovered (struct dc_t *dc, DurableSupport_status *status) { - struct known_ds_t *known_ds; + struct server_t *server; uint32_t total; /* lookup the ds entry in the list of available ds's */ - if ((known_ds = ddsrt_avl_clookup (&known_ds_td, &dc->known_ds, status->id)) != NULL) { + if ((server = ddsrt_avl_clookup (&server_td, &dc->servers, status->id)) != NULL) { /* ds already known */ return; } - known_ds = create_known_ds(dc, status->id, status->name, status->hostname); - total = (uint32_t)ddsrt_avl_ccount(&dc->known_ds); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "durable service \"%s\" (%s@%s) discovered (total: %" PRIu32 ")\n", known_ds->id_str, known_ds->name, known_ds->hostname, total); - /* reevalute if the quorum has been reached */ - evaluate_quorum_reached(dc, total); + server = create_server(dc, status->id, status->name, status->hostname); + total = (uint32_t)ddsrt_avl_ccount(&dc->servers); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "durable service \"%s\" (%s@%s) discovered (total: %" PRIu32 ")\n", server->id_str, server->name, server->hostname, total); } static int dc_process_status (dds_entity_t rd, struct dc_t *dc) @@ -525,21 +602,15 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) DurableSupport_status *status = (DurableSupport_status *)samples[j]; if ((info[j].instance_state == DDS_IST_NOT_ALIVE_DISPOSED) || (info[j].instance_state == DDS_IST_NOT_ALIVE_NO_WRITERS)) { /* a DS is not available any more, remove from the list of known DS's */ - dc_lost_ds(dc, status); + dc_server_lost(dc, status); } else if (info[j].valid_data) { - /* a DS is available */ - - /* todo: check if the participant of the status topic contains the IDENT, - * so we are sure that this is a durable . This prevents that the client - * is fooled that a ds is present when some malicious node sends a - * status without the IDENT. However, for testing purposes we actually - * might want to fool a client. - * - * We might want to use dds_get_matched_publication_data() to retrieve the - * builtin endpoint for the writer that wrote the data, and check it's - * participant for the presence of the IDENT. */ - - dc_ds_discovered(dc, status); + /* To avoid reacting to malicious status messages we want to verify if + * the status message originates from a "real" DS by verifying if its participant + * contains the IDENT in the user data. To do this we actually need to retrieve + * the builtin endpoint that represents the status writer that published this + * status, and check if the participant of this writer has the IDENT in its + * userdata. For now, we skip this check. */ + dc_server_discovered(dc, status); } } } @@ -547,6 +618,270 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } +/* verifies if the user data of the endpoint contains the identifier + * that indicates that this endpoint is a durable container */ +static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *ep, const char *ident) +{ + dds_builtintopic_endpoint_t template; + dds_builtintopic_participant_t *participant; + dds_instance_handle_t ih; + dds_return_t rc; + static void *samples[1]; + static dds_sample_info_t info[1]; + void *userdata; + size_t size = 0; + char id_str[37]; + bool result = false; + + assert(ep); + /* by convention, if the ident == NULL then return true */ + if (ident == NULL) { + return true; + } + /* lookup the instance handle of the builtin participant endpoint that + * contains the participant of the subinfo */ + memcpy(template.key.v,ep->participant_key.v,16); + if ((ih = dds_lookup_instance(com->rd_participant, &template)) == DDS_HANDLE_NIL) { + DDS_ERROR("Failed to lookup the participant of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); + goto err_lookup_instance; + } + if ((rc = dds_read_instance(com->rd_participant, samples, info, 1, 1, ih)) <= 0) { + DDS_ERROR("Failed to read the participant of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); + goto err_read_instance; + } + if (info[0].valid_data) { + participant = (dds_builtintopic_participant_t *)samples[0]; + /* get the user data */ + if (!dds_qget_userdata(participant->qos, &userdata, &size)) { + DDS_ERROR("Unable to retrieve the user data of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); + goto err_qget_userdata; + } + if ((size != strlen(ident)) || (userdata == NULL) || (strcmp(userdata, ident) != 0)) { + /* the user data of the participant of the durable reader does not contain the ident, + * so the endoint is not from a remote DS */ + result = false; + } else { + /* this endpoint's participant is a ds */ + result = true; + } + dds_free(userdata); + } + return result; + +err_lookup_instance: +err_read_instance: +err_qget_userdata: + return false; +} + +static void dc_free_partitions (uint32_t plen, char **partitions) +{ + uint32_t i; + + if (partitions == NULL) { + return; + } + for (i=0; i < plen; i++) { + ddsrt_free(partitions[i]); + } + ddsrt_free(partitions); +} + + +static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer) +{ + dds_qos_t *qos; + dds_writer *wr; + dds_return_t rc; + uint32_t plen, i; + char **partitions; + struct quorum_entry_key_t key; + struct quorum_entry_t *qe; + bool quorum_reached = true; + + assert(writer); + assert(dc); + + qos = dds_create_qos(); + if ((rc = dds_get_qos(writer, qos)) < 0) { + DDS_ERROR("failed to get qos from writer [%s]", dds_strretcode(rc)); + goto err_get_qos; + } + if (!dds_qget_partition(qos, &plen, &partitions)) { + DDS_ERROR("failed to get partitions from qos\n"); + goto err_qget_partition; + } + assert(plen > 0); + if ((rc = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) { + DDS_ERROR("failed to lock writer\n"); + goto err_writer_lock; + } + key.tpname = ddsrt_strdup(wr->m_topic->m_name); + /* nothing to do if quorum was already reached */ + if (!wr->quorum_reached) { + for (i=0; i < plen && quorum_reached; i++) { + /* lookup the quorum entry and if a quorum has reached for all relevant data containers */ + key.partition = ddsrt_strdup(partitions[i]); + if ((qe = ddsrt_avl_clookup (&quorum_entry_td, &dc->quorum_entries, &key)) == NULL) { + quorum_reached = false; + } else { + quorum_reached = (qe->cnt >= dc->cfg.quorum); + } + ddsrt_free(key.partition); + } + wr->quorum_reached = quorum_reached; + } + ddsrt_free(key.tpname); + dds_writer_unlock (wr); +err_writer_lock: + dc_free_partitions(plen, partitions); +err_qget_partition: +err_get_qos: + dds_delete_qos(qos); + return; +} + +/* get a quorum counter for the builtin endoint and create a quorum counter for the endpoint */ +static struct quorum_entry_t *dc_get_or_create_quorum_entry (struct dc_t *dc, dds_builtintopic_endpoint_t *ep) +{ + struct quorum_entry_t *qe; + struct quorum_entry_key_t key; + uint32_t plen; + char **partitions; + + if (!dds_qget_partition(ep->qos, &plen, &partitions)) { + DDS_ERROR("failed to get partitions from qos\n"); + goto err_qget_partition; + } + assert(plen == 1); + key.tpname = ddsrt_strdup(ep->topic_name); + key.partition = ddsrt_strdup(partitions[0]); + if ((qe = ddsrt_avl_clookup (&quorum_entry_td, &dc->quorum_entries, &key)) == NULL) { + /* create quorum entry */ + if ((qe = (struct quorum_entry_t *)ddsrt_malloc(sizeof(struct quorum_entry_t))) == NULL) { + DDS_ERROR("failed to allocate quorum entry\n"); + goto err_alloc_quorum_entry; + } + qe->key.partition = ddsrt_strdup(key.partition); + qe->key.tpname = ddsrt_strdup(key.tpname); + qe->cnt = 0; + ddsrt_avl_cinsert(&quorum_entry_td, &dc->quorum_entries, qe); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum entry for \"%s.%s\" created\n", qe->key.partition, qe->key.tpname); + } + ddsrt_free(key.tpname); + ddsrt_free(key.partition); + dc_free_partitions(plen, partitions); + return qe; + +err_alloc_quorum_entry: + ddsrt_free(key.tpname); + ddsrt_free(key.partition); + dc_free_partitions(plen, partitions); +err_qget_partition: + return NULL; +} + +static struct quorum_entry_t *dc_link_handle_to_quorum_entry (struct dc_t *dc, dds_instance_handle_t ih, struct quorum_entry_t *qe) +{ + struct handle_to_quorum_entry_t *hqe; + + assert(qe); + /* link the handle to the quorum entry, so we can lookup the + * quorum entry if the data container identified by the handle + * disappears */ + if ((hqe = (struct handle_to_quorum_entry_t *)ddsrt_malloc(sizeof(struct handle_to_quorum_entry_t))) == NULL) { + DDS_ERROR("failed to allocate handle_to_quorum_entry_t\n"); + goto err_alloc_hqe; + } + hqe->ih = ih; + hqe->qe_ref = qe; + ddsrt_avl_cinsert(&handle_to_quorum_entry_td, &dc->handle_to_quorum_entries, hqe); + qe->cnt++; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for \"%s.%s\" bumped to %" PRIu32 " (ih %" PRIx64 ")\n", qe->key.partition, qe->key.tpname, qe->cnt, ih); + return qe; + +err_alloc_hqe: + return NULL; +} + +/* Update the quorum entry when a data container leaves. + * Returns a reference to the quorum entry as long as there are still containers, or NULL otherwise */ +static struct quorum_entry_t *dc_unlink_handle_to_quorum_entry (struct dc_t *dc, dds_instance_handle_t ih) +{ + struct handle_to_quorum_entry_t *hqe; + struct quorum_entry_t *qe = NULL; + ddsrt_avl_dpath_t dpath_hqe, dpath_qe; + + /* look up the quorum entry via the instance handle */ + if ((hqe = ddsrt_avl_clookup_dpath (&handle_to_quorum_entry_td, &dc->handle_to_quorum_entries, &ih, &dpath_hqe)) != NULL) { + qe = hqe->qe_ref; + assert(qe); + assert(qe->cnt > 0); + qe->cnt--; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for \"%s.%s\" decreased to %" PRIu32 " (ih %" PRIx64 ")\n", qe->key.partition, qe->key.tpname, qe->cnt, ih); + if (qe->cnt == 0) { + /* by unlinking this subscription info, the last reference to the quorum entry is now gone. + * We can now garbage collect the quorum entry itself. */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum entry for \"%s.%s\" deleted\n", qe->key.partition, qe->key.tpname); + if (ddsrt_avl_clookup_dpath(&quorum_entry_td, &dc->quorum_entries, &qe->key, &dpath_qe)) { + ddsrt_avl_cdelete_dpath(&quorum_entry_td, &dc->quorum_entries, qe, &dpath_qe); + cleanup_quorum_entry(qe); + qe = NULL; + } + } + ddsrt_avl_cdelete_dpath(&handle_to_quorum_entry_td, &dc->handle_to_quorum_entries, hqe, &dpath_hqe); + cleanup_handle_to_quorum_entry(hqe); + } + return qe; +} + +/* called when there is a match for a durable writer */ +static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publication_matched_status_t status, void *arg) +{ + struct dc_t *dc = (struct dc_t *)arg; + dds_instance_handle_t ih; + dds_builtintopic_endpoint_t *ep; + struct quorum_entry_t *qe; + + /* a reader has matched with a durable writer. */ + /* check if the reader is a data container. + * If so, this might affect the quorum */ + assert(writer); + if ((ih = status.last_subscription_handle) == DDS_HANDLE_NIL) { + DDS_ERROR("failed to receive valid last_subscription_handle\n"); + goto err_last_subscription_handle; + } + if ((ep = dds_get_matched_subscription_data(writer, ih)) != NULL) { + if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { + /* a data container has matched with this writer. + * Increase the quorum counter for this container. + * If no quorum counter existed, then create one. + * Also link the subscription handle to the quorum counter, + * so that we can decrease the quorum counter in case the + * data container does not exist. */ + if ((qe = dc_get_or_create_quorum_entry(dc, ep)) == NULL) { + goto err_inc_or_create_quorum_entry; + } + dc_link_handle_to_quorum_entry(dc, ih, qe); + /* a relevant data container from a durable service for this writer has become available. + * Reevaluate if the quorum has been reached */ + dc_check_quorum_reached(dc, writer); + } + dds_builtintopic_free_endpoint(ep); + } else { + /* the endpoint that represents a data container is not available any more. + * decrease the quorum counter for the data container associated with + * the handle. If the quorum counter reaches 0, we'll garbage collect + * the quorum counter entry. */ + qe = dc_unlink_handle_to_quorum_entry(dc, ih); + /* a data container from a durable service has been lost. + * reevaluate if the quorum still holds */ + dc_check_quorum_reached(dc, writer); + } + err_inc_or_create_quorum_entry: +err_last_subscription_handle: + return; +} static uint32_t recv_handler (void *a) { @@ -554,9 +889,23 @@ static uint32_t recv_handler (void *a) dds_duration_t timeout = DDS_INFINITY; dds_attach_t wsresults[1]; size_t wsresultsize = sizeof(wsresults)/sizeof(wsresults[0]); - int n; - int j; + int n, j; + dds_return_t rc; + if ((dc->quorum_listener = dds_create_listener(dc)) == NULL) { + DDS_ERROR("failed to create quorum listener\n"); + goto err_create_quorum_listener; + } + dds_lset_publication_matched(dc->quorum_listener, default_durable_writer_matched_cb); + if ((dc->subinfo_listener = dds_create_listener(dc)) == NULL) { + DDS_ERROR("failed to create subinfo listener\n"); + goto err_create_subinfo_listener; + } + // dds_lset_data_available(dc->subinfo_listener, default_evaluate_quorum_cb); + if ((rc = dds_set_listener(dc->com->rd_subinfo, dc->subinfo_listener)) < 0) { + DDS_ERROR("Unable to set the subinfo listener\n"); + goto err_set_listener; + } DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "start durable client thread\n"); while (!dds_triggered(dc->com->ws)) { n = dds_waitset_wait_until (dc->com->ws, wsresults, wsresultsize, timeout); @@ -570,8 +919,19 @@ static uint32_t recv_handler (void *a) } } } + dds_delete_listener(dc->subinfo_listener); + dc->subinfo_listener = NULL; + dds_delete_listener(dc->quorum_listener); + dc->quorum_listener = NULL; DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "stop durable client thread\n"); return 0; + +err_set_listener: + dds_delete_listener(dc->subinfo_listener); +err_create_subinfo_listener: + dds_delete_listener(dc->quorum_listener); +err_create_quorum_listener: + return 1; } dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_domaingv *gv) @@ -589,13 +949,11 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom * increase the refcount for this participant as well. */ ddsrt_atomic_inc32(&dc.refcount); dc.gv = gv; - /* LH: the quorum is now initialized to 0. - * if set to 1, the transient_publisher cannot terminate if it has writers that are blocked. - * This is because the writers are only unblocked when dds_durability_fini(), - * but this function never gets called because the blocking transient_publisher application - * keeps a participant alive. */ - dc.cfg.quorum = 1; - ddsrt_avl_cinit(&known_ds_td, &dc.known_ds); + dc.cfg.quorum = DEFAULT_QOURUM; /* LH: currently hardcoded set to 1, should be made configurable in future */ + dc.cfg.ident = ddsrt_strdup(DEFAULT_IDENT); + ddsrt_avl_cinit(&server_td, &dc.servers); + ddsrt_avl_cinit(&quorum_entry_td, &dc.quorum_entries); + ddsrt_avl_cinit(&handle_to_quorum_entry_td, &dc.handle_to_quorum_entries); if ((dc.com = dc_com_new(&dc, domainid, gv))== NULL) { DDS_ERROR("failed to initialize the durable client infrastructure\n"); goto err_com_new; @@ -608,9 +966,10 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom return DDS_RETCODE_OK; err_recv_thread: - dc.com = NULL; + dc_com_free(dc.com); err_com_new: - ddsrt_avl_cfree(&known_ds_td, &dc.known_ds, cleanup_known_ds); + ddsrt_avl_cfree(&quorum_entry_td, &dc.quorum_entries, cleanup_quorum_entry); + ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); return DDS_RETCODE_ERROR; } @@ -641,8 +1000,11 @@ dds_return_t dds_durability_fini (void) DDS_ERROR("failed to join the dc recv thread [%s]", dds_strretcode(rc)); } dc_com_free(dc.com); - ddsrt_avl_cfree(&known_ds_td, &dc.known_ds, cleanup_known_ds); + ddsrt_avl_cfree(&handle_to_quorum_entry_td, &dc.handle_to_quorum_entries, cleanup_handle_to_quorum_entry); + ddsrt_avl_cfree(&quorum_entry_td, &dc.quorum_entries, cleanup_quorum_entry); + ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); } + ddsrt_free(dc.cfg.ident); return DDS_RETCODE_OK; } @@ -680,22 +1042,58 @@ void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc */ dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer) { -/* temporarily disabled */ -(void)writer; -#if 0 - uint32_t nds; + /* temporarily disabled */ + (void)writer; + return DDS_RETCODE_OK; +} +dds_return_t dds_durability_new_local_writer (dds_entity_t writer) +{ + dds_durability_kind_t dkind; + dds_qos_t *qos; + dds_return_t rc = DDS_RETCODE_ERROR; + dds_guid_t wguid; + char id_str[37]; - if (writer == NULL) { - return DDS_RETCODE_PRECONDITION_NOT_MET; + /* check if the writer is a durable writer, and if so, we need to keep track of the quorum */ + assert(writer); + qos = dds_create_qos(); + if ((rc = dds_get_qos(writer, qos)) < 0) { + DDS_ERROR("failed to get qos from writer [%s]", dds_strretcode(rc)); + goto err_get_qos; } - /* quorum not reached if the number of discovered ds's is less than the quorum */ - if ((nds = (uint32_t)ddsrt_avl_ccount(&dc.known_ds)) < dc.cfg.quorum) { - printf("LH *** not enough ds\n"); - return DDS_RETCODE_PRECONDITION_NOT_MET; + if (!dds_qget_durability(qos, &dkind)) { + DDS_ERROR("failed to retrieve durability qos"); + goto err_qget_durability; } - /* */ -#endif - + if ((dkind == DDS_DURABILITY_TRANSIENT) || (dkind == DDS_DURABILITY_PERSISTENT)) { + assert(dc.quorum_listener); + /* The writer is durable, so subjected to reaching a quorum before + * it can start publishing. We set a publication_matched listener on + * the writer. Each time a matching durable data container is discovered + * the listener will be triggered, causing relevant quora to be updated + * accordingly. + * + * Note that setting a publication_matched listener implies that we do NOT + * allow that user application can set a listener on durable writers. + * This is currently a limitation. */ + if ((rc = dds_get_guid(writer, &wguid)) != DDS_RETCODE_OK) { + DDS_ERROR("failed to retrieve writer guid"); + goto err_get_guid; + } + DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "durable writer \"%s\" subject to quorum checking\n", dc_stringify_id(wguid.v, id_str)); + if ((rc = dds_set_listener(writer, dc.quorum_listener)) < 0) { + DDS_ERROR("Unable to set the quorum listener on writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); + goto err_set_listener; + } + } + dds_delete_qos(qos); return DDS_RETCODE_OK; + +err_set_listener: +err_get_guid: +err_qget_durability: +err_get_qos: + dds_delete_qos(qos); + return rc; } From 0297892d7e02da92157a2e0200bea3bc5c7fb7a9 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Mon, 16 Oct 2023 12:04:03 +0200 Subject: [PATCH 178/207] quorum checking for durable writers Signed-off-by: TheFixer --- src/core/ddsc/src/dds_write.c | 14 ++ src/core/ddsc/src/dds_writer.c | 2 +- .../include/dds/durability/dds_durability.h | 3 + src/durability/src/dds_durability.c | 173 +++++++++++++++++- 4 files changed, 183 insertions(+), 9 deletions(-) diff --git a/src/core/ddsc/src/dds_write.c b/src/core/ddsc/src/dds_write.c index 58a21f9561..1b8e3d33fc 100644 --- a/src/core/ddsc/src/dds_write.c +++ b/src/core/ddsc/src/dds_write.c @@ -46,6 +46,19 @@ dds_return_t dds_write (dds_entity_t writer, const void *data) if (data == NULL) return DDS_RETCODE_BAD_PARAMETER; +#ifdef DDS_HAS_DURABILITY + /* determine if the quorum of durable services for the writer is fulfilled. + * + * LH: This implementation may be suboptimal, because determining whether the + * quorum is fulfilled, and the actual publication of the data is not done + * within the same writer lock. So after the quorum has been established, + * and before the data is published, the quorum could have been dropped. + * Chances for this to happen are slim, but still ... */ + if ((ret = dds_durability_wait_for_quorum(writer)) != DDS_RETCODE_OK) { + return ret; + } +#endif + if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) return ret; ret = dds_write_impl (wr, data, dds_time (), 0); @@ -822,6 +835,7 @@ dds_return_t dds_write_impl (dds_writer *wr, const void *data, dds_time_t timest // - deliver serdata // c. no psmx // - ddsi_serdata_from_sample, deliver serdata + ddsi_thread_state_awake (thrst, &wr->m_entity.m_domain->gv); struct ddsi_serdata *serdata; struct dds_loaned_sample *psmx_loan; diff --git a/src/core/ddsc/src/dds_writer.c b/src/core/ddsc/src/dds_writer.c index a4e71d864e..6336bfa166 100644 --- a/src/core/ddsc/src/dds_writer.c +++ b/src/core/ddsc/src/dds_writer.c @@ -430,7 +430,7 @@ static dds_entity_t dds_create_writer_int (dds_entity_t participant_or_publisher #if DDS_HAS_DURABILITY /* quorum applies only to durable writers, initially quorum is not reached */ - wr->quorum_reached = (wqos->durability.kind <= DDS_DURABILITY_VOLATILE) ? true : false; + wr->quorum_reached = (wqos->durability.kind <= DDS_DURABILITY_TRANSIENT_LOCAL) ? true : false; #endif struct ddsi_sertype *sertype = ddsi_sertype_derive_sertype (tp->m_stype, data_representation, diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h index af8a6ab7c0..1db1572ac3 100644 --- a/src/durability/include/dds/durability/dds_durability.h +++ b/src/durability/include/dds/durability/dds_durability.h @@ -29,7 +29,10 @@ dds_return_t dds_durability_init (const dds_domainid_t domain, struct ddsi_domai dds_return_t dds_durability_fini (void); void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc); dds_return_t dds_durability_new_local_writer (dds_entity_t writer); +dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer); + dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer); + bool dds_durability_is_terminating (void); diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 2f32307361..d5fe416e65 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -20,6 +20,7 @@ #include "ddsc/dds.h" #include #include "dds__writer.h" +#include "dds/ddsi/ddsi_endpoint.h" #define DEFAULT_QOURUM 1 #define DEFAULT_IDENT "durable_support" @@ -296,7 +297,7 @@ static int create_request_partition_expression (struct com_t *com, char **reques DDS_ERROR("Failed to create request partition expression\n"); return -1; } - /* todo: perhaps add a configurable set of request partitions */ + /* todo: LH perhaps add a configurable set of request partitions */ /* set the request partition*/ *request_partition = ddsrt_strdup(req_pname); return 0; @@ -687,8 +688,35 @@ static void dc_free_partitions (uint32_t plen, char **partitions) ddsrt_free(partitions); } +static ddsi_guid_prefix_t dc_ddsi_hton_guid_prefix (ddsi_guid_prefix_t p) +{ + int i; + for (i = 0; i < 3; i++) + p.u[i] = ddsrt_toBE4u (p.u[i]); + return p; +} + +static ddsi_entityid_t dc_ddsi_hton_entityid (ddsi_entityid_t e) +{ + e.u = ddsrt_toBE4u (e.u); + return e; +} + +static ddsi_guid_t dc_ddsi_hton_guid (ddsi_guid_t g) +{ + g.prefix = dc_ddsi_hton_guid_prefix (g.prefix); + g.entityid = dc_ddsi_hton_entityid (g.entityid); + return g; +} + +static void dc_ddsiguid2guid (dds_guid_t *dds_guid, const ddsi_guid_t *ddsi_guid) +{ + ddsi_guid_t tmp; + tmp = dc_ddsi_hton_guid (*ddsi_guid); + memcpy (dds_guid, &tmp, sizeof (*dds_guid)); +} -static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer) +static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer, bool new_qe) { dds_qos_t *qos; dds_writer *wr; @@ -717,10 +745,12 @@ static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer) goto err_writer_lock; } key.tpname = ddsrt_strdup(wr->m_topic->m_name); - /* nothing to do if quorum was already reached */ - if (!wr->quorum_reached) { + if (((!wr->quorum_reached) && (new_qe)) || ((wr->quorum_reached) && (!new_qe))) { + /* the quorum was not reached and a new quorum entry has been found, or + * the quorum was reached and a quorum entry has been lost + * In both cases check if the quorum still holds */ for (i=0; i < plen && quorum_reached; i++) { - /* lookup the quorum entry and if a quorum has reached for all relevant data containers */ + /* lookup the quorum entry, and determine if a quorum has reached for all relevant data containers */ key.partition = ddsrt_strdup(partitions[i]); if ((qe = ddsrt_avl_clookup (&quorum_entry_td, &dc->quorum_entries, &key)) == NULL) { quorum_reached = false; @@ -729,7 +759,14 @@ static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer) } ddsrt_free(key.partition); } - wr->quorum_reached = quorum_reached; + if (wr->quorum_reached != quorum_reached) { + dds_guid_t guid; + char id_str[37]; + + wr->quorum_reached = quorum_reached; + dc_ddsiguid2guid(&guid, &wr->m_entity.m_guid); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for writer \"%s\" %s\n", dc_stringify_id(guid.v, id_str), quorum_reached ? "reached" : "lost"); + } } ddsrt_free(key.tpname); dds_writer_unlock (wr); @@ -741,6 +778,8 @@ static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer) return; } + + /* get a quorum counter for the builtin endoint and create a quorum counter for the endpoint */ static struct quorum_entry_t *dc_get_or_create_quorum_entry (struct dc_t *dc, dds_builtintopic_endpoint_t *ep) { @@ -865,7 +904,7 @@ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publicat dc_link_handle_to_quorum_entry(dc, ih, qe); /* a relevant data container from a durable service for this writer has become available. * Reevaluate if the quorum has been reached */ - dc_check_quorum_reached(dc, writer); + dc_check_quorum_reached(dc, writer, true); } dds_builtintopic_free_endpoint(ep); } else { @@ -876,7 +915,7 @@ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publicat qe = dc_unlink_handle_to_quorum_entry(dc, ih); /* a data container from a durable service has been lost. * reevaluate if the quorum still holds */ - dc_check_quorum_reached(dc, writer); + dc_check_quorum_reached(dc, writer, false); } err_inc_or_create_quorum_entry: err_last_subscription_handle: @@ -1097,3 +1136,121 @@ dds_return_t dds_durability_new_local_writer (dds_entity_t writer) dds_delete_qos(qos); return rc; } + +#if 0 +dds_return_t dds_durability_wait_for_quorum (dds_writer *wr) +{ + dds_return_t ret = DDS_RETCODE_ERROR; + ddsrt_mtime_t tnow = ddsrt_time_monotonic (); + ddsrt_mtime_t timeout; + dds_duration_t sleep_duration; + dds_entity_t writer; + + /* This function is called from dds_write() while the writer lock is held. + * To make sure that we temporarily release the writer lock + * while we wait until the quorum has been reached, we need access + * to the entity handle in order to acquire the lock each time + * we recheck.*/ + writer = (dds_entity_t)wr->m_entity.m_hdllink.hdl; + /* No need to check for quorum for non-durable writers */ + if (wr->m_wr->xqos->durability.kind <= DDS_DURABILITY_TRANSIENT_LOCAL) { + ret = DDS_RETCODE_OK; + goto done; + } + timeout = ddsrt_mtime_add_duration (tnow, wr->m_wr->xqos->reliability.max_blocking_time); + /* If the quorum is reached we'll immediately return DDS_RETCODE_OK. + * Note that for volatile and transient-local writers the quorum + * is but definition reached, so this function will always return with + * DDS_RETCODE_OK in those case. */ + if (wr->quorum_reached) { + ret = DDS_RETCODE_OK; + goto done; + } + /* The quorum for a durable writer is not reached. + * We will head bang until the quorum is reached. + * To prevent starvation we use a max 10ms sleep in between. + * If the quorum is reached within the max_blocking_time, + * DDS_RETCODE_OK is returned, otherwise DDS_PRECONDITION_NOT_MET + * is returned. */ + do { + sleep_duration = DDS_MSECS(10); + dds_writer_unlock(wr); + dds_sleepfor (sleep_duration); + if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) { + goto err_writer_lock; + } + tnow = ddsrt_time_monotonic (); + if (tnow.v >= timeout.v) { + ret = DDS_RETCODE_PRECONDITION_NOT_MET; + break; + } + if (wr->quorum_reached) { + ret = DDS_RETCODE_OK; + break; + } + } while (true); +done: + dds_writer_unlock(wr); +err_writer_lock: + return ret; +} +#endif + +/* Retrieve the quorum_reached value from the dds_writer that corresponds to the writer entity */ +static dds_return_t dds_durability_get_quorum_reached (dds_entity_t writer, bool *quorum_reached, ddsrt_mtime_t *timeout) +{ + dds_return_t ret = DDS_RETCODE_OK; + dds_writer *wr; + ddsrt_mtime_t tnow; + + *quorum_reached = false; + if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) { + goto err_writer_lock; + } + /* determine the timeout lazily */ + if (timeout->v == DDS_TIME_INVALID) { + tnow = ddsrt_time_monotonic (); + *timeout = ddsrt_mtime_add_duration (tnow,wr->m_wr->xqos->reliability.max_blocking_time); + } + /* retrieve quorum reached */ + *quorum_reached = wr->quorum_reached; + dds_writer_unlock(wr); +err_writer_lock: + return ret; +} + +dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) +{ + dds_return_t ret = DDS_RETCODE_ERROR; + ddsrt_mtime_t tnow = ddsrt_time_monotonic (); + ddsrt_mtime_t timeout; + dds_duration_t tdur; + bool quorum_reached; + + /* Check if the quorum for a durable writer is reached. + * If not, we will head bang until the quorum is reached. + * To prevent starvation we use a 10ms sleep in between. + * When the quorum is reached within the max_blocking_time, + * DDS_RETCODE_OK is returned, otherwise DDS_PRECONDITION_NOT_MET + * is returned. The max_blocking_time itself is retrieved lazily + * on the first call to dds_durability_get_quorum_reached(). */ + timeout.v = DDS_TIME_INVALID; + do { + if ((ret = dds_durability_get_quorum_reached(writer, &quorum_reached, &timeout)) != DDS_RETCODE_OK) { + break; + } + if (quorum_reached) { + ret = DDS_RETCODE_OK; + break; + } + tnow = ddsrt_time_monotonic(); + if (tnow.v >= timeout.v) { + ret = DDS_RETCODE_PRECONDITION_NOT_MET; + break; + } + tdur = (timeout.v -tnow.v <= DDS_MSECS(10)) ? timeout.v - tnow.v : DDS_MSECS(10); + dds_sleepfor (tdur); + } while (true); /* Note: potential but deliberate infinite loop when max_blocking_time is set to DDS_INFINITY. */ + return ret; +} + From 513c1d7e6083eb69cf844bf275126410965f5ea3 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 17 Oct 2023 10:25:01 +0200 Subject: [PATCH 179/207] Use similar idl files for durable client as for durable server Signed-off-by: TheFixer --- src/core/ddsc/src/dds_reader.c | 9 + src/durability/CMakeLists.txt | 4 +- .../include/dds/durability/dds_durability.h | 2 +- .../{client_durability.h => durablesupport.h} | 161 ++++-- src/durability/src/dds_durability.c | 49 +- .../{client_durability.c => durablesupport.c} | 546 ++++++++++++------ 6 files changed, 549 insertions(+), 222 deletions(-) rename src/durability/include/dds/durability/{client_durability.h => durablesupport.h} (67%) rename src/durability/src/{client_durability.c => durablesupport.c} (67%) diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index fa235c7086..ee5aa4f43f 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -52,6 +52,10 @@ #include "dds/ddsi/ddsi_tkmap.h" #endif +#ifdef DDS_HAS_DURABILITY +#include "dds/durability/dds_durability.h" +#endif + DECL_ENTITY_LOCK_UNLOCK (dds_reader) #define DDS_READER_STATUS_MASK \ @@ -789,6 +793,11 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe dds_topic_allow_set_qos (tp); dds_topic_unpin (tp); dds_subscriber_unlock (sub); + +#ifdef DDS_HAS_DURABILITY + dds_durability_new_local_reader(reader, rhc); +#endif + return reader; err_psmx_endpoint_setcb: diff --git a/src/durability/CMakeLists.txt b/src/durability/CMakeLists.txt index aec416df73..434c38867a 100644 --- a/src/durability/CMakeLists.txt +++ b/src/durability/CMakeLists.txt @@ -21,11 +21,11 @@ target_include_directories( set(headers "${source_dir}/include/dds/durability/dds_durability.h" - "${source_dir}/include/dds/durability/client_durability.h") + "${source_dir}/include/dds/durability/durablesupport.h") set(sources "${source_dir}/src/dds_durability.c" - "${source_dir}/src/client_durability.c") + "${source_dir}/src/durablesupport.c") target_sources(durability INTERFACE ${headers} ${sources}) diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h index 1db1572ac3..08d34d746d 100644 --- a/src/durability/include/dds/durability/dds_durability.h +++ b/src/durability/include/dds/durability/dds_durability.h @@ -27,7 +27,7 @@ typedef int (*plugin_finalize)(void *context); dds_return_t dds_durability_init (const dds_domainid_t domain, struct ddsi_domaingv *gv); dds_return_t dds_durability_fini (void); -void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc); +dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc); dds_return_t dds_durability_new_local_writer (dds_entity_t writer); dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer); diff --git a/src/durability/include/dds/durability/client_durability.h b/src/durability/include/dds/durability/durablesupport.h similarity index 67% rename from src/durability/include/dds/durability/client_durability.h rename to src/durability/include/dds/durability/durablesupport.h index 5f2649c6b3..1318821ee9 100644 --- a/src/durability/include/dds/durability/client_durability.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -8,8 +8,8 @@ in idlc_generate(). *****************************************************************/ -#ifndef CLIENT_DURABILITY_H -#define CLIENT_DURABILITY_H +#ifndef DURABLE_SUPPORT_H +#define DURABLE_SUPPORT_H #include "dds/ddsc/dds_public_impl.h" @@ -52,52 +52,92 @@ extern const dds_topic_descriptor_t DurableSupport_status_desc; #define DurableSupport_status_free(d,o) \ dds_sample_free ((d), &DurableSupport_status_desc, (o)) -typedef struct DurableSupport_request_id_t +typedef struct DurableSupport_range { - DurableSupport_id_t client; - uint64_t seq; -} DurableSupport_request_id_t; + uint64_t lb; + uint64_t ub; +} DurableSupport_range; -extern const dds_topic_descriptor_t DurableSupport_request_id_t_desc; +#ifndef DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED +#define DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED +typedef struct dds_sequence_DurableSupport_range +{ + uint32_t _maximum; + uint32_t _length; + struct DurableSupport_range *_buffer; + bool _release; +} dds_sequence_DurableSupport_range; -#define DurableSupport_request_id_t__alloc() \ -((DurableSupport_request_id_t*) dds_alloc (sizeof (DurableSupport_request_id_t))); +#define dds_sequence_DurableSupport_range__alloc() \ +((dds_sequence_DurableSupport_range*) dds_alloc (sizeof (dds_sequence_DurableSupport_range))); -#define DurableSupport_request_id_t_free(d,o) \ -dds_sample_free ((d), &DurableSupport_request_id_t_desc, (o)) +#define dds_sequence_DurableSupport_range_allocbuf(l) \ +((struct DurableSupport_range *) dds_alloc ((l) * sizeof (struct DurableSupport_range))) +#endif /* DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED */ -#ifndef DDS_SEQUENCE_STRING_DEFINED -#define DDS_SEQUENCE_STRING_DEFINED -typedef struct dds_sequence_string +typedef struct DurableSupport_writer +{ + DurableSupport_id_t id; + uint32_t flags; + dds_sequence_DurableSupport_range ranges; +} DurableSupport_writer; + +#ifndef DDS_SEQUENCE_DURABLESUPPORT_WRITER_DEFINED +#define DDS_SEQUENCE_DURABLESUPPORT_WRITER_DEFINED +typedef struct dds_sequence_DurableSupport_writer { uint32_t _maximum; uint32_t _length; - char **_buffer; + struct DurableSupport_writer *_buffer; bool _release; -} dds_sequence_string; +} dds_sequence_DurableSupport_writer; -#define dds_sequence_string__alloc() \ -((dds_sequence_string*) dds_alloc (sizeof (dds_sequence_string))); +#define dds_sequence_DurableSupport_writer__alloc() \ +((dds_sequence_DurableSupport_writer*) dds_alloc (sizeof (dds_sequence_DurableSupport_writer))); -#define dds_sequence_string_allocbuf(l) \ -((char **) dds_alloc ((l) * sizeof (char*))) -#endif /* DDS_SEQUENCE_STRING_DEFINED */ +#define dds_sequence_DurableSupport_writer_allocbuf(l) \ +((struct DurableSupport_writer *) dds_alloc ((l) * sizeof (struct DurableSupport_writer))) +#endif /* DDS_SEQUENCE_DURABLESUPPORT_WRITER_DEFINED */ -typedef struct DurableSupport_request +typedef struct DurableSupport_set { - struct DurableSupport_request_id_t requestid; char * partition; char * tpname; - dds_sequence_string alignment_partition; -} DurableSupport_request; + uint32_t flags; + dds_sequence_DurableSupport_writer writers; +} DurableSupport_set; -extern const dds_topic_descriptor_t DurableSupport_request_desc; +#ifndef DDS_SEQUENCE_DURABLESUPPORT_SET_DEFINED +#define DDS_SEQUENCE_DURABLESUPPORT_SET_DEFINED +typedef struct dds_sequence_DurableSupport_set +{ + uint32_t _maximum; + uint32_t _length; + struct DurableSupport_set *_buffer; + bool _release; +} dds_sequence_DurableSupport_set; -#define DurableSupport_request__alloc() \ -((DurableSupport_request*) dds_alloc (sizeof (DurableSupport_request))); +#define dds_sequence_DurableSupport_set__alloc() \ +((dds_sequence_DurableSupport_set*) dds_alloc (sizeof (dds_sequence_DurableSupport_set))); -#define DurableSupport_request_free(d,o) \ -dds_sample_free ((d), &DurableSupport_request_desc, (o)) +#define dds_sequence_DurableSupport_set_allocbuf(l) \ +((struct DurableSupport_set *) dds_alloc ((l) * sizeof (struct DurableSupport_set))) +#endif /* DDS_SEQUENCE_DURABLESUPPORT_SET_DEFINED */ + +typedef struct DurableSupport_state +{ + DurableSupport_id_t id; + char * name; + dds_sequence_DurableSupport_set sets; +} DurableSupport_state; + +extern const dds_topic_descriptor_t DurableSupport_state_desc; + +#define DurableSupport_state__alloc() \ +((DurableSupport_state*) dds_alloc (sizeof (DurableSupport_state))); + +#define DurableSupport_state_free(d,o) \ +dds_sample_free ((d), &DurableSupport_state_desc, (o)) #define DurableSupport_BEADTYPE_SESSION 1 #define DurableSupport_BEADTYPE_SET 2 @@ -106,7 +146,6 @@ dds_sample_free ((d), &DurableSupport_request_desc, (o)) #define DurableSupport_SESSION_KIND_START 1 #define DurableSupport_SESSION_KIND_END 2 #define DurableSupport_SESSION_KIND_ABORT 3 - typedef struct DurableSupport_session_t { DurableSupport_session_kind_t kind; @@ -138,12 +177,6 @@ typedef struct DurableSupport_set_t dds_sequence_DurableSupport_id_t addressees; } DurableSupport_set_t; -typedef struct DurableSupport_range -{ - uint64_t lb; - uint64_t ub; -} DurableSupport_range; - #ifndef DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED #define DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED typedef struct dds_sequence_DurableSupport_range @@ -216,8 +249,60 @@ extern const dds_topic_descriptor_t DurableSupport_bead_desc; #define DurableSupport_bead_free(d,o) \ dds_sample_free ((d), &DurableSupport_bead_desc, (o)) +typedef int64_t DurableSupport_duration_t; + +#define DurableSupport_duration_t__alloc() \ +((DurableSupport_duration_t*) dds_alloc (sizeof (DurableSupport_duration_t))); + +typedef struct DurableSupport_request_id_t +{ + DurableSupport_id_t client; + uint64_t seq; +} DurableSupport_request_id_t; + +extern const dds_topic_descriptor_t DurableSupport_request_id_t_desc; + +#define DurableSupport_request_id_t__alloc() \ +((DurableSupport_request_id_t*) dds_alloc (sizeof (DurableSupport_request_id_t))); + +#define DurableSupport_request_id_t_free(d,o) \ +dds_sample_free ((d), &DurableSupport_request_id_t_desc, (o)) + +#ifndef DDS_SEQUENCE_STRING_DEFINED +#define DDS_SEQUENCE_STRING_DEFINED +typedef struct dds_sequence_string +{ + uint32_t _maximum; + uint32_t _length; + char **_buffer; + bool _release; +} dds_sequence_string; + +#define dds_sequence_string__alloc() \ +((dds_sequence_string*) dds_alloc (sizeof (dds_sequence_string))); + +#define dds_sequence_string_allocbuf(l) \ +((char **) dds_alloc ((l) * sizeof (char*))) +#endif /* DDS_SEQUENCE_STRING_DEFINED */ + +typedef struct DurableSupport_request +{ + struct DurableSupport_request_id_t requestid; + dds_sequence_string partitions; + char * tpname; + DurableSupport_duration_t timeout; +} DurableSupport_request; + +extern const dds_topic_descriptor_t DurableSupport_request_desc; + +#define DurableSupport_request__alloc() \ +((DurableSupport_request*) dds_alloc (sizeof (DurableSupport_request))); + +#define DurableSupport_request_free(d,o) \ +dds_sample_free ((d), &DurableSupport_request_desc, (o)) + #ifdef __cplusplus } #endif -#endif /* CLIENT_DURABILITY_H */ +#endif /* DURABLE_SUPPORT_H */ diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index d5fe416e65..66778e282b 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -11,7 +11,7 @@ */ #include "dds/ddsi/ddsi_domaingv.h" #include "dds/durability/dds_durability.h" -#include "dds/durability/client_durability.h" +#include "dds/durability/durablesupport.h" #include "dds/ddsrt/atomics.h" #include "dds/ddsrt/string.h" #include "dds/ddsrt/heap.h" @@ -157,6 +157,8 @@ struct com_t { */ struct dc_t { struct { + DurableSupport_id_t id; /* the id of this client */ + char id_str[37]; /* string representation of the service id */ char *request_partition; /* partition to send requests too; by default same as */ uint32_t quorum; /*quorum of durable services needed to unblock durable writers */ char *ident; /* ds identification */ @@ -292,7 +294,7 @@ static int create_request_partition_expression (struct com_t *com, char **reques char req_pname[1024] = { 0 }; int result = 0; - (void)com; + (void)com; if ((result = get_host_specific_partition_name(req_pname, 1024)) < 0) { DDS_ERROR("Failed to create request partition expression\n"); return -1; @@ -317,6 +319,7 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, unsigned nps; dds_return_t ret; char *request_partition = NULL; + dds_guid_t guid; (void)dc; if ((com = (struct com_t *)ddsrt_malloc(sizeof(struct com_t))) == NULL) { @@ -328,6 +331,15 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc participant [%s]\n", dds_strretcode(-com->participant)); goto err_create_participant; } + /* use the participant guid as the identification of this client */ + if ((ret = dds_get_guid(com->participant, &guid)) != DDS_RETCODE_OK) { + DDS_ERROR("failed to get dc participant guid [%s]\n", dds_strretcode(-ret)); + goto err_get_guid; + } + /* get and cache the id of the participant */ + memcpy(dc->cfg.id, guid.v, 16); + (void)dc_stringify_id(dc->cfg.id, dc->cfg.id_str); + /* create subscriber */ if ((status_sqos = dds_create_qos()) == NULL) { DDS_ERROR("failed to create the dc status subscriber qos\n"); goto err_alloc_status_sqos; @@ -537,6 +549,7 @@ err_response_subscriber : dds_free(bufcopy1); dds_free(ps1); err_alloc_status_sqos: +err_get_guid: dds_delete(com->participant); err_create_participant: ddsrt_free(com); @@ -554,6 +567,25 @@ static void dc_com_free (struct com_t *com) return; } +static dds_return_t dc_com_send_request (struct com_t *com, dds_entity_t reader) +{ + /* check for publication_matched() on the dc_request writer tomake sure that the request arrives */ + /* create a request */ + /* set the request on the pending liust */ + /* send the request */ + + /* note: we allow doing a request for volatile readers */ + DurableSupport_request *request; + + request = DurableSupport_request__alloc(); + memcpy(request->requestid.client, dc.cfg.id, 16); + DurableSupport_request_free(request, DDS_FREE_ALL); + + (void)com; + (void)reader; + return DDS_RETCODE_OK; +} + static void dc_server_lost (struct dc_t *dc, DurableSupport_status *status) { struct server_t *server; @@ -985,9 +1017,12 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom } /* This is the first participant, so let's create a durable client (dc). * The dc will also create a new participant, therefore - * increase the refcount for this participant as well. */ + * increase the refcount for this participant as well. + * The guid of the participant for client durability will be used + * to identify this client. */ ddsrt_atomic_inc32(&dc.refcount); dc.gv = gv; + /* Note: dc.cfg.id will be set once we create the participant in dc_com_new() */ dc.cfg.quorum = DEFAULT_QOURUM; /* LH: currently hardcoded set to 1, should be made configurable in future */ dc.cfg.ident = ddsrt_strdup(DEFAULT_IDENT); ddsrt_avl_cinit(&server_td, &dc.servers); @@ -1052,14 +1087,18 @@ bool dds_durability_is_terminating (void) return (ddsrt_atomic_ld32(&dc.termflag) > 0); } -void dds_durability_new_local_reader (struct dds_reader *reader, struct dds_rhc *rhc) +dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc) { /* create the administration to store transient data */ /* create a durability reader that sucks and stores it in the store */ + /* send a request */ + + dc_com_send_request (dc.com, reader); + (void)rhc; (void)reader; - return; + return DDS_RETCODE_OK;; } /* This function checks if the writer has reached the quorum of matching durable containers diff --git a/src/durability/src/client_durability.c b/src/durability/src/durablesupport.c similarity index 67% rename from src/durability/src/client_durability.c rename to src/durability/src/durablesupport.c index ea5429a4d8..4a19d54e8f 100644 --- a/src/durability/src/client_durability.c +++ b/src/durability/src/durablesupport.c @@ -1,14 +1,12 @@ /**************************************************************** - IMPORTANT: - - The file contains the definitions for the client durability related topics. - This file is partially copied from the output generated by durabledupport.idl - because we cannot generate code from an idl file due to cyclic dependencies - in idlc_generate(). + Generated by Eclipse Cyclone DDS IDL to C Translator + File name: /home/lex/Repositories/TheFixer/durable_support/build/src/durablesupport.c + Source: /home/lex/Repositories/TheFixer/durable_support/src/durablesupport.idl + Cyclone DDS: V0.11.0 *****************************************************************/ -#include "../include/dds/durability/client_durability.h" +#include "../include/dds/durability/durablesupport.h" static const uint32_t DurableSupport_status_ops [] = { @@ -18,7 +16,7 @@ static const uint32_t DurableSupport_status_ops [] = DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_status, hostname), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_status, name), DDS_OP_RTS, - + /* key: id */ DDS_OP_KOF | 1, 1u /* order: 0 */ }; @@ -95,200 +93,183 @@ const dds_topic_descriptor_t DurableSupport_status_desc = .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_status, .sz = TYPE_MAP_CDR_SZ_DurableSupport_status } }; -static const uint32_t DurableSupport_request_id_t_ops [] = +static const uint32_t DurableSupport_state_ops [] = { - /* request_id_t */ + /* state */ DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), - DDS_OP_RTS -}; - -/* Type Information: - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] (#deps: 1) - - [MINIMAL 43f53a2be35b432cc735e9431a89] - [COMPLETE 852fffc913b7ee54aadae7a1859a] (#deps: 1) - - [COMPLETE aca4d5a256d39713924333e85c6d] -*/ -#define TYPE_INFO_CDR_DurableSupport_request_id_t (const unsigned char []){ \ - 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, \ - 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, \ - 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x40, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_request_id_t 148u -#define TYPE_MAP_CDR_DurableSupport_request_id_t (const unsigned char []){ \ - 0x8a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ - 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ - 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, \ - 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, \ - 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ - 0xe4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ - 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ - 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ - 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0xf1, \ - 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_request_id_t 444u -const dds_topic_descriptor_t DurableSupport_request_id_t_desc = -{ - .m_size = sizeof (DurableSupport_request_id_t), - .m_align = dds_alignof (DurableSupport_request_id_t), - .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 0u, - .m_typename = "DurableSupport::request_id_t", - .m_keys = NULL, - .m_nops = 4, - .m_ops = DurableSupport_request_id_t_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request_id_t, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request_id_t }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request_id_t, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request_id_t } -}; + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_state, id), 16u, + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_state, name), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_state, sets), sizeof (DurableSupport_set), (4u << 16u) + 5u /* set */, + DDS_OP_RTS, -static const uint32_t DurableSupport_request_ops [] = -{ - /* request */ + /* set */ DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_EXT, offsetof (DurableSupport_request, requestid), (3u << 16u) + 10u /* request_id_t */, - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, partition), - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STR, offsetof (DurableSupport_request, alignment_partition), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, partition), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, tpname), + DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_set, flags), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_set, writers), sizeof (DurableSupport_writer), (4u << 16u) + 5u /* writer */, DDS_OP_RTS, - /* request_id_t */ + /* writer */ DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_writer, id), 16u, + DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_writer, flags), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_writer, ranges), sizeof (DurableSupport_range), (4u << 16u) + 5u /* range */, DDS_OP_RTS, - /* key: requestid.client */ - DDS_OP_KOF | 2, 1u /* order: 0 */, 1u /* order: 0 */, - - /* key: requestid.seq */ - DDS_OP_KOF | 2, 1u /* order: 0 */, 4u /* order: 1 */ + /* range */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, lb), + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, ub), + DDS_OP_RTS, + + /* key: id */ + DDS_OP_KOF | 1, 1u /* order: 0 */ }; -static const dds_key_descriptor_t DurableSupport_request_keys[2] = +static const dds_key_descriptor_t DurableSupport_state_keys[1] = { - { "requestid.client", 18, 0 }, - { "requestid.seq", 21, 1 } + { "id", 40, 0 } }; /* Type Information: - [MINIMAL 54af0d70dd88f2a169924dd8b880] (#deps: 2) - - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] + [MINIMAL 29c25c35d5510f091b9d2951e87d] (#deps: 4) - [MINIMAL 43f53a2be35b432cc735e9431a89] - [COMPLETE 77ef4931b703e23e4f8f33c76508] (#deps: 2) - - [COMPLETE 852fffc913b7ee54aadae7a1859a] + - [MINIMAL 4c34d21c8ec2020e687b75390553] + - [MINIMAL 7b73d4df4f265b2da8c52f3c3a8e] + - [MINIMAL ef038b7b19448c9ce27fa1c268cd] + [COMPLETE a4dc41b7052cef5bfdb62c313d77] (#deps: 4) - [COMPLETE aca4d5a256d39713924333e85c6d] + - [COMPLETE ec0a17f45bf4c4917bb5db3c5b18] + - [COMPLETE 3be64a4fbc92a7b2f612cbd52a3a] + - [COMPLETE d8d43c2295c185a21b9591a7126c] */ -#define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ - 0xc0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x54, 0xaf, 0x0d, 0x70, 0xdd, 0x88, 0xf2, 0xa1, 0x69, 0x92, 0x4d, \ - 0xd8, 0xb8, 0x80, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ - 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x77, 0xef, 0x49, 0x31, 0xb7, 0x03, 0xe2, 0x3e, 0x4f, 0x8f, 0x33, \ - 0xc7, 0x65, 0x08, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ - 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x40, 0x00, 0x00, 0x00\ +#define TYPE_INFO_CDR_DurableSupport_state (const unsigned char []){ \ + 0x20, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x29, 0xc2, 0x5c, 0x35, 0xd5, 0x51, 0x0f, 0x09, 0x1b, 0x9d, 0x29, \ + 0x51, 0xe8, 0x7d, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, 0x05, 0x53, 0x00, \ + 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, \ + 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, \ + 0x37, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa4, 0xdc, 0x41, 0xb7, 0x05, 0x2c, 0xef, 0x5b, 0xfd, 0xb6, 0x2c, \ + 0x31, 0x3d, 0x77, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xec, 0x0a, 0x17, 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, 0x3c, 0x5b, 0x18, 0x00, \ + 0xae, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, \ + 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, \ + 0x61, 0x00, 0x00, 0x00\ } -#define TYPE_INFO_CDR_SZ_DurableSupport_request 196u -#define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ - 0x06, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0x54, 0xaf, 0x0d, 0x70, 0xdd, 0x88, 0xf2, \ - 0xa1, 0x69, 0x92, 0x4d, 0xd8, 0xb8, 0x80, 0x00, 0x69, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, \ - 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x3c, 0xb0, 0x21, 0x74, 0x00, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ - 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ - 0x11, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, \ - 0x00, 0xd8, 0xc7, 0x47, 0x1e, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, \ - 0x0f, 0xd5, 0x22, 0xa4, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, \ - 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, \ - 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ - 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xbc, 0x01, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0xf2, 0x77, 0xef, 0x49, 0x31, 0xb7, 0x03, 0xe2, 0x3e, 0x4f, 0x8f, 0x33, \ - 0xc7, 0x65, 0x08, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x00, \ - 0x96, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, \ - 0x9a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, \ - 0x64, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, \ - 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, \ - 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x02, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ +#define TYPE_INFO_CDR_SZ_DurableSupport_state 292u +#define TYPE_MAP_CDR_DurableSupport_state (const unsigned char []){ \ + 0xef, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf1, 0x29, 0xc2, 0x5c, 0x35, 0xd5, 0x51, 0x0f, \ + 0x09, 0x1b, 0x9d, 0x29, 0x51, 0xe8, 0x7d, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0xb0, 0x68, 0x93, 0x1c, \ + 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ + 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, 0x05, 0x53, 0x17, 0x8d, \ + 0x51, 0x02, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, \ + 0x89, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x10, 0x02, 0xf1, 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, 0x05, \ + 0x53, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x0b, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, \ + 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0xbf, 0x63, 0x9b, 0x5f, 0xf1, 0x7b, \ + 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0x00, 0x00, 0x00, \ + 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x56, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, \ + 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, \ + 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x8d, 0x81, 0x02, 0xfb, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, \ + 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x26, \ + 0x40, 0x3e, 0xc6, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x1c, \ + 0x78, 0xb4, 0x86, 0x00, 0xe5, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf2, 0xa4, 0xdc, 0x41, \ + 0xb7, 0x05, 0x2c, 0xef, 0x5b, 0xfd, 0xb6, 0x2c, 0x31, 0x3d, 0x77, 0x00, 0x9b, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x02, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ - 0x46, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0x73, 0x74, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x70, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, \ + 0x27, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, \ + 0xec, 0x0a, 0x17, 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, 0x3c, 0x5b, 0x18, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, \ + 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0xf2, 0x77, 0xef, 0x49, 0x31, 0xb7, 0x03, 0xe2, 0x3e, 0x4f, 0x8f, 0x33, \ - 0xc7, 0x65, 0x08, 0xf1, 0x54, 0xaf, 0x0d, 0x70, 0xdd, 0x88, 0xf2, 0xa1, 0x69, 0x92, 0x4d, 0xd8, \ - 0xb8, 0x80, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, \ - 0x9a, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, \ - 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0xec, 0x0a, 0x17, \ + 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, 0x3c, 0x5b, 0x18, 0x00, 0xaa, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x73, 0x65, 0x74, 0x00, 0x82, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, \ + 0xbc, 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, \ + 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, \ + 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ + 0x29, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, \ + 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, \ + 0x07, 0x00, 0x00, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, \ + 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x5d, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x6c, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x9a, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf2, 0xa4, 0xdc, 0x41, 0xb7, 0x05, 0x2c, 0xef, \ + 0x5b, 0xfd, 0xb6, 0x2c, 0x31, 0x3d, 0x77, 0xf1, 0x29, 0xc2, 0x5c, 0x35, 0xd5, 0x51, 0x0f, 0x09, \ + 0x1b, 0x9d, 0x29, 0x51, 0xe8, 0x7d, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, \ + 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0xec, 0x0a, 0x17, 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, \ + 0x3c, 0x5b, 0x18, 0xf1, 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, \ + 0x05, 0x53, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, \ + 0x3a, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, \ + 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, \ + 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_request 814u -const dds_topic_descriptor_t DurableSupport_request_desc = +#define TYPE_MAP_CDR_SZ_DurableSupport_state 1406u +const dds_topic_descriptor_t DurableSupport_state_desc = { - .m_size = sizeof (DurableSupport_request), - .m_align = dds_alignof (DurableSupport_request), + .m_size = sizeof (DurableSupport_state), + .m_align = dds_alignof (DurableSupport_state), .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 2u, - .m_typename = "DurableSupport::request", - .m_keys = DurableSupport_request_keys, - .m_nops = 10, - .m_ops = DurableSupport_request_ops, + .m_nkeys = 1u, + .m_typename = "DurableSupport::state", + .m_keys = DurableSupport_state_keys, + .m_nops = 20, + .m_ops = DurableSupport_state_ops, .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request } + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_state, .sz = TYPE_INFO_CDR_SZ_DurableSupport_state }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_state, .sz = TYPE_MAP_CDR_SZ_DurableSupport_state } }; static const uint32_t DurableSupport_bead_ops [] = @@ -341,7 +322,7 @@ static const uint32_t DurableSupport_bead_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_data_t, blob), DDS_OP_RTS, - + /* key: id */ DDS_OP_KOF | 1, 1u /* order: 0 */ }; @@ -604,3 +585,216 @@ const dds_topic_descriptor_t DurableSupport_bead_desc = .type_information = { .data = TYPE_INFO_CDR_DurableSupport_bead, .sz = TYPE_INFO_CDR_SZ_DurableSupport_bead }, .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_bead, .sz = TYPE_MAP_CDR_SZ_DurableSupport_bead } }; + +static const uint32_t DurableSupport_request_id_t_ops [] = +{ + /* request_id_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), + DDS_OP_RTS +}; + +/* Type Information: + [MINIMAL 28dabddcc42d4b6a3d640fd522a4] (#deps: 1) + - [MINIMAL 43f53a2be35b432cc735e9431a89] + [COMPLETE 852fffc913b7ee54aadae7a1859a] (#deps: 1) + - [COMPLETE aca4d5a256d39713924333e85c6d] +*/ +#define TYPE_INFO_CDR_DurableSupport_request_id_t (const unsigned char []){ \ + 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, \ + 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, \ + 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ + 0x40, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_request_id_t 148u +#define TYPE_MAP_CDR_DurableSupport_request_id_t (const unsigned char []){ \ + 0x8a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ + 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, \ + 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, \ + 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ + 0xe4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ + 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ + 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0xf1, \ + 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_request_id_t 444u +const dds_topic_descriptor_t DurableSupport_request_id_t_desc = +{ + .m_size = sizeof (DurableSupport_request_id_t), + .m_align = dds_alignof (DurableSupport_request_id_t), + .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 0u, + .m_typename = "DurableSupport::request_id_t", + .m_keys = NULL, + .m_nops = 4, + .m_ops = DurableSupport_request_id_t_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request_id_t, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request_id_t }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request_id_t, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request_id_t } +}; + +static const uint32_t DurableSupport_request_ops [] = +{ + /* request */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_EXT, offsetof (DurableSupport_request, requestid), (3u << 16u) + 10u /* request_id_t */, + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STR, offsetof (DurableSupport_request, partitions), + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), + DDS_OP_ADR | DDS_OP_TYPE_8BY | DDS_OP_FLAG_SGN, offsetof (DurableSupport_request, timeout), + DDS_OP_RTS, + + /* request_id_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), + DDS_OP_RTS, + + /* key: requestid.client */ + DDS_OP_KOF | 2, 1u /* order: 0 */, 1u /* order: 0 */, + + /* key: requestid.seq */ + DDS_OP_KOF | 2, 1u /* order: 0 */, 4u /* order: 1 */ +}; + +static const dds_key_descriptor_t DurableSupport_request_keys[2] = +{ + { "requestid.client", 18, 0 }, + { "requestid.seq", 21, 1 } +}; + +/* Type Information: + [MINIMAL 20fb854c344bb02af8430115a676] (#deps: 3) + - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] + - [MINIMAL 43f53a2be35b432cc735e9431a89] + - [MINIMAL 84ce9c3d894c1483f859c00d5927] + [COMPLETE 2de91793545eff71a07b9e15f413] (#deps: 3) + - [COMPLETE 852fffc913b7ee54aadae7a1859a] + - [COMPLETE aca4d5a256d39713924333e85c6d] + - [COMPLETE 023df3bd21223779cd1936cef928] +*/ +#define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ + 0xf0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x20, 0xfb, 0x85, 0x4c, 0x34, 0x4b, 0xb0, 0x2a, 0xf8, 0x43, 0x01, \ + 0x15, 0xa6, 0x76, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ + 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, \ + 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x2d, 0xe9, 0x17, \ + 0x93, 0x54, 0x5e, 0xff, 0x71, 0xa0, 0x7b, 0x9e, 0x15, 0xf4, 0x13, 0x00, 0xce, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, \ + 0x7e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ + 0x39, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_request 244u +#define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ + 0x3b, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf1, 0x20, 0xfb, 0x85, 0x4c, 0x34, 0x4b, 0xb0, \ + 0x2a, 0xf8, 0x43, 0x01, 0x15, 0xa6, 0x76, 0x00, 0x79, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, \ + 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x3c, 0xb0, 0x21, 0x74, 0x00, 0x00, 0x00, \ + 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, \ + 0x00, 0xae, 0xa4, 0x67, 0xe1, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, \ + 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, \ + 0x0f, 0xd5, 0x22, 0xa4, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, \ + 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, \ + 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ + 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ + 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, \ + 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ + 0x0d, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf2, 0x2d, 0xe9, 0x17, 0x93, 0x54, 0x5e, 0xff, \ + 0x71, 0xa0, 0x7b, 0x9e, 0x15, 0xf4, 0x13, 0x00, 0xca, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ + 0x65, 0x73, 0x74, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, \ + 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x72, 0x65, 0x71, 0x75, \ + 0x65, 0x73, 0x74, 0x69, 0x64, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, \ + 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, \ + 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, \ + 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ + 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, \ + 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x75, 0x72, 0x61, \ + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf2, 0x2d, 0xe9, 0x17, \ + 0x93, 0x54, 0x5e, 0xff, 0x71, 0xa0, 0x7b, 0x9e, 0x15, 0xf4, 0x13, 0xf1, 0x20, 0xfb, 0x85, 0x4c, \ + 0x34, 0x4b, 0xb0, 0x2a, 0xf8, 0x43, 0x01, 0x15, 0xa6, 0x76, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, \ + 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, \ + 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, \ + 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, \ + 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, \ + 0xc0, 0x0d, 0x59, 0x27\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_request 980u +const dds_topic_descriptor_t DurableSupport_request_desc = +{ + .m_size = sizeof (DurableSupport_request), + .m_align = dds_alignof (DurableSupport_request), + .m_flagset = DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 2u, + .m_typename = "DurableSupport::request", + .m_keys = DurableSupport_request_keys, + .m_nops = 10, + .m_ops = DurableSupport_request_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request } +}; + From a4ffe3d807f52e056669de5c06f88cbaea3ecac0 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 20 Oct 2023 08:45:20 +0200 Subject: [PATCH 180/207] Initialize quorum_reached variable correctly in case quorum threshold is set to 0 (even though we might want to forbid it as an invalid configuration). Signed-off-by: TheFixer --- src/core/ddsc/src/dds_writer.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/core/ddsc/src/dds_writer.c b/src/core/ddsc/src/dds_writer.c index 6336bfa166..fcc2c9bf1b 100644 --- a/src/core/ddsc/src/dds_writer.c +++ b/src/core/ddsc/src/dds_writer.c @@ -429,8 +429,16 @@ static dds_entity_t dds_create_writer_int (dds_entity_t participant_or_publisher goto err_pipe_open; #if DDS_HAS_DURABILITY - /* quorum applies only to durable writers, initially quorum is not reached */ - wr->quorum_reached = (wqos->durability.kind <= DDS_DURABILITY_TRANSIENT_LOCAL) ? true : false; + /* quorum applies only to durable writers. + * By default quorum reached for volatile and transient-local writers + * For durable writer the quorum is initially reached when quorum threshold == 0 + * (but we'll likely prohibit this case as an invalid configuration because + * it may lead to eventual inconsistencies). */ + uint32_t quorum = dds_durability_get_quorum(); + wr->quorum_reached = true; + if (wqos->durability.kind >= DDS_DURABILITY_TRANSIENT) { + wr->quorum_reached = (quorum == 0); + } #endif struct ddsi_sertype *sertype = ddsi_sertype_derive_sertype (tp->m_stype, data_representation, From 3b1ed77cde2d4298f9d0490365b037866e73c15f Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 20 Oct 2023 09:24:50 +0200 Subject: [PATCH 181/207] Use dds_get_matched_subscriptions() in dc_check_quorum_reched() to determine if a quorum is reached Signed-off-by: TheFixer --- .../include/dds/durability/dds_durability.h | 2 +- src/durability/src/dds_durability.c | 859 ++++++++---------- 2 files changed, 386 insertions(+), 475 deletions(-) diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h index 08d34d746d..37294cd825 100644 --- a/src/durability/include/dds/durability/dds_durability.h +++ b/src/durability/include/dds/durability/dds_durability.h @@ -27,10 +27,10 @@ typedef int (*plugin_finalize)(void *context); dds_return_t dds_durability_init (const dds_domainid_t domain, struct ddsi_domaingv *gv); dds_return_t dds_durability_fini (void); +uint32_t dds_durability_get_quorum (void); dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc); dds_return_t dds_durability_new_local_writer (dds_entity_t writer); dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer); - dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer); bool dds_durability_is_terminating (void); diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 66778e282b..321cdc1fce 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -21,6 +21,7 @@ #include #include "dds__writer.h" #include "dds/ddsi/ddsi_endpoint.h" +#include "dds/ddsrt/avl.h" #define DEFAULT_QOURUM 1 #define DEFAULT_IDENT "durable_support" @@ -37,7 +38,6 @@ static char *dc_stringify_id(const DurableSupport_id_t id, char *buf) return buf; } - struct server_t { ddsrt_avl_node_t node; DurableSupport_id_t id; /* id key */ @@ -61,71 +61,6 @@ static void cleanup_server (void *n) static const ddsrt_avl_ctreedef_t server_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct server_t, node), offsetof (struct server_t, id), cmp_server, 0); - -struct quorum_entry_key_t { - char *partition; /* the partition of the data container; should be a singleton */ - char *tpname; /* topic name */ - /* LH: todo: add a type id to support xtypes */ -}; - -struct quorum_entry_t { - ddsrt_avl_node_t node; - struct quorum_entry_key_t key; - uint32_t cnt; /* the number of data containers found for this partition/topic combination */ -}; - -static int cmp_quorum_entry (const void *a, const void *b) -{ - struct quorum_entry_key_t *qk1 = (struct quorum_entry_key_t *)a; - struct quorum_entry_key_t *qk2 = (struct quorum_entry_key_t *)b; - int cmp; - - if ((cmp = strcmp(qk1->partition, qk2->partition)) < 0) { - return -1; - } else if (cmp > 0) { - return 1; - } else if ((cmp = strcmp(qk1->tpname, qk2->tpname)) < 0) { - return -1; - } else if (cmp > 0) { - return 1; - } else { - return 0; - } -} - -static void cleanup_quorum_entry (void *n) -{ - struct quorum_entry_t *qe = (struct quorum_entry_t *)n; - ddsrt_free(qe->key.partition); - ddsrt_free(qe->key.tpname); - ddsrt_free(qe); -} - -static const ddsrt_avl_ctreedef_t quorum_entry_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct quorum_entry_t, node), offsetof (struct quorum_entry_t, key), cmp_quorum_entry, 0); - -struct handle_to_quorum_entry_t { - ddsrt_avl_node_t node; - dds_instance_handle_t ih; - struct quorum_entry_t *qe_ref; /* reference to quorum entry */ -}; - -static int cmp_instance_handle (const void *a, const void *b) -{ - dds_instance_handle_t *ih1 = (dds_instance_handle_t *)a; - dds_instance_handle_t *ih2 = (dds_instance_handle_t *)b; - - return (*ih1 < *ih2) ? -1 : ((*ih1 > *ih2) ? 1 : 0); -} - -static void cleanup_handle_to_quorum_entry (void *n) -{ - struct handle_to_quorum_entry_t *hqe = (struct handle_to_quorum_entry_t *)n; - - ddsrt_free(hqe); -} - -static const ddsrt_avl_ctreedef_t handle_to_quorum_entry_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct handle_to_quorum_entry_t, node), offsetof (struct handle_to_quorum_entry_t, ih), cmp_instance_handle, 0); - struct com_t { dds_entity_t participant; /* durable client participant */ dds_entity_t status_subscriber; /* subscriber used to receive status messages */ @@ -163,6 +98,7 @@ struct dc_t { uint32_t quorum; /*quorum of durable services needed to unblock durable writers */ char *ident; /* ds identification */ } cfg; + uint64_t seq; /* monotonically increasing sequence number, bumped by 1 for each request by this client */ ddsrt_atomic_uint32_t refcount; /* refcount, increased/decreased when a participant is created/deleted */ struct ddsi_domaingv *gv; /* reference to ddsi domain settings */ struct com_t *com; /* ptr to durable client communication infra structure */ @@ -207,36 +143,6 @@ static unsigned split_string (const char ***p_ps, char **p_bufcopy, const char * return nps; } -#if 0 -/* callback function to update the sequence number administration of a container - * and to optionally monitor the contents of data containers */ -static void default_data_available_cb (dds_entity_t rd, void *arg) -{ -#define MAX_SAMPLES 100 - int samplecount; - static void *samples[MAX_SAMPLES]; - dds_sample_info_t info[MAX_SAMPLES]; - - (void)arg; - - samplecount = dds_read_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ALIVE_INSTANCE_STATE); - printf("LH *** samplecount = %d\n", samplecount); - if (samplecount < 0) { - printf("LH *** dds_read_mask for status reader failed: %s", dds_strretcode(-samplecount)); - goto samplecount_err; - } - for (int j = 0; j < samplecount; j++) { - DurableSupport_status *status = (DurableSupport_status *)samples[j]; - printf("LH *** recv status(): name=%s\n", status->name); - info[j].publication_handle(); - - } -samplecount_err: -#undef MAX_SAMPLES - return; -} -#endif - static struct server_t *create_server (struct dc_t *dc, DurableSupport_id_t id, const char *name, const char *hostname) { struct server_t *server; @@ -305,6 +211,295 @@ static int create_request_partition_expression (struct com_t *com, char **reques return 0; } +/* The following is used to build up an administration to evaluate + * if a writer has reached its quorum for durable containers. + * The administration uses data container counters to count the + * number of data container matches for a given writer. If the writer + * publishes on multiple partitions, we requires that for each of + * these partitions the quorum must be met in order for the publisher + * to start publishing. + * To retrieve the matching data containers for a writer we use + * dds_get_matched_subscriptions(). This call returns the matched + * reader for a given writer, even the onces that occurred before the + * quorum listener has been attached to the writer. To reduce the + * number of calls to dds_get_matched_subscriptions() we only call + * it there is a risk that the quorum changes. + */ +struct data_container_cnt_key_t { + char *partition; +}; + +struct data_container_cnt_t { + ddsrt_avl_node_t node; + struct data_container_cnt_key_t key; + uint32_t cnt; +}; + +static void cleanup_data_container_cnt (void *n) +{ + struct data_container_cnt_t *dcc = (struct data_container_cnt_t *)n; + + ddsrt_free(dcc->key.partition); + ddsrt_free(dcc); +} + +static int cmp_data_container_cnt (const void *a, const void *b) +{ + struct data_container_cnt_key_t *k1 = (struct data_container_cnt_key_t *)a; + struct data_container_cnt_key_t *k2 = (struct data_container_cnt_key_t *)b; + + return strcmp(k1->partition, k2->partition); +} + +static const ddsrt_avl_ctreedef_t data_container_cnt_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct data_container_cnt_t, node), offsetof (struct data_container_cnt_t, key), cmp_data_container_cnt, 0); + + +static struct data_container_cnt_t *create_data_container_cnt (ddsrt_avl_ctree_t *dcc_tree, const char *partition) +{ + struct data_container_cnt_t *dcc; + + assert(partition); + dcc = (struct data_container_cnt_t *)ddsrt_malloc(sizeof(struct data_container_cnt_t)); + dcc->key.partition = ddsrt_strdup(partition); + dcc->cnt = 0; + ddsrt_avl_cinsert(&data_container_cnt_td, dcc_tree, dcc); + return dcc; +} + +static struct data_container_cnt_t *get_data_container_cnt (ddsrt_avl_ctree_t *dcc_tree, const char *partition, bool autocreate) +{ + struct data_container_cnt_t *dcc = NULL; + struct data_container_cnt_key_t key; + + assert(dcc_tree); + assert(partition); + key.partition = ddsrt_strdup(partition); + if (((dcc = ddsrt_avl_clookup (&data_container_cnt_td, dcc_tree, &key)) == NULL) && autocreate) { + dcc = create_data_container_cnt(dcc_tree, partition); + } + ddsrt_free(key.partition); + return dcc; +} + +static void dc_free_partitions (uint32_t plen, char **partitions) +{ + uint32_t i; + + if (partitions == NULL) { + return; + } + for (i=0; i < plen; i++) { + ddsrt_free(partitions[i]); + } + ddsrt_free(partitions); +} + +/* verifies if the user data of the endpoint contains the identifier + * that indicates that this endpoint is a durable container */ +static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *ep, const char *ident) +{ + dds_builtintopic_endpoint_t template; + dds_builtintopic_participant_t *participant; + dds_instance_handle_t ih; + dds_return_t rc; + static void *samples[1]; + static dds_sample_info_t info[1]; + void *userdata; + size_t size = 0; + char id_str[37]; + bool result = false; + + assert(ep); + /* by convention, if the ident == NULL then return true */ + if (ident == NULL) { + return true; + } + /* lookup the instance handle of the builtin participant endpoint that + * contains the participant of the subinfo */ + memcpy(template.key.v,ep->participant_key.v,16); + if ((ih = dds_lookup_instance(com->rd_participant, &template)) == DDS_HANDLE_NIL) { + DDS_ERROR("Failed to lookup the participant of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); + goto err_lookup_instance; + } + if ((rc = dds_read_instance(com->rd_participant, samples, info, 1, 1, ih)) <= 0) { + DDS_ERROR("Failed to read the participant of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); + goto err_read_instance; + } + if (info[0].valid_data) { + participant = (dds_builtintopic_participant_t *)samples[0]; + /* get the user data */ + if (!dds_qget_userdata(participant->qos, &userdata, &size)) { + DDS_ERROR("Unable to retrieve the user data of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); + goto err_qget_userdata; + } + if ((size != strlen(ident)) || (userdata == NULL) || (strcmp(userdata, ident) != 0)) { + /* the user data of the participant of the durable reader does not contain the ident, + * so the endoint is not from a remote DS */ + result = false; + } else { + /* this endpoint's participant is a ds */ + result = true; + } + dds_free(userdata); + } + return result; + +err_lookup_instance: +err_read_instance: +err_qget_userdata: + return false; +} + +/* Determine if the quorum for the writer is reached or not. + * This function also does its job when the quorum threshold is 0, + * even though this case is likely to be prohibited because it + * violates eventual consistency. After all, how can you provide + * historical data if you allow that durable publishers start to + * publish when there is no durable support? */ +static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer, bool wr_appeared) +{ + /* precondition: the writer is only called when we know that the writer is durable */ + + dds_qos_t *qos; + dds_return_t ret; + uint32_t plen, i; + char **partitions; + char *tpname; + dds_writer *wr; + bool old_quorum_reached, quorum_reached = true; + bool to_check = false; + struct data_container_cnt_t *dcc; + dds_guid_t wguid; + char id_str[37]; + + qos = dds_create_qos(); + if ((ret = dds_get_qos(writer, qos)) < 0) { + DDS_ERROR("failed to get qos from writer [%s]\n", dds_strretcode(ret)); + goto err_get_qos; + } + if (!dds_qget_partition(qos, &plen, &partitions)) { + DDS_ERROR("failed to get partitions from qos\n"); + goto err_qget_partition; + } + assert(plen > 0); + if (dds_get_guid(writer, &wguid) < 0) { + DDS_ERROR("failed to writer guid\n"); + goto err_get_guid; + } + /* determine if the quorum is already satisfied or not */ + if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) { + DDS_ERROR("failed to lock writer [%s]\n", dds_strretcode(ret)); + goto err_writer_lock; + } + tpname = ddsrt_strdup(wr->m_topic->m_name); + old_quorum_reached = wr->quorum_reached; + to_check = ((!wr->quorum_reached) && (wr_appeared)) || ((wr->quorum_reached) && (!wr_appeared)); + dds_writer_unlock (wr); + if (to_check) { + dds_instance_handle_t *rd_ihs; + size_t nrds = 128; + ddsrt_avl_ctree_t data_container_counters; + + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "checking quorum for writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); + ddsrt_avl_cinit(&data_container_cnt_td, &data_container_counters); + /* Check if the quorum for the writer is lost or reached. + * We do this by calling dds_get_matched_subscriptions(). + * This is an expensive call, but it works for now. At least we + * are protected against missing publication_matches() that could have + * occurred before the quorum listener was set on the writer. + * We only do this expensive call when there is a possibility + * that the quorum_reached property of the writer changes. + * Because the call to dds_get_matched_subscriptions() requires + * an preallocated list of reader handles and we don't know the + * size of the list beforehand, we dynamically extend the list + * until it is large enough to hold all handles of matching readers. */ + do { + nrds = nrds * 2; + rd_ihs = ddsrt_malloc(nrds * sizeof(dds_instance_handle_t)); + if ((ret = dds_get_matched_subscriptions(writer, rd_ihs, nrds)) > (int32_t)nrds) { + /* allocated list is too small, use a bigger list */ + ddsrt_free(rd_ihs); + } + } while (ret > (int32_t)nrds); + /* We now have a list of handles to readers that match with the writer. + * Determine if the quorum is reached by verifying if the reader + * is a data container, an counting the matches. */ + if ((ret >= 0) && (dc->cfg.quorum > (uint32_t)ret)) { + /* the number of matches is less than the quorum, so we are sure that + * the quorum cannot be reached. */ + quorum_reached = false; + } else if (ret >= 0) { + /* now walk over all reader handles, lookup the reader, + * and determine if the reader is a remote data container. + * If so, we have detected a matching remote data container and + * we increase the count for this container. */ + for (i=0; i < (uint32_t)ret; i++) { + dds_builtintopic_endpoint_t *ep; + + if ((ep = dds_get_matched_subscription_data(writer, rd_ihs[i])) != NULL) { + if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { + /* the matching endpoint represents a data container. + * Increase the count for this container. */ + uint32_t ep_plen; + char **ep_partitions; + + dds_qget_partition(ep->qos, &ep_plen, &ep_partitions); + assert(ep_plen == 1); /* this is a data container, so it must have a singleton as partition */ + dcc = get_data_container_cnt(&data_container_counters, ep_partitions[0], true); + dcc->cnt++; + dc_free_partitions(ep_plen, ep_partitions); + } + dds_builtintopic_free_endpoint(ep); + } + } + /* Determine if the quorum is reached or not. + * We do this by walking over the partitions of the writer, + * lookup the corresponding data container counter, and determine + * if they meet the quorum. Only if the quorum is met for all + * partitions of the writer, then we are sure that the writer meets + * the quorum condition, and publication can proceed. */ + quorum_reached = true; + for (i=0; i < plen; i++) { + if ((dcc = get_data_container_cnt(&data_container_counters, partitions[i], false)) == NULL) { + /* no data container counter found for this partitions of the writer, so + * quorom not reached */ + quorum_reached = false; + break; + } else if (dcc->cnt < dc->cfg.quorum) { + /* quorom not (yet) reached */ + quorum_reached = false; + break; + } + } + } + if (old_quorum_reached != quorum_reached) { + /* the quorum has changed, update the writer quorum setting */ + if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) { + DDS_ERROR("failed to lock writer [%s]\n", dds_strretcode(ret)); + goto err_writer_lock; + } + wr->quorum_reached = quorum_reached; + dds_writer_unlock (wr); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for writer \"%s\" %s\n", dc_stringify_id(wguid.v, id_str), quorum_reached ? "reached" : "lost"); + } else { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for writer \"%s\" still %sreached\n", dc_stringify_id(wguid.v, id_str), quorum_reached ? "" : "not "); + } + ddsrt_avl_cfree(&data_container_cnt_td, &data_container_counters, cleanup_data_container_cnt); + ddsrt_free(rd_ihs); + } + dc_free_partitions(plen, partitions); + ddsrt_free(tpname); + dds_delete_qos(qos); + return; + +err_writer_lock: +err_get_guid: + dc_free_partitions(plen, partitions); +err_qget_partition: +err_get_qos: + dds_delete_qos(qos); + return; +} /* set up durable client infrastructure */ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, struct ddsi_domaingv *gv) @@ -450,7 +645,7 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc participant reader [%s]\n", dds_strretcode(-com->rd_participant)); goto err_rd_participant; } - /* subinfo reader and listener to detect remote data containers */ + /* subinfo reader to detect remote data containers */ if ((com->rd_subinfo = dds_create_reader(com->participant, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL)) < 0) { DDS_ERROR("failed to create dc subinfo reader [%s]\n", dds_strretcode(-com->rd_subinfo)); goto err_rd_subinfo; @@ -567,7 +762,13 @@ static void dc_com_free (struct com_t *com) return; } -static dds_return_t dc_com_send_request (struct com_t *com, dds_entity_t reader) +static uint64_t next_request_seq (struct dc_t *dc) +{ + (dc->seq)++; + return dc->seq; +} + +static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader) { /* check for publication_matched() on the dc_request writer tomake sure that the request arrives */ /* create a request */ @@ -576,14 +777,51 @@ static dds_return_t dc_com_send_request (struct com_t *com, dds_entity_t reader) /* note: we allow doing a request for volatile readers */ DurableSupport_request *request; + dds_qos_t *rqos; + dds_return_t ret = DDS_RETCODE_OK; + uint32_t plen, i; + char **partitions; + if ((rqos = dds_create_qos()) == NULL) { + DDS_ERROR("Unable to create reader qos for dc_request"); + goto err_alloc_rqos; + } + if ((ret = dds_get_qos(reader, rqos)) != DDS_RETCODE_OK) { + DDS_ERROR("Unable to get reader qos for dc_request"); + goto err_get_qos; + } + if (!dds_qget_partition(rqos, &plen, &partitions)) { + DDS_ERROR("Failed to retrieve partition qos for dc_request"); + goto err_qget_partition; + } request = DurableSupport_request__alloc(); memcpy(request->requestid.client, dc.cfg.id, 16); + request->requestid.seq = next_request_seq(&dc); + request->partitions._length = plen; + request->partitions._maximum = plen; + request->partitions._buffer = dds_sequence_string_allocbuf(plen); + request->partitions._release = true; + for (i=0; i < plen; i++) { + request->partitions._buffer[i] = ddsrt_strdup(partitions[i]); + } + request->timeout = DDS_SECS(5); + /* todo: administrate the request */ + if ((ret = dds_write(com->wr_request, request)) < 0) { + DDS_ERROR("com_set_bead_write failed [%s]", dds_strretcode(-ret)); + goto err_request_write; + } + DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "dc_request sent\n"); +err_request_write: + dc_free_partitions(plen, partitions); + dds_delete_qos(rqos); DurableSupport_request_free(request, DDS_FREE_ALL); + return ret; - (void)com; - (void)reader; - return DDS_RETCODE_OK; +err_qget_partition: +err_get_qos: + dds_delete_qos(rqos); +err_alloc_rqos: + return DDS_RETCODE_ERROR; } static void dc_server_lost (struct dc_t *dc, DurableSupport_status *status) @@ -651,268 +889,12 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } -/* verifies if the user data of the endpoint contains the identifier - * that indicates that this endpoint is a durable container */ -static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *ep, const char *ident) -{ - dds_builtintopic_endpoint_t template; - dds_builtintopic_participant_t *participant; - dds_instance_handle_t ih; - dds_return_t rc; - static void *samples[1]; - static dds_sample_info_t info[1]; - void *userdata; - size_t size = 0; - char id_str[37]; - bool result = false; - - assert(ep); - /* by convention, if the ident == NULL then return true */ - if (ident == NULL) { - return true; - } - /* lookup the instance handle of the builtin participant endpoint that - * contains the participant of the subinfo */ - memcpy(template.key.v,ep->participant_key.v,16); - if ((ih = dds_lookup_instance(com->rd_participant, &template)) == DDS_HANDLE_NIL) { - DDS_ERROR("Failed to lookup the participant of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); - goto err_lookup_instance; - } - if ((rc = dds_read_instance(com->rd_participant, samples, info, 1, 1, ih)) <= 0) { - DDS_ERROR("Failed to read the participant of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); - goto err_read_instance; - } - if (info[0].valid_data) { - participant = (dds_builtintopic_participant_t *)samples[0]; - /* get the user data */ - if (!dds_qget_userdata(participant->qos, &userdata, &size)) { - DDS_ERROR("Unable to retrieve the user data of reader \"%s\"", dc_stringify_id(ep->key.v, id_str)); - goto err_qget_userdata; - } - if ((size != strlen(ident)) || (userdata == NULL) || (strcmp(userdata, ident) != 0)) { - /* the user data of the participant of the durable reader does not contain the ident, - * so the endoint is not from a remote DS */ - result = false; - } else { - /* this endpoint's participant is a ds */ - result = true; - } - dds_free(userdata); - } - return result; - -err_lookup_instance: -err_read_instance: -err_qget_userdata: - return false; -} - -static void dc_free_partitions (uint32_t plen, char **partitions) -{ - uint32_t i; - - if (partitions == NULL) { - return; - } - for (i=0; i < plen; i++) { - ddsrt_free(partitions[i]); - } - ddsrt_free(partitions); -} - -static ddsi_guid_prefix_t dc_ddsi_hton_guid_prefix (ddsi_guid_prefix_t p) -{ - int i; - for (i = 0; i < 3; i++) - p.u[i] = ddsrt_toBE4u (p.u[i]); - return p; -} - -static ddsi_entityid_t dc_ddsi_hton_entityid (ddsi_entityid_t e) -{ - e.u = ddsrt_toBE4u (e.u); - return e; -} - -static ddsi_guid_t dc_ddsi_hton_guid (ddsi_guid_t g) -{ - g.prefix = dc_ddsi_hton_guid_prefix (g.prefix); - g.entityid = dc_ddsi_hton_entityid (g.entityid); - return g; -} - -static void dc_ddsiguid2guid (dds_guid_t *dds_guid, const ddsi_guid_t *ddsi_guid) -{ - ddsi_guid_t tmp; - tmp = dc_ddsi_hton_guid (*ddsi_guid); - memcpy (dds_guid, &tmp, sizeof (*dds_guid)); -} - -static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer, bool new_qe) -{ - dds_qos_t *qos; - dds_writer *wr; - dds_return_t rc; - uint32_t plen, i; - char **partitions; - struct quorum_entry_key_t key; - struct quorum_entry_t *qe; - bool quorum_reached = true; - - assert(writer); - assert(dc); - - qos = dds_create_qos(); - if ((rc = dds_get_qos(writer, qos)) < 0) { - DDS_ERROR("failed to get qos from writer [%s]", dds_strretcode(rc)); - goto err_get_qos; - } - if (!dds_qget_partition(qos, &plen, &partitions)) { - DDS_ERROR("failed to get partitions from qos\n"); - goto err_qget_partition; - } - assert(plen > 0); - if ((rc = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) { - DDS_ERROR("failed to lock writer\n"); - goto err_writer_lock; - } - key.tpname = ddsrt_strdup(wr->m_topic->m_name); - if (((!wr->quorum_reached) && (new_qe)) || ((wr->quorum_reached) && (!new_qe))) { - /* the quorum was not reached and a new quorum entry has been found, or - * the quorum was reached and a quorum entry has been lost - * In both cases check if the quorum still holds */ - for (i=0; i < plen && quorum_reached; i++) { - /* lookup the quorum entry, and determine if a quorum has reached for all relevant data containers */ - key.partition = ddsrt_strdup(partitions[i]); - if ((qe = ddsrt_avl_clookup (&quorum_entry_td, &dc->quorum_entries, &key)) == NULL) { - quorum_reached = false; - } else { - quorum_reached = (qe->cnt >= dc->cfg.quorum); - } - ddsrt_free(key.partition); - } - if (wr->quorum_reached != quorum_reached) { - dds_guid_t guid; - char id_str[37]; - - wr->quorum_reached = quorum_reached; - dc_ddsiguid2guid(&guid, &wr->m_entity.m_guid); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for writer \"%s\" %s\n", dc_stringify_id(guid.v, id_str), quorum_reached ? "reached" : "lost"); - } - } - ddsrt_free(key.tpname); - dds_writer_unlock (wr); -err_writer_lock: - dc_free_partitions(plen, partitions); -err_qget_partition: -err_get_qos: - dds_delete_qos(qos); - return; -} - - - -/* get a quorum counter for the builtin endoint and create a quorum counter for the endpoint */ -static struct quorum_entry_t *dc_get_or_create_quorum_entry (struct dc_t *dc, dds_builtintopic_endpoint_t *ep) -{ - struct quorum_entry_t *qe; - struct quorum_entry_key_t key; - uint32_t plen; - char **partitions; - - if (!dds_qget_partition(ep->qos, &plen, &partitions)) { - DDS_ERROR("failed to get partitions from qos\n"); - goto err_qget_partition; - } - assert(plen == 1); - key.tpname = ddsrt_strdup(ep->topic_name); - key.partition = ddsrt_strdup(partitions[0]); - if ((qe = ddsrt_avl_clookup (&quorum_entry_td, &dc->quorum_entries, &key)) == NULL) { - /* create quorum entry */ - if ((qe = (struct quorum_entry_t *)ddsrt_malloc(sizeof(struct quorum_entry_t))) == NULL) { - DDS_ERROR("failed to allocate quorum entry\n"); - goto err_alloc_quorum_entry; - } - qe->key.partition = ddsrt_strdup(key.partition); - qe->key.tpname = ddsrt_strdup(key.tpname); - qe->cnt = 0; - ddsrt_avl_cinsert(&quorum_entry_td, &dc->quorum_entries, qe); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum entry for \"%s.%s\" created\n", qe->key.partition, qe->key.tpname); - } - ddsrt_free(key.tpname); - ddsrt_free(key.partition); - dc_free_partitions(plen, partitions); - return qe; - -err_alloc_quorum_entry: - ddsrt_free(key.tpname); - ddsrt_free(key.partition); - dc_free_partitions(plen, partitions); -err_qget_partition: - return NULL; -} - -static struct quorum_entry_t *dc_link_handle_to_quorum_entry (struct dc_t *dc, dds_instance_handle_t ih, struct quorum_entry_t *qe) -{ - struct handle_to_quorum_entry_t *hqe; - - assert(qe); - /* link the handle to the quorum entry, so we can lookup the - * quorum entry if the data container identified by the handle - * disappears */ - if ((hqe = (struct handle_to_quorum_entry_t *)ddsrt_malloc(sizeof(struct handle_to_quorum_entry_t))) == NULL) { - DDS_ERROR("failed to allocate handle_to_quorum_entry_t\n"); - goto err_alloc_hqe; - } - hqe->ih = ih; - hqe->qe_ref = qe; - ddsrt_avl_cinsert(&handle_to_quorum_entry_td, &dc->handle_to_quorum_entries, hqe); - qe->cnt++; - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for \"%s.%s\" bumped to %" PRIu32 " (ih %" PRIx64 ")\n", qe->key.partition, qe->key.tpname, qe->cnt, ih); - return qe; - -err_alloc_hqe: - return NULL; -} - -/* Update the quorum entry when a data container leaves. - * Returns a reference to the quorum entry as long as there are still containers, or NULL otherwise */ -static struct quorum_entry_t *dc_unlink_handle_to_quorum_entry (struct dc_t *dc, dds_instance_handle_t ih) -{ - struct handle_to_quorum_entry_t *hqe; - struct quorum_entry_t *qe = NULL; - ddsrt_avl_dpath_t dpath_hqe, dpath_qe; - - /* look up the quorum entry via the instance handle */ - if ((hqe = ddsrt_avl_clookup_dpath (&handle_to_quorum_entry_td, &dc->handle_to_quorum_entries, &ih, &dpath_hqe)) != NULL) { - qe = hqe->qe_ref; - assert(qe); - assert(qe->cnt > 0); - qe->cnt--; - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum for \"%s.%s\" decreased to %" PRIu32 " (ih %" PRIx64 ")\n", qe->key.partition, qe->key.tpname, qe->cnt, ih); - if (qe->cnt == 0) { - /* by unlinking this subscription info, the last reference to the quorum entry is now gone. - * We can now garbage collect the quorum entry itself. */ - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "quorum entry for \"%s.%s\" deleted\n", qe->key.partition, qe->key.tpname); - if (ddsrt_avl_clookup_dpath(&quorum_entry_td, &dc->quorum_entries, &qe->key, &dpath_qe)) { - ddsrt_avl_cdelete_dpath(&quorum_entry_td, &dc->quorum_entries, qe, &dpath_qe); - cleanup_quorum_entry(qe); - qe = NULL; - } - } - ddsrt_avl_cdelete_dpath(&handle_to_quorum_entry_td, &dc->handle_to_quorum_entries, hqe, &dpath_hqe); - cleanup_handle_to_quorum_entry(hqe); - } - return qe; -} - /* called when there is a match for a durable writer */ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publication_matched_status_t status, void *arg) { struct dc_t *dc = (struct dc_t *)arg; dds_instance_handle_t ih; dds_builtintopic_endpoint_t *ep; - struct quorum_entry_t *qe; /* a reader has matched with a durable writer. */ /* check if the reader is a data container. @@ -924,32 +906,16 @@ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publicat } if ((ep = dds_get_matched_subscription_data(writer, ih)) != NULL) { if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { - /* a data container has matched with this writer. - * Increase the quorum counter for this container. - * If no quorum counter existed, then create one. - * Also link the subscription handle to the quorum counter, - * so that we can decrease the quorum counter in case the - * data container does not exist. */ - if ((qe = dc_get_or_create_quorum_entry(dc, ep)) == NULL) { - goto err_inc_or_create_quorum_entry; - } - dc_link_handle_to_quorum_entry(dc, ih, qe); - /* a relevant data container from a durable service for this writer has become available. - * Reevaluate if the quorum has been reached */ + /* A data container has matched with this writer. + * Check if the quorum is met. */ dc_check_quorum_reached(dc, writer, true); } dds_builtintopic_free_endpoint(ep); } else { - /* the endpoint that represents a data container is not available any more. - * decrease the quorum counter for the data container associated with - * the handle. If the quorum counter reaches 0, we'll garbage collect - * the quorum counter entry. */ - qe = dc_unlink_handle_to_quorum_entry(dc, ih); - /* a data container from a durable service has been lost. - * reevaluate if the quorum still holds */ + /* the endpoint is not available any more. + * Check if the quorom has been lost*/ dc_check_quorum_reached(dc, writer, false); } - err_inc_or_create_quorum_entry: err_last_subscription_handle: return; } @@ -961,22 +927,7 @@ static uint32_t recv_handler (void *a) dds_attach_t wsresults[1]; size_t wsresultsize = sizeof(wsresults)/sizeof(wsresults[0]); int n, j; - dds_return_t rc; - if ((dc->quorum_listener = dds_create_listener(dc)) == NULL) { - DDS_ERROR("failed to create quorum listener\n"); - goto err_create_quorum_listener; - } - dds_lset_publication_matched(dc->quorum_listener, default_durable_writer_matched_cb); - if ((dc->subinfo_listener = dds_create_listener(dc)) == NULL) { - DDS_ERROR("failed to create subinfo listener\n"); - goto err_create_subinfo_listener; - } - // dds_lset_data_available(dc->subinfo_listener, default_evaluate_quorum_cb); - if ((rc = dds_set_listener(dc->com->rd_subinfo, dc->subinfo_listener)) < 0) { - DDS_ERROR("Unable to set the subinfo listener\n"); - goto err_set_listener; - } DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "start durable client thread\n"); while (!dds_triggered(dc->com->ws)) { n = dds_waitset_wait_until (dc->com->ws, wsresults, wsresultsize, timeout); @@ -990,19 +941,8 @@ static uint32_t recv_handler (void *a) } } } - dds_delete_listener(dc->subinfo_listener); - dc->subinfo_listener = NULL; - dds_delete_listener(dc->quorum_listener); - dc->quorum_listener = NULL; DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "stop durable client thread\n"); return 0; - -err_set_listener: - dds_delete_listener(dc->subinfo_listener); -err_create_subinfo_listener: - dds_delete_listener(dc->quorum_listener); -err_create_quorum_listener: - return 1; } dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_domaingv *gv) @@ -1026,8 +966,12 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom dc.cfg.quorum = DEFAULT_QOURUM; /* LH: currently hardcoded set to 1, should be made configurable in future */ dc.cfg.ident = ddsrt_strdup(DEFAULT_IDENT); ddsrt_avl_cinit(&server_td, &dc.servers); - ddsrt_avl_cinit(&quorum_entry_td, &dc.quorum_entries); - ddsrt_avl_cinit(&handle_to_quorum_entry_td, &dc.handle_to_quorum_entries); + /* create the quorum listener */ + if ((dc.quorum_listener = dds_create_listener(&dc)) == NULL) { + DDS_ERROR("failed to create quorum listener\n"); + goto err_create_quorum_listener; + } + dds_lset_publication_matched(dc.quorum_listener, default_durable_writer_matched_cb); if ((dc.com = dc_com_new(&dc, domainid, gv))== NULL) { DDS_ERROR("failed to initialize the durable client infrastructure\n"); goto err_com_new; @@ -1042,8 +986,8 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom err_recv_thread: dc_com_free(dc.com); err_com_new: - ddsrt_avl_cfree(&quorum_entry_td, &dc.quorum_entries, cleanup_quorum_entry); - ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); + dds_delete_listener(dc.quorum_listener); +err_create_quorum_listener: return DDS_RETCODE_ERROR; } @@ -1074,8 +1018,6 @@ dds_return_t dds_durability_fini (void) DDS_ERROR("failed to join the dc recv thread [%s]", dds_strretcode(rc)); } dc_com_free(dc.com); - ddsrt_avl_cfree(&handle_to_quorum_entry_td, &dc.handle_to_quorum_entries, cleanup_handle_to_quorum_entry); - ddsrt_avl_cfree(&quorum_entry_td, &dc.quorum_entries, cleanup_quorum_entry); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); } ddsrt_free(dc.cfg.ident); @@ -1093,8 +1035,14 @@ dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rh /* create a durability reader that sucks and stores it in the store */ /* send a request */ - - dc_com_send_request (dc.com, reader); + if (dc.com) { + // dc_send_cached_requests(); + dc_com_request_write(dc.com, reader); + } else { + /* todo: apparently a reader is created before com is initialized. + * cache the request until com becomes available */ + // dc_cache_request(reader, rhc); + } (void)rhc; (void)reader; @@ -1137,7 +1085,7 @@ dds_return_t dds_durability_new_local_writer (dds_entity_t writer) assert(writer); qos = dds_create_qos(); if ((rc = dds_get_qos(writer, qos)) < 0) { - DDS_ERROR("failed to get qos from writer [%s]", dds_strretcode(rc)); + DDS_ERROR("failed to get qos from writer [%s]\n", dds_strretcode(rc)); goto err_get_qos; } if (!dds_qget_durability(qos, &dkind)) { @@ -1159,11 +1107,22 @@ dds_return_t dds_durability_new_local_writer (dds_entity_t writer) DDS_ERROR("failed to retrieve writer guid"); goto err_get_guid; } + /* We now set a quorum listener on the durable writer. + * Each time a matching reader will appear, wewill get notified. + * Existing readers may already have matched before the listener takes effect, + * so these publication_match events may be missed. Luckily, we can request + * all matching readers using dds_get_matched_subscriptions(). + * + * Note: be aware that the same readers can be present in the list provided + * by dds_get_matched_subscriptions(), and can also be triggered by the listener. + * Avoid counting these readers twice! + */ DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "durable writer \"%s\" subject to quorum checking\n", dc_stringify_id(wguid.v, id_str)); if ((rc = dds_set_listener(writer, dc.quorum_listener)) < 0) { DDS_ERROR("Unable to set the quorum listener on writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); goto err_set_listener; } + dc_check_quorum_reached (&dc, writer, true); } dds_delete_qos(qos); return DDS_RETCODE_OK; @@ -1176,65 +1135,6 @@ dds_return_t dds_durability_new_local_writer (dds_entity_t writer) return rc; } -#if 0 -dds_return_t dds_durability_wait_for_quorum (dds_writer *wr) -{ - dds_return_t ret = DDS_RETCODE_ERROR; - ddsrt_mtime_t tnow = ddsrt_time_monotonic (); - ddsrt_mtime_t timeout; - dds_duration_t sleep_duration; - dds_entity_t writer; - - /* This function is called from dds_write() while the writer lock is held. - * To make sure that we temporarily release the writer lock - * while we wait until the quorum has been reached, we need access - * to the entity handle in order to acquire the lock each time - * we recheck.*/ - writer = (dds_entity_t)wr->m_entity.m_hdllink.hdl; - /* No need to check for quorum for non-durable writers */ - if (wr->m_wr->xqos->durability.kind <= DDS_DURABILITY_TRANSIENT_LOCAL) { - ret = DDS_RETCODE_OK; - goto done; - } - timeout = ddsrt_mtime_add_duration (tnow, wr->m_wr->xqos->reliability.max_blocking_time); - /* If the quorum is reached we'll immediately return DDS_RETCODE_OK. - * Note that for volatile and transient-local writers the quorum - * is but definition reached, so this function will always return with - * DDS_RETCODE_OK in those case. */ - if (wr->quorum_reached) { - ret = DDS_RETCODE_OK; - goto done; - } - /* The quorum for a durable writer is not reached. - * We will head bang until the quorum is reached. - * To prevent starvation we use a max 10ms sleep in between. - * If the quorum is reached within the max_blocking_time, - * DDS_RETCODE_OK is returned, otherwise DDS_PRECONDITION_NOT_MET - * is returned. */ - do { - sleep_duration = DDS_MSECS(10); - dds_writer_unlock(wr); - dds_sleepfor (sleep_duration); - if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) { - goto err_writer_lock; - } - tnow = ddsrt_time_monotonic (); - if (tnow.v >= timeout.v) { - ret = DDS_RETCODE_PRECONDITION_NOT_MET; - break; - } - if (wr->quorum_reached) { - ret = DDS_RETCODE_OK; - break; - } - } while (true); -done: - dds_writer_unlock(wr); -err_writer_lock: - return ret; -} -#endif - /* Retrieve the quorum_reached value from the dds_writer that corresponds to the writer entity */ static dds_return_t dds_durability_get_quorum_reached (dds_entity_t writer, bool *quorum_reached, ddsrt_mtime_t *timeout) { @@ -1251,13 +1151,14 @@ static dds_return_t dds_durability_get_quorum_reached (dds_entity_t writer, bool tnow = ddsrt_time_monotonic (); *timeout = ddsrt_mtime_add_duration (tnow,wr->m_wr->xqos->reliability.max_blocking_time); } - /* retrieve quorum reached */ - *quorum_reached = wr->quorum_reached; + /* retrieve quorum reached; by default true if quorum is 0 */ + *quorum_reached = wr->quorum_reached | (dc.cfg.quorum == 0); dds_writer_unlock(wr); err_writer_lock: return ret; } +/* wait for quorum reached, or timeout in case max_blocking_time is expired and quorum not yet reached */ dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) { dds_return_t ret = DDS_RETCODE_ERROR; @@ -1272,7 +1173,11 @@ dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) * When the quorum is reached within the max_blocking_time, * DDS_RETCODE_OK is returned, otherwise DDS_PRECONDITION_NOT_MET * is returned. The max_blocking_time itself is retrieved lazily - * on the first call to dds_durability_get_quorum_reached(). */ + * on the first call to dds_durability_get_quorum_reached(). + * + * LH: A better solution would be to wait on a condition variable, + * and get notified once the quorum is reached (or the max_blocking_time + * times out) */ timeout.v = DDS_TIME_INVALID; do { if ((ret = dds_durability_get_quorum_reached(writer, &quorum_reached, &timeout)) != DDS_RETCODE_OK) { @@ -1293,3 +1198,9 @@ dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) return ret; } +/* get the configured quorum */ +uint32_t dds_durability_get_quorum (void) +{ + return dc.cfg.quorum; +} + From 7652c5afdee164a4165fc7c97ca9d8671a08679d Mon Sep 17 00:00:00 2001 From: Michel van den Hoek Date: Tue, 24 Oct 2023 13:17:27 +0200 Subject: [PATCH 182/207] fix sanitizer error due to double free Signed-off-by: Michel van den Hoek --- src/durability/src/dds_durability.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 321cdc1fce..3a66752f94 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -988,6 +988,7 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom err_com_new: dds_delete_listener(dc.quorum_listener); err_create_quorum_listener: + ddsrt_free(dc.cfg.ident); return DDS_RETCODE_ERROR; } @@ -1019,8 +1020,8 @@ dds_return_t dds_durability_fini (void) } dc_com_free(dc.com); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); + ddsrt_free(dc.cfg.ident); } - ddsrt_free(dc.cfg.ident); return DDS_RETCODE_OK; } From 12216faca9064edf2f849c2648b363dbb0b65d6c Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 3 Nov 2023 12:32:41 +0100 Subject: [PATCH 183/207] Publish dc_request when a durable reader is created Signed-off-by: TheFixer --- src/core/ddsc/src/dds_reader.c | 9 +- .../include/dds/durability/dds_durability.h | 4 +- src/durability/src/dds_durability.c | 447 +++++++++++++++--- 3 files changed, 395 insertions(+), 65 deletions(-) diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index ee5aa4f43f..9cb4cdfb41 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -702,6 +702,11 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe } #endif +#ifdef DDS_HAS_DURABILITY + dds_durability_kind_t dkind; + dds_qget_durability(rqos, &dkind); +#endif + /* Create reader and associated read cache (if not provided by caller) */ struct dds_reader * const rd = dds_alloc (sizeof (*rd)); const dds_entity_t reader = dds_entity_init (&rd->m_entity, &sub->m_entity, DDS_KIND_READER, false, true, rqos, listener, DDS_READER_STATUS_MASK); @@ -795,7 +800,9 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe dds_subscriber_unlock (sub); #ifdef DDS_HAS_DURABILITY - dds_durability_new_local_reader(reader, rhc); + if (dkind >= DDS_DURABILITY_TRANSIENT) { + dds_durability_new_local_reader(reader, rhc); + } #endif return reader; diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h index 37294cd825..0be8256392 100644 --- a/src/durability/include/dds/durability/dds_durability.h +++ b/src/durability/include/dds/durability/dds_durability.h @@ -17,6 +17,9 @@ #include "dds__types.h" #include "dds/ddsc/dds_rhc.h" +/* This is the user data that identifies a durable service */ +#define IDENT "durable_support" + #if defined (__cplusplus) extern "C" { #endif @@ -31,7 +34,6 @@ uint32_t dds_durability_get_quorum (void); dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc); dds_return_t dds_durability_new_local_writer (dds_entity_t writer); dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer); -dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer); bool dds_durability_is_terminating (void); diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 3a66752f94..015ac13187 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -61,6 +61,69 @@ static void cleanup_server (void *n) static const ddsrt_avl_ctreedef_t server_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct server_t, node), offsetof (struct server_t, id), cmp_server, 0); +/* This represents a request for historical data. */ +struct pending_request_t { + ddsrt_avl_node_t node; /* represents a node in the tree of pending requests */ + ddsrt_fibheap_node_t fhnode; /* represents a node in the priority queue */ + dds_instance_handle_t ih; /* the instance handle that represents the reader */ + uint64_t seq; /* the sequence number of the request; this is used as the key */ + dds_entity_t reader; /* the reader that does the request */ + struct dds_rhc *rhc; /* reader rhc */ + dds_duration_t exptime; /* expiry time for this pending request */ +}; + +static int cmp_pending_request (const void *a, const void *b) +{ + uint64_t *s1 = (uint64_t *)a; + uint64_t *s2 = (uint64_t *)b; + + return (*s1 < *s2) ? -1 : ((*s1 > *s2) ? 1 : 0); +} + +static void cleanup_pending_request (void *n) +{ + struct pending_request_t *pr = (struct pending_request_t *)n; + ddsrt_free(pr); +} + +static int cmp_exp_time (const void *a, const void *b) +{ + struct pending_request_t *pr1 = (struct pending_request_t *)a; + struct pending_request_t *pr2 = (struct pending_request_t *)b; + + return (pr1->exptime < pr2->exptime) ? -1 : ((pr1->exptime > pr2->exptime) ? 1 : 0); +} + +static const ddsrt_avl_ctreedef_t pending_requests_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct pending_request_t, node), offsetof (struct pending_request_t, seq), cmp_pending_request, 0); + +static const ddsrt_fibheap_def_t pending_requests_fd = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct pending_request_t, fhnode), cmp_exp_time); + +/* Administration to keep track of the request readers of a ds + * that can act as a target to send requests for historical data to.. + * Based on this administration requests for historical data are published immediately, + * or pending until a ds is found that matches. */ + +struct matched_request_reader_t { + ddsrt_avl_node_t node; + dds_instance_handle_t ih; /* the instance handle of the matched request reader for my own request writer */ +}; + +static int cmp_matched_request_reader (const void *a, const void *b) +{ + dds_instance_handle_t *ih1 = (dds_instance_handle_t *)a; + dds_instance_handle_t *ih2 = (dds_instance_handle_t *)b; + + return (*ih1 < *ih2) ? -1 : ((*ih1 > *ih2) ? 1 : 0); +} + +static void cleanup_matched_request_reader (void *n) +{ + struct matched_request_reader_t *mrr = (struct matched_request_reader_t *)n; + ddsrt_free(mrr); +} + +static const ddsrt_avl_ctreedef_t matched_request_readers_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct matched_request_reader_t, node), offsetof (struct matched_request_reader_t, ih), cmp_matched_request_reader, 0); + struct com_t { dds_entity_t participant; /* durable client participant */ dds_entity_t status_subscriber; /* subscriber used to receive status messages */ @@ -93,7 +156,7 @@ struct com_t { struct dc_t { struct { DurableSupport_id_t id; /* the id of this client */ - char id_str[37]; /* string representation of the service id */ + char id_str[37]; /* string representation of the client id */ char *request_partition; /* partition to send requests too; by default same as */ uint32_t quorum; /*quorum of durable services needed to unblock durable writers */ char *ident; /* ds identification */ @@ -111,8 +174,12 @@ struct dc_t { ddsrt_avl_ctree_t servers; /* tree containing all discovered durable servers */ dds_listener_t *subinfo_listener; /* listener to detect remote containers */ dds_listener_t *quorum_listener; /* listener to check if a quorum is reached */ - ddsrt_avl_ctree_t quorum_entries; /* tree containing quora for all discovered data containers */ - ddsrt_avl_ctree_t handle_to_quorum_entries; /* tree that maps subscription handles to references to quorum entries */ + dds_listener_t *request_listener; /* listener to check if request reader is available */ + ddsrt_avl_ctree_t pending_requests; /* tree containing pending requests */ + ddsrt_fibheap_t pending_requests_fh; /* priority queue for pending requests, prioritized by expiry time */ + dds_instance_handle_t selected_request_reader_ih; /* instance handle to matched request reader, DDS_HANDLE_NIL if not available */ + ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on a ds that match with my ds writer */ + uint32_t nr_of_matched_dc_requests; /* indicates the number of matched dc_request readers for the dc_request writer of this client */ }; static struct dc_t dc = { 0 }; /* static durable client structure */ @@ -302,8 +369,8 @@ static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *e dds_builtintopic_participant_t *participant; dds_instance_handle_t ih; dds_return_t rc; - static void *samples[1]; - static dds_sample_info_t info[1]; + void *samples[1] = { NULL }; + dds_sample_info_t info[1]; void *userdata; size_t size = 0; char id_str[37]; @@ -342,10 +409,12 @@ static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *e } dds_free(userdata); } + (void)dds_return_loan (com->rd_participant, samples, rc); return result; err_lookup_instance: err_read_instance: + (void)dds_return_loan (com->rd_participant, samples, rc); err_qget_userdata: return false; } @@ -576,7 +645,10 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc status read condition [%s]\n", dds_strretcode(-com->rc_status)); goto err_rc_status; } - /* create dc_request writer */ + /* create dc_request writer + * The dc_request topic is a transient-local topic, which ensures that + * a late joining DS can still get a request provided it has not not + * expired. */ if (create_request_partition_expression(com, &request_partition) < 0) { DDS_ERROR("failed to create dc request partition\n"); goto err_request_partition; @@ -592,8 +664,9 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("Failed to create dc publisher for request topic [%s]\n", dds_strretcode(-com->request_publisher)); goto err_request_publisher; } - dds_qset_durability(tqos, DDS_DURABILITY_VOLATILE); - dds_qset_history(tqos, DDS_HISTORY_KEEP_ALL, DDS_LENGTH_UNLIMITED); + /* create dc_request writer */ + dds_qset_durability(tqos, DDS_DURABILITY_TRANSIENT_LOCAL); + dds_qset_history(tqos, DDS_HISTORY_KEEP_LAST, 1); if ((com->tp_request = dds_create_topic (com->participant, &DurableSupport_request_desc, "dc_request", tqos, NULL)) < 0) { DDS_ERROR("failed to create the dc request topic [%s]\n", dds_strretcode(-com->tp_request)); goto err_tp_request; @@ -606,6 +679,18 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to copy dc request topic qos [%s]\n", dds_strretcode(-ret)); goto err_copy_request_wqos; } + /* The writer data lifecycle of a dc_request writer has an + * autodispose policy. This makes it possible to cancel requests + * when the client disconnects from the DS. */ + dds_qset_writer_data_lifecycle(request_wqos, true); + /* if we attach the request_listener now to the request writer here, then it + * is that possible the function triggers before this com_new() function + * has been finished. Because the request listener callback requires + * the com to be initialized (in the dc_is_ds_endpoint() call) this would + * then lead to a crash. For that reason we cannot attach the request listener + * to wr_request here, but we have to do it after com has been initialized + * (in activate_request_listener()). To not miss out on any triggers, we need to + * call dds_get_matched_subscription_data() after com has been initialized */ if ((com->wr_request = dds_create_writer(com->request_publisher, com->tp_request, request_wqos, NULL)) < 0) { DDS_ERROR("failed to create dc request writer [%s]\n", dds_strretcode(-com->wr_request)); goto err_wr_request; @@ -762,15 +847,9 @@ static void dc_com_free (struct com_t *com) return; } -static uint64_t next_request_seq (struct dc_t *dc) +static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader, uint64_t seq) { - (dc->seq)++; - return dc->seq; -} - -static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader) -{ - /* check for publication_matched() on the dc_request writer tomake sure that the request arrives */ + /* check for publication_matched() on the dc_request writer to make sure that the request arrives */ /* create a request */ /* set the request on the pending liust */ /* send the request */ @@ -796,7 +875,7 @@ static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader } request = DurableSupport_request__alloc(); memcpy(request->requestid.client, dc.cfg.id, 16); - request->requestid.seq = next_request_seq(&dc); + request->requestid.seq = seq; request->partitions._length = plen; request->partitions._maximum = plen; request->partitions._buffer = dds_sequence_string_allocbuf(plen); @@ -805,12 +884,11 @@ static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader request->partitions._buffer[i] = ddsrt_strdup(partitions[i]); } request->timeout = DDS_SECS(5); - /* todo: administrate the request */ if ((ret = dds_write(com->wr_request, request)) < 0) { - DDS_ERROR("com_set_bead_write failed [%s]", dds_strretcode(-ret)); + DDS_ERROR("failed to publish dc_request [%s]", dds_strretcode(-ret)); goto err_request_write; } - DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "dc_request sent\n"); + DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "publish dc_request {\"client\":\"%s\", \"seq\":%" PRIu64 "}\n", dc.cfg.id_str, seq); err_request_write: dc_free_partitions(plen, partitions); dds_delete_qos(rqos); @@ -859,14 +937,18 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) { #define MAX_SAMPLES 100 - static void *samples[MAX_SAMPLES]; - static dds_sample_info_t info[MAX_SAMPLES]; + void *samples[MAX_SAMPLES] = { NULL }; + dds_sample_info_t info[MAX_SAMPLES]; int samplecount; int j; + /* dds_read/take allocates memory for the data if samples[0] is a null pointer. + * The memory must be released when done by returning the loan */ + samples[0]= NULL; samplecount = dds_take_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE); if (samplecount < 0) { DDS_ERROR("durable client failed to take ds_status [%s]", dds_strretcode(-samplecount)); + goto err_samplecount; } else { /* call the handler function to process the status sample */ for (j = 0; !dds_triggered(dc->com->ws) && j < samplecount; j++) { @@ -885,6 +967,8 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) } } } + (void)dds_return_loan (rd, samples, samplecount); +err_samplecount: return samplecount; #undef MAX_SAMPLES } @@ -913,13 +997,129 @@ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publicat dds_builtintopic_free_endpoint(ep); } else { /* the endpoint is not available any more. - * Check if the quorom has been lost*/ + * Check if the quorem has been lost */ dc_check_quorum_reached(dc, writer, false); } err_last_subscription_handle: return; } +/* publish a reader request + * The reader request is published as a transient-local topic which is + * keyed by the guid of this client and a monotonically increasing sequence number. + * Even though this is not recommended, this allows multiple requests from the + * same reader (because they have a different sequence number). + * + * For each outgoing request, a pending request entry will be created to administrate + * the outgoing requests. Pending requests can have a expiration. Expired pending + * requests will lead to removal of the pending request, and a dispose of the + * corresponding reader request to prevent that late joining + */ +static struct pending_request_t *dc_publish_reader_request (struct dc_t *dc, dds_entity_t reader, struct dds_rhc *rhc) +{ + struct pending_request_t *pr; + dds_instance_handle_t ih; + dds_return_t rc; + + /* verify if the reader still exists; if not, delete the request */ + if ((rc = dds_get_instance_handle(reader, &ih)) != DDS_RETCODE_OK) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "No need to publish dc_request, reader is not available\n"); + return NULL; + } + /* create a pending request entry and insert it in the table of pending requests */ + if ((pr = (struct pending_request_t *)ddsrt_malloc(sizeof(struct pending_request_t))) == NULL) { + DDS_ERROR("Failed to allocate a reader request\n"); + goto err_alloc_reader_request; + } + memset(pr, 0, sizeof(struct pending_request_t)); + pr->ih = ih; + pr->seq = ++(dc->seq); + pr->reader = reader; + pr->rhc = rhc; + ddsrt_avl_cinsert(&pending_requests_td, &dc->pending_requests, pr); + /* publish the request */ + if ((rc = dc_com_request_write(dc->com, reader, dc->seq)) != DDS_RETCODE_OK) { + DDS_ERROR("Failed to publish dc_request\n"); + goto err_publish_reader_request; + } + return pr; + +err_publish_reader_request: + ddsrt_avl_cdelete(&pending_requests_td, &dc->pending_requests, pr); + cleanup_pending_request(pr); + --(dc->seq); +err_alloc_reader_request: + return NULL; +} + +/* a dc_request reader endpoint on a DS has been found that matched with my dc_request writer */ +static struct matched_request_reader_t *dc_add_matched_request_reader (struct dc_t *dc, dds_builtintopic_endpoint_t *ep, dds_instance_handle_t ih) +{ + struct matched_request_reader_t *mrr; + uint32_t cnt; + char id_str[37]; + + assert(ep); + if ((mrr = ddsrt_avl_clookup (&matched_request_readers_td, &dc->matched_request_readers, &ih)) == NULL) { + mrr = (struct matched_request_reader_t *)ddsrt_malloc(sizeof(struct matched_request_reader_t)); + mrr->ih = ih; + ddsrt_avl_cinsert(&matched_request_readers_td, &dc->matched_request_readers, mrr); + cnt = (uint32_t)ddsrt_avl_ccount(&dc->matched_request_readers); + dc->nr_of_matched_dc_requests = cnt; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "matching dc_request reader \"%s\" discovered (ih: %" PRIx64 ") [%" PRIu32 "]\n", dc_stringify_id(ep->key.v, id_str), ih, cnt); + } + return mrr; +} + +/* a dc_request reader has been lost */ +static void dc_remove_matched_request_reader (struct dc_t *dc, dds_instance_handle_t ih) +{ + struct matched_request_reader_t *mrr; + ddsrt_avl_dpath_t dpath; + uint32_t cnt; + + if ((mrr = ddsrt_avl_clookup_dpath(&matched_request_readers_td, &dc->matched_request_readers, &ih, &dpath)) != NULL) { + ddsrt_avl_cdelete_dpath(&matched_request_readers_td, &dc->matched_request_readers, mrr, &dpath); + cleanup_matched_request_reader(mrr); + cnt = (uint32_t)ddsrt_avl_ccount(&dc->matched_request_readers); + dc->nr_of_matched_dc_requests = cnt; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "matching dc_request reader lost (ih: %" PRIx64 ") [%" PRIu32 "]\n", ih, cnt); + } +} + +/* called when the dc_request writer has been found or lost a matching dc_request reader. + * Due to synchronous triggering we see them all */ +static void default_request_writer_matched_cb (dds_entity_t writer, dds_publication_matched_status_t status, void *arg) +{ + struct dc_t *dc = (struct dc_t *)arg; + dds_instance_handle_t ih; + dds_builtintopic_endpoint_t *ep; + + /* A reader has matched (or lost) with a dc_request writer. */ + /* As long as there is at least one match with a dc_request + * reader located on a ds, we can publish safely publish + * requests. If there is no match with such dc_request reader, + * we have to postpone the publication of dc_request until such + * dc_request reader becomes available. */ + assert(writer); + if ((ih = status.last_subscription_handle) == DDS_HANDLE_NIL) { + DDS_ERROR("failed to receive valid last_subscription_handle\n"); + return; + } + if ((ep = dds_get_matched_subscription_data(writer, ih)) != NULL) { + if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { + /* A dc_request reader on a data container has matched with the dc_request writer. + * From now on it is allowed to publish requests. + * In case there are any pending requests, we can sent them now */ + dc_add_matched_request_reader(dc, ep, ih); + } + dds_builtintopic_free_endpoint(ep); + } else { + /* the dc_request endpoint is not available any more. */ + dc_remove_matched_request_reader(dc, ih); + } +} + static uint32_t recv_handler (void *a) { struct dc_t *dc = (struct dc_t *)a; @@ -945,6 +1145,70 @@ static uint32_t recv_handler (void *a) return 0; } +/* set the request listener to learn about the existence of matching request readers. + * Because matches may have occurred already before */ + +static dds_return_t activate_request_listener (struct dc_t *dc) +{ + dds_return_t rc, ret; + dds_guid_t wguid; + char id_str[37]; + size_t nrds = 128; + dds_instance_handle_t *rd_ihs; + int i; + dds_builtintopic_endpoint_t *ep; + bool selected = false; /* indicates if a dc_request reader is selected to accept our requests */ + + assert(dc); + assert(dc->com); + if ((rc = dds_get_guid(dc->com->wr_request, &wguid)) != DDS_RETCODE_OK) { + DDS_ERROR("failed to retrieve writer guid for request writer"); + goto err_get_guid; + } + if ((rc = dds_set_listener(dc->com->wr_request, dc->request_listener)) < 0) { + DDS_ERROR("Unable to set the request listener on writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); + goto err_set_listener; + } + /* matches for this listener may have occurred before the listener was attached. + * To get these matches, we need to call dds_get_matched_subscriptions(). + * We don't know the size of the array holding the matches beforehand, so + * we dynamically this list. */ + do { + nrds = nrds * 2; + rd_ihs = ddsrt_malloc(nrds * sizeof(dds_instance_handle_t)); + if ((ret = dds_get_matched_subscriptions(dc->com->wr_request, rd_ihs, nrds)) > (int32_t)nrds) { + /* allocated list is too small, use a bigger list */ + ddsrt_free(rd_ihs); + } + } while (ret > (int32_t)nrds); + /* The local host request reader only match requests with a ds on the same host. + * As long as there is at least one match, then we know there is a dc_request reader + * on the local node. If the dc_request reader belongs to a ds, then we have found + * a ds on the local node. */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "request listener activated, currently found %" PRIu32 " matching dc_request readers\n", (uint32_t)ret); + for (i=0; i < ret && !selected; i++) { + /* check if the matched reader belongs to a ds */ + if ((ep = dds_get_matched_subscription_data(dc->com->wr_request, rd_ihs[i])) != NULL) { + if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { + /* A dc_request reader on a DS has matched with the dc_request writer. + * From now on it is allowed to publish requests. + * In case there are any pending requests, we can sent them now */ + dc_add_matched_request_reader(dc, ep, rd_ihs[i]); + } + dds_builtintopic_free_endpoint(ep); + } else { + /* the dc_request endpoint is not available any more. */ + dc_remove_matched_request_reader(dc, rd_ihs[i]); + } + } + ddsrt_free(rd_ihs); + return rc; + +err_set_listener: +err_get_guid: + return DDS_RETCODE_ERROR; +} + dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_domaingv *gv) { dds_return_t rc; @@ -965,17 +1229,29 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom /* Note: dc.cfg.id will be set once we create the participant in dc_com_new() */ dc.cfg.quorum = DEFAULT_QOURUM; /* LH: currently hardcoded set to 1, should be made configurable in future */ dc.cfg.ident = ddsrt_strdup(DEFAULT_IDENT); + dc.selected_request_reader_ih = DDS_HANDLE_NIL; + dc.nr_of_matched_dc_requests = 0; ddsrt_avl_cinit(&server_td, &dc.servers); + ddsrt_avl_cinit(&pending_requests_td, &dc.pending_requests); + ddsrt_avl_cinit(&matched_request_readers_td, &dc.matched_request_readers); + ddsrt_fibheap_init(&pending_requests_fd, &dc.pending_requests_fh); /* create the quorum listener */ if ((dc.quorum_listener = dds_create_listener(&dc)) == NULL) { DDS_ERROR("failed to create quorum listener\n"); goto err_create_quorum_listener; } dds_lset_publication_matched(dc.quorum_listener, default_durable_writer_matched_cb); + /* create the request listener */ + if ((dc.request_listener = dds_create_listener(&dc)) == NULL) { + DDS_ERROR("failed to create request listener\n"); + goto err_create_request_listener; + } + dds_lset_publication_matched(dc.request_listener, default_request_writer_matched_cb); if ((dc.com = dc_com_new(&dc, domainid, gv))== NULL) { DDS_ERROR("failed to initialize the durable client infrastructure\n"); goto err_com_new; } + activate_request_listener(&dc); /* start a thread to process messages coming from a ds */ ddsrt_threadattr_init(&dc.recv_tattr); if ((rc = ddsrt_thread_create(&dc.recv_tid, "dc", &dc.recv_tattr, recv_handler, &dc)) != DDS_RETCODE_OK) { @@ -986,6 +1262,8 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom err_recv_thread: dc_com_free(dc.com); err_com_new: + dds_delete_listener(dc.request_listener); +err_create_request_listener: dds_delete_listener(dc.quorum_listener); err_create_quorum_listener: ddsrt_free(dc.cfg.ident); @@ -1018,7 +1296,11 @@ dds_return_t dds_durability_fini (void) if ((rc = ddsrt_thread_join(dc.recv_tid, NULL)) < 0) { DDS_ERROR("failed to join the dc recv thread [%s]", dds_strretcode(rc)); } + dds_delete_listener(dc.request_listener); + dds_delete_listener(dc.quorum_listener); dc_com_free(dc.com); + ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); + ddsrt_avl_cfree(&pending_requests_td, &dc.pending_requests, cleanup_pending_request); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); ddsrt_free(dc.cfg.ident); } @@ -1032,46 +1314,72 @@ bool dds_durability_is_terminating (void) dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc) { - /* create the administration to store transient data */ - /* create a durability reader that sucks and stores it in the store */ + dds_durability_kind_t dkind; + dds_qos_t *qos, *parqos; + dds_return_t rc = DDS_RETCODE_ERROR; - /* send a request */ - if (dc.com) { - // dc_send_cached_requests(); - dc_com_request_write(dc.com, reader); - } else { - /* todo: apparently a reader is created before com is initialized. - * cache the request until com becomes available */ - // dc_cache_request(reader, rhc); + /* check if the reader is a durable reader from a "real" user application, + * if so, send a request to obtain historical data */ + assert(reader); + qos = dds_create_qos(); + if ((rc = dds_get_qos(reader, qos)) < 0) { + DDS_ERROR("failed to get qos from reader [%s]\n", dds_strretcode(rc)); + goto err_get_qos; } + if (!dds_qget_durability(qos, &dkind)) { + DDS_ERROR("failed to retrieve durability qos\n"); + goto err_qget_durability; + } + if ((dkind == DDS_DURABILITY_TRANSIENT) || (dkind == DDS_DURABILITY_PERSISTENT)) { + dds_entity_t par; + void *userdata; + size_t size = 0; + + /* Creation of a durable reader must only lead to the publication + * of a dc_request when the reader is a "real" application reader. + * If the reader belongs to a participant that carries user data + * containing the IDENT, then the reader is a data container. + * We don't need to generate dc_requests for data containers */ + if ((par = dds_get_participant(reader)) < 0) { + DDS_ERROR("Unable to retrieve the participant of the reader [%s]\n", dds_strretcode(rc)); + goto err_get_participant; + } + if ((parqos = dds_create_qos()) == NULL) { + DDS_ERROR("Failed to allocate qos\n"); + goto err_alloc_parqos; + } + if ((rc = dds_get_qos(par, parqos)) < 0) { + DDS_ERROR("Failed to get topic qos [%s]", dds_strretcode(rc)); + goto err_get_parqos; + } + if (!dds_qget_userdata(parqos, &userdata, &size)) { + DDS_ERROR("Unable to retrieve the participant's user data for reader\n"); + goto err_qget_userdata; + } + if ((size != strlen(IDENT)) || (userdata == NULL) || (strcmp(userdata, IDENT) != 0)) { + /* the user data of the participant for this durable reader does + * not contain the ident, so the endoint is not from a remote DS. + * We can now publish a dc_request for this durable reader. The + * dc_request is published as a transient-local topic. This means + * that a late joining DS will receive the DS as long as the request + * is not yet disposed.*/ + (void)dc_publish_reader_request(&dc, reader, rhc); + } + dds_free(userdata); + dds_delete_qos(parqos); + } + dds_delete_qos(qos); + return rc; - (void)rhc; - (void)reader; - return DDS_RETCODE_OK;; -} - -/* This function checks if the writer has reached the quorum of matching durable containers - * - * It is NOT sufficient to verify if the quorum of durable services is reached. - * If a writer would unblock when the quorum of durable services is reached, then - * it is by no means certain that the durable writer has discovered the corresponding - * data containers of these durable services. Data that has is published before the - * data containers have been discovered by the writers, would not be delivered to - * the data containers. - * - * For this reason, the quorum must be calculated based on the number of discovered - * data containers for a writer. This also implies that if a writer has reached a quorum, - * some other writer may not have reached the quorum yet. - * - * return - * DDS_RETCODE_OK if quorum is reached - * DDS_PRECONDITION_NOT_MET otherwise - */ -dds_return_t dds_durability_check_quorum_reached (struct dds_writer *writer) -{ - /* temporarily disabled */ - (void)writer; - return DDS_RETCODE_OK; +err_qget_userdata: +err_get_parqos: + dds_delete_qos(parqos); +err_alloc_parqos: +err_get_participant: +err_qget_durability: +err_get_qos: + dds_delete_qos(qos); + return rc; } dds_return_t dds_durability_new_local_writer (dds_entity_t writer) @@ -1123,7 +1431,7 @@ dds_return_t dds_durability_new_local_writer (dds_entity_t writer) DDS_ERROR("Unable to set the quorum listener on writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); goto err_set_listener; } - dc_check_quorum_reached (&dc, writer, true); + dc_check_quorum_reached(&dc, writer, true); } dds_delete_qos(qos); return DDS_RETCODE_OK; @@ -1159,7 +1467,20 @@ static dds_return_t dds_durability_get_quorum_reached (dds_entity_t writer, bool return ret; } -/* wait for quorum reached, or timeout in case max_blocking_time is expired and quorum not yet reached */ +/* This function waits for a quorum of durable data containers to be available, + * or timeout in case max_blocking_time is expired and quorum not yet reached. + * + * If the quorum is not reached before the max_blocking_time() is expired, + * DDS_RETCODE_PRECONDITION + * + * The quorum is calculated based on the number of discovered and matched data containers + * for a writer. This also implies that if a writer has reached a quorum, + * some other writer may not have reached the quorum yet. + * + * return + * DDS_RETCODE_OK if quorum is reached + * DDS_PRECONDITION_NOT_MET otherwise + */ dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) { dds_return_t ret = DDS_RETCODE_ERROR; @@ -1178,7 +1499,7 @@ dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) * * LH: A better solution would be to wait on a condition variable, * and get notified once the quorum is reached (or the max_blocking_time - * times out) */ + * times out) */ timeout.v = DDS_TIME_INVALID; do { if ((ret = dds_durability_get_quorum_reached(writer, &quorum_reached, &timeout)) != DDS_RETCODE_OK) { From 7df91d946117fd092537f4825ac645fa5de7975c Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 7 Nov 2023 12:21:29 +0100 Subject: [PATCH 184/207] Make dc_requests transient-local and autodispose, and add the ability dispose requests after a timeout expires Signed-off-by: TheFixer --- .../include/dds/durability/dds_durability.h | 3 - src/durability/src/dds_durability.c | 168 ++++++++++++++++-- 2 files changed, 154 insertions(+), 17 deletions(-) diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h index 0be8256392..83e9033478 100644 --- a/src/durability/include/dds/durability/dds_durability.h +++ b/src/durability/include/dds/durability/dds_durability.h @@ -17,9 +17,6 @@ #include "dds__types.h" #include "dds/ddsc/dds_rhc.h" -/* This is the user data that identifies a durable service */ -#define IDENT "durable_support" - #if defined (__cplusplus) extern "C" { #endif diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 015ac13187..94bcced310 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -67,9 +67,10 @@ struct pending_request_t { ddsrt_fibheap_node_t fhnode; /* represents a node in the priority queue */ dds_instance_handle_t ih; /* the instance handle that represents the reader */ uint64_t seq; /* the sequence number of the request; this is used as the key */ + dds_time_t birth_time; /* time this pending event was created */ dds_entity_t reader; /* the reader that does the request */ struct dds_rhc *rhc; /* reader rhc */ - dds_duration_t exptime; /* expiry time for this pending request */ + dds_time_t exp_time; /* Expire time for this pending request */ }; static int cmp_pending_request (const void *a, const void *b) @@ -91,7 +92,7 @@ static int cmp_exp_time (const void *a, const void *b) struct pending_request_t *pr1 = (struct pending_request_t *)a; struct pending_request_t *pr2 = (struct pending_request_t *)b; - return (pr1->exptime < pr2->exptime) ? -1 : ((pr1->exptime > pr2->exptime) ? 1 : 0); + return (pr1->exp_time < pr2->exp_time) ? -1 : ((pr1->exp_time > pr2->exp_time) ? 1 : 0); } static const ddsrt_avl_ctreedef_t pending_requests_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct pending_request_t, node), offsetof (struct pending_request_t, seq), cmp_pending_request, 0); @@ -140,6 +141,7 @@ struct com_t { dds_entity_t rd_participant; /* participant reader */ dds_entity_t rd_subinfo; /* DCPSSubscription reader */ dds_entity_t rc_subinfo; /* DCPSSubscription read condition */ + dds_entity_t pending_request_guard; /* trigger expiration of pending request */ dds_listener_t *status_listener; /* listener on status topic */ dds_entity_t ws; }; @@ -177,6 +179,8 @@ struct dc_t { dds_listener_t *request_listener; /* listener to check if request reader is available */ ddsrt_avl_ctree_t pending_requests; /* tree containing pending requests */ ddsrt_fibheap_t pending_requests_fh; /* priority queue for pending requests, prioritized by expiry time */ + ddsrt_mutex_t pending_request_mutex; /* pending request queue mutex */ + ddsrt_cond_t pending_request_cond; /* pending request condition */ dds_instance_handle_t selected_request_reader_ih; /* instance handle to matched request reader, DDS_HANDLE_NIL if not available */ ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on a ds that match with my ds writer */ uint32_t nr_of_matched_dc_requests; /* indicates the number of matched dc_request readers for the dc_request writer of this client */ @@ -371,7 +375,7 @@ static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *e dds_return_t rc; void *samples[1] = { NULL }; dds_sample_info_t info[1]; - void *userdata; + void *userdata = NULL; size_t size = 0; char id_str[37]; bool result = false; @@ -739,11 +743,24 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc subinfo read condition [%s]\n", dds_strretcode(-com->rc_subinfo)); goto err_rc_subinfo; } + /* create pending reuqest guard condition */ + if ((com->pending_request_guard = dds_create_guardcondition(com->participant)) < 0) { + DDS_ERROR("failed to create guard condition [%s]\n", dds_strretcode(-com->pending_request_guard)); + goto err_create_pending_request_guard_condition; + } + if ((ret = dds_set_guardcondition(com->pending_request_guard, false)) < 0) { + DDS_ERROR("failed to initialize guard condition [%s]\n", dds_strretcode(-ret)); + goto err_set_guard_condition; + } /* create waitset and attach read conditions */ if ((com->ws = dds_create_waitset(com->participant)) < 0) { DDS_ERROR("failed to create dc waitset [%s]\n", dds_strretcode(-com->ws)); goto err_waitset; } + if ((ret = dds_waitset_attach (com->ws, com->pending_request_guard, com->pending_request_guard)) < 0) { + DDS_ERROR("failed to attach pending request guard condition to waitset [%s]\n", dds_strretcode(-ret)); + goto err_attach_pending_request_guard; + } if ((ret = dds_waitset_attach (com->ws, com->rc_status, com->rd_status)) < 0) { DDS_ERROR("failed to attach dc status reader to waitset [%s]\n", dds_strretcode(-ret)); goto err_attach_rd_status; @@ -776,8 +793,13 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, err_attach_rd_response: dds_waitset_detach(com->ws, com->rc_status); err_attach_rd_status: + dds_waitset_detach(com->ws, com->pending_request_guard); +err_attach_pending_request_guard: dds_delete(com->ws); err_waitset: + dds_delete(com->pending_request_guard); +err_create_pending_request_guard_condition: +err_set_guard_condition: dds_delete(com->rc_subinfo); err_rc_subinfo: dds_delete(com->rd_subinfo); @@ -902,6 +924,11 @@ static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader return DDS_RETCODE_ERROR; } +static dds_return_t dc_com_request_dispose (struct com_t *com, dds_instance_handle_t ih) +{ + return dds_dispose_ih(com->wr_request, ih); +} + static void dc_server_lost (struct dc_t *dc, DurableSupport_status *status) { struct server_t *server; @@ -1004,6 +1031,31 @@ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publicat return; } +static void dc_add_pending_request (struct dc_t *dc, struct pending_request_t *pr) +{ + ddsrt_avl_ipath_t ipath; + dds_return_t ret; + + assert(pr); + ddsrt_mutex_lock(&dc->pending_request_mutex); + if ((ddsrt_avl_clookup_ipath(&pending_requests_td, &dc->pending_requests, &pr->seq, &ipath)) != NULL) { + /* there is already an outstanding reader request for this reader */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "There is already an outstanding reader request with seq %" PRIu64 "\n", pr->seq); + ddsrt_mutex_unlock(&dc->pending_request_mutex); + return; + } + /* pending request not yet available, add it to tree of pending request */ + ddsrt_avl_cinsert(&pending_requests_td, &dc->pending_requests, pr); + ddsrt_fibheap_insert(&pending_requests_fd, &dc->pending_requests_fh, pr); + if (pr == ddsrt_fibheap_min(&pending_requests_fd, &dc->pending_requests_fh)) { + /* trigger the main loop in the recv_handler to recalculate the timeout */ + if ((ret = dds_set_guardcondition(dc->com->pending_request_guard, true)) < 0) { + DDS_ERROR("failed to set pending request guard to true [%s]", dds_strretcode(ret)); + } + } + ddsrt_mutex_unlock(&dc->pending_request_mutex); +} + /* publish a reader request * The reader request is published as a transient-local topic which is * keyed by the guid of this client and a monotonically increasing sequence number. @@ -1020,6 +1072,7 @@ static struct pending_request_t *dc_publish_reader_request (struct dc_t *dc, dds struct pending_request_t *pr; dds_instance_handle_t ih; dds_return_t rc; + dds_time_t now = dds_time(); /* verify if the reader still exists; if not, delete the request */ if ((rc = dds_get_instance_handle(reader, &ih)) != DDS_RETCODE_OK) { @@ -1032,14 +1085,27 @@ static struct pending_request_t *dc_publish_reader_request (struct dc_t *dc, dds goto err_alloc_reader_request; } memset(pr, 0, sizeof(struct pending_request_t)); - pr->ih = ih; - pr->seq = ++(dc->seq); + pr->birth_time = now; + pr->ih = ih; /* handle that corresponds to the reader for which this request is done; key for the pending_request tree */ + pr->seq = ++(dc->seq); /* sequence number; key for the fibheap tree */ pr->reader = reader; pr->rhc = rhc; - ddsrt_avl_cinsert(&pending_requests_td, &dc->pending_requests, pr); + /* LH: We currently never dispose a request to a DS on the same hos + * (which is the only mode we currently support for now). In this way + * a disconnect with the DS will lead to a dispose of the request + * on the DS (by virtue of the autodispose property). A reconnect with + * the DS will lead to the request being received again. + * Once we allow sending requests to (multiple) remote DSs, we need to + * implement a mechanism to detect a disconnect with the DS, and + * perhaps choose to another DS to send a request. + * We also need to cancel requests to DSs that have not responded yet in + * case we received the required data from one of the DSs */ + pr->exp_time = DDS_NEVER; + /* add the pending request */ + dc_add_pending_request(dc, pr); /* publish the request */ if ((rc = dc_com_request_write(dc->com, reader, dc->seq)) != DDS_RETCODE_OK) { - DDS_ERROR("Failed to publish dc_request\n"); + DDS_ERROR("Failed to publish dc_request #%" PRIu64 "\n", dc->seq); goto err_publish_reader_request; } return pr; @@ -1047,11 +1113,35 @@ static struct pending_request_t *dc_publish_reader_request (struct dc_t *dc, dds err_publish_reader_request: ddsrt_avl_cdelete(&pending_requests_td, &dc->pending_requests, pr); cleanup_pending_request(pr); - --(dc->seq); err_alloc_reader_request: return NULL; } +/* dispose the request with key 'seq' */ +static void dc_dispose_reader_request (struct dc_t *dc, uint64_t seq) +{ + dds_return_t rc; + dds_instance_handle_t ih; + DurableSupport_request request; + + /* create a dummy request containing the key fields to retrieve the instance handle */ + memcpy(request.requestid.client, dc->cfg.id, 16); + request.requestid.seq = seq; + if ((ih = dds_lookup_instance(dc->com->wr_request, &request)) == DDS_HANDLE_NIL) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dc_request #%" PRIu64 " not available, nothing to dispose\n", seq); + return; + } + if ((rc = dc_com_request_dispose(dc->com, ih)) != DDS_RETCODE_OK) { + DDS_ERROR("Failed to dispose dc_request #%" PRIu64 " [%s]\n", seq, dds_strretcode(-rc)); + goto err_dispose_reader_request; + } + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dispose dc_request {\"client\":\"%s\", \"seq\":%" PRIu64 "}\n", dc->cfg.id_str, seq); + return; + +err_dispose_reader_request: + return; +} + /* a dc_request reader endpoint on a DS has been found that matched with my dc_request writer */ static struct matched_request_reader_t *dc_add_matched_request_reader (struct dc_t *dc, dds_builtintopic_endpoint_t *ep, dds_instance_handle_t ih) { @@ -1120,12 +1210,48 @@ static void default_request_writer_matched_cb (dds_entity_t writer, dds_publicat } } +/* handle expired pending request and determine the next timeout */ +static void dc_process_pending_request_guard (struct dc_t *dc, dds_time_t *timeout) +{ + dds_return_t ret; + struct pending_request_t *pr; + dds_time_t now = dds_time(); + + ddsrt_mutex_lock(&dc->pending_request_mutex); + do { + pr = ddsrt_fibheap_min(&pending_requests_fd, &dc->pending_requests_fh); + if ((pr == NULL) || (now < pr->exp_time)) { + /* there is no pending request, or the first pending request is not yet expired */ + break; + } + /* The head is expired. Remove the pending request from the priority queue + * and dispose it to prevent that a DS reacts to an expired request */ + if ((pr = ddsrt_fibheap_extract_min(&pending_requests_fd, &dc->pending_requests_fh)) != NULL) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "process pending request %" PRIu64 "\n", pr->seq); + dc_dispose_reader_request(dc, pr->seq); + cleanup_pending_request(pr); + } + } while (true); + /* recalculate the remaining timeout */ + *timeout = (pr == NULL) ? DDS_NEVER : pr->exp_time; + if ((ret = dds_set_guardcondition(dc->com->pending_request_guard, false)) < 0) { + DDS_ERROR("failed to set pending request guard to false [%s]", dds_strretcode(ret)); + } + if (*timeout != DDS_NEVER) { + dds_duration_t tnext = *timeout - now; + int64_t sec = (int64_t)(tnext / DDS_NSECS_IN_SEC); + uint32_t usec = (uint32_t)((tnext % DDS_NSECS_IN_SEC) / DDS_NSECS_IN_USEC); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "next pending request timeout at %" PRId64 ".%06" PRIu32 "s\n", sec, usec); + } + ddsrt_mutex_unlock(&dc->pending_request_mutex); +} + static uint32_t recv_handler (void *a) { struct dc_t *dc = (struct dc_t *)a; - dds_duration_t timeout = DDS_INFINITY; - dds_attach_t wsresults[1]; - size_t wsresultsize = sizeof(wsresults)/sizeof(wsresults[0]); + dds_time_t timeout = DDS_NEVER; + dds_attach_t wsresults[2]; + size_t wsresultsize = sizeof(wsresults) / sizeof(wsresults[0]); int n, j; DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "start durable client thread\n"); @@ -1137,8 +1263,13 @@ static uint32_t recv_handler (void *a) for (j=0; j < n && (size_t)j < wsresultsize; j++) { if (wsresults[j] == dc->com->rd_status) { dc_process_status(dc->com->rd_status, dc); + } else if (wsresults[j] == dc->com->pending_request_guard) { + dc_process_pending_request_guard(dc, &timeout); } } + } else { + /* timeout */ + dc_process_pending_request_guard(dc, &timeout); } } DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "stop durable client thread\n"); @@ -1232,9 +1363,11 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom dc.selected_request_reader_ih = DDS_HANDLE_NIL; dc.nr_of_matched_dc_requests = 0; ddsrt_avl_cinit(&server_td, &dc.servers); - ddsrt_avl_cinit(&pending_requests_td, &dc.pending_requests); ddsrt_avl_cinit(&matched_request_readers_td, &dc.matched_request_readers); + ddsrt_avl_cinit(&pending_requests_td, &dc.pending_requests); ddsrt_fibheap_init(&pending_requests_fd, &dc.pending_requests_fh); + ddsrt_mutex_init(&dc.pending_request_mutex); + ddsrt_cond_init(&dc.pending_request_cond); /* create the quorum listener */ if ((dc.quorum_listener = dds_create_listener(&dc)) == NULL) { DDS_ERROR("failed to create quorum listener\n"); @@ -1266,6 +1399,11 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom err_create_request_listener: dds_delete_listener(dc.quorum_listener); err_create_quorum_listener: + ddsrt_cond_destroy(&dc.pending_request_cond); + ddsrt_mutex_destroy(&dc.pending_request_mutex); + ddsrt_avl_cfree(&pending_requests_td, &dc.pending_requests, cleanup_pending_request); + ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); + ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); ddsrt_free(dc.cfg.ident); return DDS_RETCODE_ERROR; } @@ -1299,6 +1437,8 @@ dds_return_t dds_durability_fini (void) dds_delete_listener(dc.request_listener); dds_delete_listener(dc.quorum_listener); dc_com_free(dc.com); + ddsrt_cond_destroy(&dc.pending_request_cond); + ddsrt_mutex_destroy(&dc.pending_request_mutex); ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); ddsrt_avl_cfree(&pending_requests_td, &dc.pending_requests, cleanup_pending_request); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); @@ -1356,9 +1496,9 @@ dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rh DDS_ERROR("Unable to retrieve the participant's user data for reader\n"); goto err_qget_userdata; } - if ((size != strlen(IDENT)) || (userdata == NULL) || (strcmp(userdata, IDENT) != 0)) { + if ((size != strlen(dc.cfg.ident)) || (userdata == NULL) || (strcmp(userdata, dc.cfg.ident) != 0)) { /* the user data of the participant for this durable reader does - * not contain the ident, so the endoint is not from a remote DS. + * not contain the ident, so the endpoint is not from a remote DS. * We can now publish a dc_request for this durable reader. The * dc_request is published as a transient-local topic. This means * that a late joining DS will receive the DS as long as the request From d35a1ed1655300921ea125b1fc3e4d99cfb65762 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Mon, 13 Nov 2023 10:30:33 +0100 Subject: [PATCH 185/207] Add additional check on the length of topic names in dc_requests Signed-off-by: TheFixer --- src/durability/src/dds_durability.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 94bcced310..4d96d4aab4 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -869,6 +869,8 @@ static void dc_com_free (struct com_t *com) return; } +#define MAX_TOPIC_NAME_SIZE 255 + static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader, uint64_t seq) { /* check for publication_matched() on the dc_request writer to make sure that the request arrives */ @@ -882,6 +884,8 @@ static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader dds_return_t ret = DDS_RETCODE_OK; uint32_t plen, i; char **partitions; + dds_entity_t topic; + char tpname[MAX_TOPIC_NAME_SIZE]; if ((rqos = dds_create_qos()) == NULL) { DDS_ERROR("Unable to create reader qos for dc_request"); @@ -895,6 +899,17 @@ static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader DDS_ERROR("Failed to retrieve partition qos for dc_request"); goto err_qget_partition; } + if ((topic = dds_get_topic(reader)) < 0) { + DDS_ERROR("Failed to get topic for reader [%s]", dds_strretcode(topic)); + goto err_get_topic; + } + if ((ret = dds_get_name(topic, tpname, sizeof(tpname))) < 0) { + DDS_ERROR("Failed to get topic name from reader [%s]", dds_strretcode(ret)); + goto err_get_name; + } else if (ret > MAX_TOPIC_NAME_SIZE) { + DDS_ERROR("topic name '%s...', name too long [%s]", tpname, dds_strretcode(ret)); + goto err_get_name_size; + } request = DurableSupport_request__alloc(); memcpy(request->requestid.client, dc.cfg.id, 16); request->requestid.seq = seq; @@ -905,12 +920,17 @@ static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader for (i=0; i < plen; i++) { request->partitions._buffer[i] = ddsrt_strdup(partitions[i]); } + request->tpname = ddsrt_strdup(tpname); request->timeout = DDS_SECS(5); if ((ret = dds_write(com->wr_request, request)) < 0) { DDS_ERROR("failed to publish dc_request [%s]", dds_strretcode(-ret)); goto err_request_write; } DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "publish dc_request {\"client\":\"%s\", \"seq\":%" PRIu64 "}\n", dc.cfg.id_str, seq); + +err_get_topic: +err_get_name: +err_get_name_size: err_request_write: dc_free_partitions(plen, partitions); dds_delete_qos(rqos); @@ -1099,7 +1119,7 @@ static struct pending_request_t *dc_publish_reader_request (struct dc_t *dc, dds * implement a mechanism to detect a disconnect with the DS, and * perhaps choose to another DS to send a request. * We also need to cancel requests to DSs that have not responded yet in - * case we received the required data from one of the DSs */ + * case we received the required data from one of the DSs */ pr->exp_time = DDS_NEVER; /* add the pending request */ dc_add_pending_request(dc, pr); From 2c4016aea1381eca127a1150f46e1a551a779fed Mon Sep 17 00:00:00 2001 From: TheFixer Date: Wed, 15 Nov 2023 11:25:22 +0100 Subject: [PATCH 186/207] Rebase the expose-seqnum-via-sampleinfo on current master Signed-off-by: TheFixer --- docs/manual/options.md | 6 +++--- etc/cyclonedds.rnc | 7 ++++--- etc/cyclonedds.xsd | 7 ++++--- src/core/ddsi/defconfig.c | 6 +++--- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/docs/manual/options.md b/docs/manual/options.md index b8c021b593..b38dfce0be 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -1909,9 +1909,9 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: `none` - - - + + + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index e7e1b1799a..713aa27299 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -1322,9 +1322,10 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
    } # generated from ddsi_config.h[e6e75c7c07b3b91a92715063cfd8abdd0fbd8b08] # generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] -# generated from ddsi__cfgelems.h[69679834d0a592a339803ed27e3966adc900d592] -# generated from ddsi_config.c[8d7ef0ae962a47cb2138de27ac0f6751e3393c66] -# generated from _confgen.h[9554f1d72645c0b8bb66ffbfbc3c0fb664fc1a43] + +# generated from ddsi__cfgelems.h[de6d6357eef2d532b2450cec9732702107d2a03c] +# generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] +# generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] # generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] # generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] # generated from generate_md.c[789b92e422631684352909cfb8bf43f6ceb16a01] diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index 8ae1f49816..8b5d8c15c6 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -1982,9 +1982,10 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - - - + + + + diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index 53614ab3ab..565f587998 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -101,9 +101,9 @@ void ddsi_config_init_default (struct ddsi_config *cfg) } /* generated from ddsi_config.h[e6e75c7c07b3b91a92715063cfd8abdd0fbd8b08] */ /* generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] */ -/* generated from ddsi__cfgelems.h[69679834d0a592a339803ed27e3966adc900d592] */ -/* generated from ddsi_config.c[8d7ef0ae962a47cb2138de27ac0f6751e3393c66] */ -/* generated from _confgen.h[9554f1d72645c0b8bb66ffbfbc3c0fb664fc1a43] */ +/* generated from ddsi__cfgelems.h[de6d6357eef2d532b2450cec9732702107d2a03c] */ +/* generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] */ +/* generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] */ /* generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] */ /* generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] */ /* generated from generate_md.c[789b92e422631684352909cfb8bf43f6ceb16a01] */ From 6af41597fde0956e3628512f7358974e9aceb982 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 17 Nov 2023 16:32:28 +0100 Subject: [PATCH 187/207] Implement receiving dc_response from a DS Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 78 +++++++ src/durability/src/dds_durability.c | 172 +++++++++++++- src/durability/src/durablesupport.c | 217 ++++++++++++++++++ 3 files changed, 462 insertions(+), 5 deletions(-) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index 1318821ee9..8497b3e663 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -254,6 +254,11 @@ typedef int64_t DurableSupport_duration_t; #define DurableSupport_duration_t__alloc() \ ((DurableSupport_duration_t*) dds_alloc (sizeof (DurableSupport_duration_t))); +typedef uint16_t DurableSupport_responsetype_t; + +#define DurableSupport_responsetype_t__alloc() \ +((DurableSupport_responsetype_t*) dds_alloc (sizeof (DurableSupport_responsetype_t))); + typedef struct DurableSupport_request_id_t { DurableSupport_id_t client; @@ -301,6 +306,79 @@ extern const dds_topic_descriptor_t DurableSupport_request_desc; #define DurableSupport_request_free(d,o) \ dds_sample_free ((d), &DurableSupport_request_desc, (o)) +#define DurableSupport_RESPONSETYPE_SET 1 +#define DurableSupport_RESPONSETYPE_DATA 2 +#ifndef DDS_SEQUENCE_DURABLESUPPORT_REQUEST_ID_T_DEFINED +#define DDS_SEQUENCE_DURABLESUPPORT_REQUEST_ID_T_DEFINED +typedef struct dds_sequence_DurableSupport_request_id_t +{ + uint32_t _maximum; + uint32_t _length; + struct DurableSupport_request_id_t *_buffer; + bool _release; +} dds_sequence_DurableSupport_request_id_t; + +#define dds_sequence_DurableSupport_request_id_t__alloc() \ +((dds_sequence_DurableSupport_request_id_t*) dds_alloc (sizeof (dds_sequence_DurableSupport_request_id_t))); + +#define dds_sequence_DurableSupport_request_id_t_allocbuf(l) \ +((struct DurableSupport_request_id_t *) dds_alloc ((l) * sizeof (struct DurableSupport_request_id_t))) +#endif /* DDS_SEQUENCE_DURABLESUPPORT_REQUEST_ID_T_DEFINED */ + +typedef struct DurableSupport_response_set_t +{ + char * partition; + char * tpname; + uint32_t flags; + dds_sequence_DurableSupport_request_id_t requestids; +} DurableSupport_response_set_t; + +#ifndef DDS_SEQUENCE_OCTET_DEFINED +#define DDS_SEQUENCE_OCTET_DEFINED +typedef struct dds_sequence_octet +{ + uint32_t _maximum; + uint32_t _length; + uint8_t *_buffer; + bool _release; +} dds_sequence_octet; + +#define dds_sequence_octet__alloc() \ +((dds_sequence_octet*) dds_alloc (sizeof (dds_sequence_octet))); + +#define dds_sequence_octet_allocbuf(l) \ +((uint8_t *) dds_alloc ((l) * sizeof (uint8_t))) +#endif /* DDS_SEQUENCE_OCTET_DEFINED */ + +typedef struct DurableSupport_response_data_t +{ + dds_sequence_octet blob; +} DurableSupport_response_data_t; + +typedef struct DurableSupport_response_content +{ + DurableSupport_responsetype_t _d; + union + { + struct DurableSupport_response_set_t set; + struct DurableSupport_response_data_t data; + } _u; +} DurableSupport_response_content; + +typedef struct DurableSupport_response +{ + DurableSupport_id_t id; + struct DurableSupport_response_content body; +} DurableSupport_response; + +extern const dds_topic_descriptor_t DurableSupport_response_desc; + +#define DurableSupport_response__alloc() \ +((DurableSupport_response*) dds_alloc (sizeof (DurableSupport_response))); + +#define DurableSupport_response_free(d,o) \ +dds_sample_free ((d), &DurableSupport_response_desc, (o)) + #ifdef __cplusplus } #endif diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 4d96d4aab4..5bd93dddd2 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -29,6 +29,12 @@ #define TRACE(...) DDS_CLOG (DDS_LC_DUR, &domaingv->logconfig, __VA_ARGS__) +/************* start of common functions ****************/ +/* LH: + * The following functions are duplicated from their equivalents used by the ds + * In future we might want to create a common library that is used both by ds and dc. + */ + static char *dc_stringify_id(const DurableSupport_id_t id, char *buf) { assert(buf); @@ -38,6 +44,119 @@ static char *dc_stringify_id(const DurableSupport_id_t id, char *buf) return buf; } +static char *dc_responsetype_image (DurableSupport_responsetype_t type) +{ + switch (type) { + case DurableSupport_RESPONSETYPE_SET: + return "set"; + case DurableSupport_RESPONSETYPE_DATA: + return "data"; + default: + return "?"; + } +} + +static char *dc_blob_image (dds_sequence_octet blob) +{ + char *buf; + uint32_t len; + uint32_t n; + uint32_t i; + +#define BLOB_IMAGE_SIZE 24 + len = (blob._length < BLOB_IMAGE_SIZE) ? blob._length : BLOB_IMAGE_SIZE; + n = len*2+1; + buf = ddsrt_malloc(n); + if (len < BLOB_IMAGE_SIZE) { + for (i=0; i < len; i++) { + sprintf(buf+i*2, "%02x", (char)blob._buffer[i]); + } + } else { + for (i=0; i < 11; i++) { + sprintf(buf+i*2, "%02x", (char)blob._buffer[i]); + } + strcpy(buf+22, "..."); + for (i=0; i < 11; i++) { + sprintf(buf+25+i*2, "%02x", (char)blob._buffer[len-11+i]); + } + } + buf[2*len] = '\0'; +#undef BLOB_IMAGE_SIZE + return buf; +} + +static int dc_stringify_response (char *buf, size_t n, const DurableSupport_response *response) +{ + size_t i = 0, j = 0; + int l; + char *str; + char id_str[37]; + + if (buf == NULL) { + goto err; + } + if (response == NULL) { + buf[0] = '\0'; + return 0; + } + if ((l = snprintf(buf+i, n-i, "{\"id\":\"%s\", \"type\":\"%s\", \"content\":{", dc_stringify_id(response->id, id_str), dc_responsetype_image(response->body._d))) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + switch (response->body._d) { + case DurableSupport_RESPONSETYPE_SET : + if ((l = snprintf(buf+i, n-i, "\"partition\":\"%s\", \"tpname\":\"%s\", \"flags\":\"0x%04" PRIx32 "\", \"requestids\":[", response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.flags)) < 0) { + goto err; + } + i += (size_t)l; + for (j=0; j < response->body._u.set.requestids._length; j++) { + DurableSupport_request_id_t requestid = response->body._u.set.requestids._buffer[j]; + if ((l = snprintf(buf+i, n-(size_t)i, "%s{\"client\":\"%s\", \"seq\":%" PRIu64 "}", (j==0) ? "" : ",", dc_stringify_id(requestid.client, id_str), requestid.seq)) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + } + if (i < n) { + buf[i++] = ']'; + } + break; + case DurableSupport_RESPONSETYPE_DATA : + str = dc_blob_image(response->body._u.data.blob); + if ((l = snprintf(buf+i, n-i, "\"blob\":\"%s\"", str)) < 0) { + ddsrt_free(str); + goto err; + } + ddsrt_free(str); + i += (size_t)l; + break; + default: + goto err; + } + if (i < n) { + buf[i++] = '}'; + } + if (i < n) { + buf[i++] = '}'; + } +trunc: + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_response failed, type: %" PRIu16 ", buf: %s\n", response->body._d, !buf ? "NULL" : buf); + return -1; +} + +/****** end of common functions *******/ + struct server_t { ddsrt_avl_node_t node; DurableSupport_id_t id; /* id key */ @@ -709,7 +828,9 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc response subscriber [%s]\n", dds_strretcode(-com->response_subscriber)); goto err_response_subscriber; } - if ((com->tp_response = dds_create_topic (com->participant, &DurableSupport_bead_desc, "dc_response", tqos, NULL)) < 0) { + dds_qset_durability(tqos, DDS_DURABILITY_VOLATILE); + dds_qset_history(tqos, DDS_HISTORY_KEEP_ALL, DDS_LENGTH_UNLIMITED); + if ((com->tp_response = dds_create_topic (com->participant, &DurableSupport_response_desc, "dc_response", tqos, NULL)) < 0) { DDS_ERROR("failed to create dc response topic [%s]\n", dds_strretcode(-com->tp_response)); goto err_tp_response; } @@ -921,7 +1042,8 @@ static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader request->partitions._buffer[i] = ddsrt_strdup(partitions[i]); } request->tpname = ddsrt_strdup(tpname); - request->timeout = DDS_SECS(5); +// request->timeout = DDS_SECS(5); + request->timeout = DDS_INFINITY; if ((ret = dds_write(com->wr_request, request)) < 0) { DDS_ERROR("failed to publish dc_request [%s]", dds_strretcode(-ret)); goto err_request_write; @@ -1020,6 +1142,44 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } +static int dc_process_response (dds_entity_t rd, struct dc_t *dc) +{ +#define MAX_SAMPLES 100 + + void *samples[MAX_SAMPLES]; + dds_sample_info_t info[MAX_SAMPLES]; + int samplecount; + int j; + + /* dds_read/take allocates memory for the data if samples[0] is a null pointer. + * The memory must be released when done by returning the loan */ + samples[0] = NULL; + samplecount = dds_take_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE); + if (samplecount < 0) { + DDS_ERROR("failed to take dc_response [%s]", dds_strretcode(-samplecount)); + goto err_samplecount; + } else { + /* process the response + * we ignore invalid samples and only process valid responses */ + for (j = 0; !dds_triggered(dc->com->ws) && j < samplecount; j++) { + DurableSupport_response *response = (DurableSupport_response *)samples[j]; + char str[1024] = { 0 }; /* max string representation size */ + int l; + if (info[j].valid_data && ((l = dc_stringify_response(str, sizeof(str), response)) > 0)) { + size_t len = (size_t)l; + + /* LH: TODO: add statistics for responses */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dc_response %s%s\n", str, (len >= sizeof(str)) ? "..(trunc)" : ""); + } + } + } + (void)dds_return_loan (rd, samples, samplecount); +err_samplecount: + return samplecount; + +#undef MAX_SAMPLES +} + /* called when there is a match for a durable writer */ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publication_matched_status_t status, void *arg) { @@ -1110,14 +1270,14 @@ static struct pending_request_t *dc_publish_reader_request (struct dc_t *dc, dds pr->seq = ++(dc->seq); /* sequence number; key for the fibheap tree */ pr->reader = reader; pr->rhc = rhc; - /* LH: We currently never dispose a request to a DS on the same hos + /* LH: We currently never explicitly dispose a request to a DS on the same host * (which is the only mode we currently support for now). In this way * a disconnect with the DS will lead to a dispose of the request * on the DS (by virtue of the autodispose property). A reconnect with * the DS will lead to the request being received again. * Once we allow sending requests to (multiple) remote DSs, we need to * implement a mechanism to detect a disconnect with the DS, and - * perhaps choose to another DS to send a request. + * perhaps choose another DS to send a request to. * We also need to cancel requests to DSs that have not responded yet in * case we received the required data from one of the DSs */ pr->exp_time = DDS_NEVER; @@ -1270,7 +1430,7 @@ static uint32_t recv_handler (void *a) { struct dc_t *dc = (struct dc_t *)a; dds_time_t timeout = DDS_NEVER; - dds_attach_t wsresults[2]; + dds_attach_t wsresults[3]; size_t wsresultsize = sizeof(wsresults) / sizeof(wsresults[0]); int n, j; @@ -1283,6 +1443,8 @@ static uint32_t recv_handler (void *a) for (j=0; j < n && (size_t)j < wsresultsize; j++) { if (wsresults[j] == dc->com->rd_status) { dc_process_status(dc->com->rd_status, dc); + } else if (wsresults[j] == dc->com->rd_response) { + dc_process_response(dc->com->rd_response, dc); } else if (wsresults[j] == dc->com->pending_request_guard) { dc_process_pending_request_guard(dc, &timeout); } diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index 4a19d54e8f..019dc51c7b 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -798,3 +798,220 @@ const dds_topic_descriptor_t DurableSupport_request_desc = .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request } }; +static const uint32_t DurableSupport_response_ops [] = +{ + /* response */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_response, id), 16u, + DDS_OP_ADR | DDS_OP_TYPE_EXT, offsetof (DurableSupport_response, body), (3u << 16u) + 4u /* response_content */, + DDS_OP_RTS, + + /* response_content */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_response_content, _d), 2u, (12u << 16u) + 4u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 9 /* response_set_t */, 1, offsetof (DurableSupport_response_content, _u.set), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 24 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, + DDS_OP_RTS, + + /* response_set_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, partition), + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, tpname), + DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_response_set_t, flags), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_response_set_t, requestids), sizeof (DurableSupport_request_id_t), (4u << 16u) + 5u /* request_id_t */, + DDS_OP_RTS, + + /* request_id_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), + DDS_OP_RTS, + + /* response_data_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_response_data_t, blob), + DDS_OP_RTS, + + /* key: id */ + DDS_OP_KOF | 1, 1u /* order: 0 */ +}; + +static const dds_key_descriptor_t DurableSupport_response_keys[1] = +{ + { "id", 45, 0 } +}; + +/* Type Information: + [MINIMAL 930d49afed28329dc1db60ef7617] (#deps: 6) + - [MINIMAL 43f53a2be35b432cc735e9431a89] + - [MINIMAL 6bc43f8b4741bc316540a0ef7b88] + - [MINIMAL 80455e796dd3437163cb532089da] + - [MINIMAL 82d72a61dfdf9b101310caab1550] + - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] + - [MINIMAL a580b28d8a19d4a49d2794aae844] + [COMPLETE 75c71ab3f8db547e64f5b5212bc9] (#deps: 6) + - [COMPLETE aca4d5a256d39713924333e85c6d] + - [COMPLETE 699d1f1db9ab7829fc4aa3be1028] + - [COMPLETE eec1bad6badde73f40ef199fedcc] + - [COMPLETE cb1a215003014659ba61115bccb5] + - [COMPLETE 852fffc913b7ee54aadae7a1859a] + - [COMPLETE 008875599776c39ce0c1fe897846] +*/ +#define TYPE_INFO_CDR_DurableSupport_response (const unsigned char []){ \ + 0x80, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x93, 0x0d, 0x49, 0xaf, 0xed, 0x28, 0x32, 0x9d, 0xc1, 0xdb, 0x60, \ + 0xef, 0x76, 0x17, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, 0x41, 0xbc, 0x31, 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0x00, \ + 0x7c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ + 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x82, 0xd7, 0x2a, 0x61, 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, 0x15, 0x50, 0x00, \ + 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ + 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ + 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x75, 0xc7, 0x1a, 0xb3, 0xf8, 0xdb, 0x54, 0x7e, 0x64, 0xf5, 0xb5, \ + 0x21, 0x2b, 0xc9, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x69, 0x9d, 0x1f, 0x1d, 0xb9, 0xab, 0x78, 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0x00, \ + 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, \ + 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xcb, 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, 0x5b, 0xcc, 0xb5, 0x00, \ + 0xbd, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ + 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ + 0x57, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_response 388u +#define TYPE_MAP_CDR_DurableSupport_response (const unsigned char []){ \ + 0x58, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0x93, 0x0d, 0x49, 0xaf, 0xed, 0x28, 0x32, \ + 0x9d, 0xc1, 0xdb, 0x60, 0xef, 0x76, 0x17, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, \ + 0x41, 0xbc, 0x31, 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ + 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, \ + 0x41, 0xbc, 0x31, 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ + 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ + 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ + 0x54, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf1, 0x82, 0xd7, 0x2a, 0x61, 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, 0x15, \ + 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ + 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ + 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ + 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x82, 0xd7, 0x2a, 0x61, \ + 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, 0x15, 0x50, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x7e, 0x75, 0xc0, 0xed, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, \ + 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, \ + 0x01, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, \ + 0x22, 0xa4, 0x7c, 0x2c, 0x0f, 0x37, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, \ + 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, \ + 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, \ + 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0xc3, 0x03, 0x00, 0x00, \ + 0x07, 0x00, 0x00, 0x00, 0xf2, 0x75, 0xc7, 0x1a, 0xb3, 0xf8, 0xdb, 0x54, 0x7e, 0x64, 0xf5, 0xb5, \ + 0x21, 0x2b, 0xc9, 0x00, 0x83, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ + 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x69, \ + 0x9d, 0x1f, 0x1d, 0xb9, 0xab, 0x78, 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, \ + 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x69, 0x9d, 0x1f, \ + 0x1d, 0xb9, 0xab, 0x78, 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0x00, 0xb3, 0x00, 0x00, 0x00, \ + 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, \ + 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xcb, \ + 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, 0x5b, 0xcc, 0xb5, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x00, \ + 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, \ + 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, \ + 0xed, 0xcc, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, \ + 0x00, 0xf2, 0xcb, 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, 0x5b, 0xcc, 0xb5, \ + 0xb9, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, \ + 0x5f, 0x74, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, \ + 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x64, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, \ + 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x7a, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x02, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ + 0x46, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, \ + 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, \ + 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0x75, 0xc7, 0x1a, \ + 0xb3, 0xf8, 0xdb, 0x54, 0x7e, 0x64, 0xf5, 0xb5, 0x21, 0x2b, 0xc9, 0xf1, 0x93, 0x0d, 0x49, 0xaf, \ + 0xed, 0x28, 0x32, 0x9d, 0xc1, 0xdb, 0x60, 0xef, 0x76, 0x17, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, \ + 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x69, 0x9d, 0x1f, 0x1d, 0xb9, 0xab, 0x78, \ + 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, 0x41, 0xbc, 0x31, \ + 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ + 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, \ + 0x53, 0x20, 0x89, 0xda, 0xf2, 0xcb, 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, \ + 0x5b, 0xcc, 0xb5, 0xf1, 0x82, 0xd7, 0x2a, 0x61, 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, \ + 0x15, 0x50, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, \ + 0x9a, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, \ + 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0xf1, \ + 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_response 1790u +const dds_topic_descriptor_t DurableSupport_response_desc = +{ + .m_size = sizeof (DurableSupport_response), + .m_align = dds_alignof (DurableSupport_response), + .m_flagset = DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 1u, + .m_typename = "DurableSupport::response", + .m_keys = DurableSupport_response_keys, + .m_nops = 22, + .m_ops = DurableSupport_response_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_response, .sz = TYPE_INFO_CDR_SZ_DurableSupport_response }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_response, .sz = TYPE_MAP_CDR_SZ_DurableSupport_response } +}; + From 1f03cb5cf46d2dd851d110dc0839dd275d83c943 Mon Sep 17 00:00:00 2001 From: Michel van den Hoek Date: Tue, 21 Nov 2023 13:24:00 +0100 Subject: [PATCH 188/207] expose symbols when building with durable support, fix goto labels Signed-off-by: Michel van den Hoek --- src/core/CMakeLists.txt | 2 +- src/durability/src/dds_durability.c | 21 +++++++++------------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 638316912c..d9ead68db4 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -13,7 +13,7 @@ include (GenerateExportHeader) add_library(ddsc) -if(BUILD_TESTING OR EXPORT_ALL_SYMBOLS) +if(BUILD_TESTING OR EXPORT_ALL_SYMBOLS OR ENABLE_DURABILITY) set_property(TARGET ddsc PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS TRUE) else() set_property(TARGET ddsc PROPERTY C_VISIBILITY_PRESET hidden) diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 5bd93dddd2..2544344ee2 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -492,12 +492,13 @@ static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *e dds_builtintopic_participant_t *participant; dds_instance_handle_t ih; dds_return_t rc; - void *samples[1] = { NULL }; + void *samples[1]; dds_sample_info_t info[1]; void *userdata = NULL; size_t size = 0; char id_str[37]; bool result = false; + samples[0] = NULL; assert(ep); /* by convention, if the ident == NULL then return true */ @@ -532,13 +533,13 @@ static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *e } dds_free(userdata); } - (void)dds_return_loan (com->rd_participant, samples, rc); + (void)dds_return_loan(com->rd_participant, samples, rc); return result; -err_lookup_instance: -err_read_instance: - (void)dds_return_loan (com->rd_participant, samples, rc); err_qget_userdata: + (void)dds_return_loan(com->rd_participant, samples, rc); +err_read_instance: +err_lookup_instance: return false; } @@ -1106,7 +1107,7 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) { #define MAX_SAMPLES 100 - void *samples[MAX_SAMPLES] = { NULL }; + void *samples[MAX_SAMPLES]; dds_sample_info_t info[MAX_SAMPLES]; int samplecount; int j; @@ -1117,7 +1118,6 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) samplecount = dds_take_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE); if (samplecount < 0) { DDS_ERROR("durable client failed to take ds_status [%s]", dds_strretcode(-samplecount)); - goto err_samplecount; } else { /* call the handler function to process the status sample */ for (j = 0; !dds_triggered(dc->com->ws) && j < samplecount; j++) { @@ -1135,9 +1135,8 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) dc_server_discovered(dc, status); } } + (void)dds_return_loan(rd, samples, samplecount); } - (void)dds_return_loan (rd, samples, samplecount); -err_samplecount: return samplecount; #undef MAX_SAMPLES } @@ -1157,7 +1156,6 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) samplecount = dds_take_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE); if (samplecount < 0) { DDS_ERROR("failed to take dc_response [%s]", dds_strretcode(-samplecount)); - goto err_samplecount; } else { /* process the response * we ignore invalid samples and only process valid responses */ @@ -1172,9 +1170,8 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dc_response %s%s\n", str, (len >= sizeof(str)) ? "..(trunc)" : ""); } } + (void)dds_return_loan(rd, samples, samplecount); } - (void)dds_return_loan (rd, samples, samplecount); -err_samplecount: return samplecount; #undef MAX_SAMPLES From e23e202d000f06250f69ada0775d82eab54c348e Mon Sep 17 00:00:00 2001 From: TheFixer Date: Wed, 6 Dec 2023 14:00:37 +0100 Subject: [PATCH 189/207] Refactor administration of requests; requests are now organised per set (i.e., proxy set) Signed-off-by: TheFixer --- src/durability/src/dds_durability.c | 466 +++++++++++++++++++--------- 1 file changed, 313 insertions(+), 153 deletions(-) diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 2544344ee2..718274cab1 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -26,6 +26,11 @@ #define DEFAULT_QOURUM 1 #define DEFAULT_IDENT "durable_support" +/* maximum supported topic name size + * Topic names larger than this size are not supported */ +#define MAX_TOPIC_NAME_SIZE 255 + +#define DC_UNUSED_ARG(x) ((void)x) #define TRACE(...) DDS_CLOG (DDS_LC_DUR, &domaingv->logconfig, __VA_ARGS__) @@ -180,24 +185,110 @@ static void cleanup_server (void *n) static const ddsrt_avl_ctreedef_t server_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct server_t, node), offsetof (struct server_t, id), cmp_server, 0); -/* This represents a request for historical data. */ +struct proxy_set_reader_key_t { + dds_guid_t guid; /* guid of the reader */ +}; + +static int cmp_proxy_set_reader (const void *a, const void *b) +{ + struct proxy_set_reader_key_t *k1 = (struct proxy_set_reader_key_t *)a; + struct proxy_set_reader_key_t *k2 = (struct proxy_set_reader_key_t *)b; + + return memcmp(k1->guid.v, k2->guid.v, 16); +} + +struct proxy_set_reader_t { + ddsrt_avl_node_t node; + struct proxy_set_reader_key_t key; + struct dds_rhc *rhc; +}; + +static void cleanup_proxy_set_reader (void *n) +{ + struct proxy_set_reader_t *proxy_set_reader = (struct proxy_set_reader_t *)n; + + ddsrt_free(proxy_set_reader); +} + +static const ddsrt_avl_ctreedef_t proxy_set_reader_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct proxy_set_reader_t, node), offsetof (struct proxy_set_reader_t, key), cmp_proxy_set_reader, 0); + +struct proxy_set_key_t { + char *partition; /* partition name */ + char *tpname; /* topic name */ + /* todo: typeid */ +}; + +struct proxy_set_t { + ddsrt_avl_node_t node; /* represents a node in the tree of pending requests */ + struct proxy_set_key_t key; /* key of a proxy set */ + ddsrt_avl_ctree_t readers; /* the tree of readers and their rhc that have an interest in this proxy set */ + uint64_t seq; /* the sequence number of the outstanding request for this proxy set, 0 if no outstanding request */ +}; + +static int cmp_proxy_set (const void *a, const void *b) +{ + struct proxy_set_key_t *k1 = (struct proxy_set_key_t *)a; + struct proxy_set_key_t *k2 = (struct proxy_set_key_t *)b; + int cmp; + + /* compare partition */ + if ((cmp = strcmp(k1->partition, k2->partition)) < 0) { + return -1; + } else if (cmp > 0) { + return 1; + } + /* compare topic */ + if ((cmp = strcmp(k1->tpname, k2->tpname)) < 0) { + return -1; + } else if (cmp > 0) { + return 1; + } + return 0; +} + +static void cleanup_proxy_set (void *n) +{ + struct proxy_set_t *proxy_set = (struct proxy_set_t *)n; + + ddsrt_avl_cfree(&proxy_set_reader_td, &proxy_set->readers, cleanup_proxy_set_reader); + ddsrt_free(proxy_set->key.partition); + ddsrt_free(proxy_set->key.tpname); + ddsrt_free(proxy_set); +} + +static const ddsrt_avl_ctreedef_t proxy_set_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct proxy_set_t, node), offsetof (struct proxy_set_t, key), cmp_proxy_set, 0); + +struct pending_request_key_t { + uint64_t seq; /* the sequence number of the request */ +}; + +/* This represents a request for data for a proxy set. + * Such request will lead to the publication of a transient-local + * autodisposed request topic to a DS. Requests are keyed by a monotonically + * increasing sequence number. + * Requests can expire when no answer is received within the specified + * expiration time. In this case the request will be disposed to prevent + * that a DS reacts to an already expired request. + * + * LH: to check: is it really necessary to allow expiration of requests? + * If a request is transient-local, autodisposed then there is no need + * to expire a request. Only if you want to request data from a different + * ds we should dispose the current requests, create another request reader + * that connects to another ds, and republish the requests. */ struct pending_request_t { ddsrt_avl_node_t node; /* represents a node in the tree of pending requests */ ddsrt_fibheap_node_t fhnode; /* represents a node in the priority queue */ - dds_instance_handle_t ih; /* the instance handle that represents the reader */ - uint64_t seq; /* the sequence number of the request; this is used as the key */ - dds_time_t birth_time; /* time this pending event was created */ - dds_entity_t reader; /* the reader that does the request */ - struct dds_rhc *rhc; /* reader rhc */ - dds_time_t exp_time; /* Expire time for this pending request */ + struct pending_request_key_t key; /* sequence number of the request */ + struct proxy_set_t *proxy_set; /* the proxy set associated with the request */ + dds_time_t exp_time; /* request expiration time */ }; static int cmp_pending_request (const void *a, const void *b) { - uint64_t *s1 = (uint64_t *)a; - uint64_t *s2 = (uint64_t *)b; + struct pending_request_key_t *k1 = (struct pending_request_key_t *)a; + struct pending_request_key_t *k2 = (struct pending_request_key_t *)b; - return (*s1 < *s2) ? -1 : ((*s1 > *s2) ? 1 : 0); + return (k1->seq < k2->seq) ? -1 : ((k1->seq > k2->seq) ? 1 : 0); } static void cleanup_pending_request (void *n) @@ -214,7 +305,7 @@ static int cmp_exp_time (const void *a, const void *b) return (pr1->exp_time < pr2->exp_time) ? -1 : ((pr1->exp_time > pr2->exp_time) ? 1 : 0); } -static const ddsrt_avl_ctreedef_t pending_requests_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct pending_request_t, node), offsetof (struct pending_request_t, seq), cmp_pending_request, 0); +static const ddsrt_avl_ctreedef_t pending_requests_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct pending_request_t, node), offsetof (struct pending_request_t, key), cmp_pending_request, 0); static const ddsrt_fibheap_def_t pending_requests_fd = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct pending_request_t, fhnode), cmp_exp_time); @@ -301,7 +392,8 @@ struct dc_t { ddsrt_mutex_t pending_request_mutex; /* pending request queue mutex */ ddsrt_cond_t pending_request_cond; /* pending request condition */ dds_instance_handle_t selected_request_reader_ih; /* instance handle to matched request reader, DDS_HANDLE_NIL if not available */ - ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on a ds that match with my ds writer */ + ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on a ds that match with my request writer */ + ddsrt_avl_ctree_t proxy_sets; /* tree containing the sets for which data has to be provided by a ds */ uint32_t nr_of_matched_dc_requests; /* indicates the number of matched dc_request readers for the dc_request writer of this client */ }; @@ -993,78 +1085,30 @@ static void dc_com_free (struct com_t *com) #define MAX_TOPIC_NAME_SIZE 255 -static dds_return_t dc_com_request_write (struct com_t *com, dds_entity_t reader, uint64_t seq) +static dds_return_t dc_com_request_write (struct com_t *com, const char *partition, const char *tpname, uint64_t seq) { - /* check for publication_matched() on the dc_request writer to make sure that the request arrives */ - /* create a request */ - /* set the request on the pending liust */ - /* send the request */ - /* note: we allow doing a request for volatile readers */ DurableSupport_request *request; - dds_qos_t *rqos; dds_return_t ret = DDS_RETCODE_OK; - uint32_t plen, i; - char **partitions; - dds_entity_t topic; - char tpname[MAX_TOPIC_NAME_SIZE]; - if ((rqos = dds_create_qos()) == NULL) { - DDS_ERROR("Unable to create reader qos for dc_request"); - goto err_alloc_rqos; - } - if ((ret = dds_get_qos(reader, rqos)) != DDS_RETCODE_OK) { - DDS_ERROR("Unable to get reader qos for dc_request"); - goto err_get_qos; - } - if (!dds_qget_partition(rqos, &plen, &partitions)) { - DDS_ERROR("Failed to retrieve partition qos for dc_request"); - goto err_qget_partition; - } - if ((topic = dds_get_topic(reader)) < 0) { - DDS_ERROR("Failed to get topic for reader [%s]", dds_strretcode(topic)); - goto err_get_topic; - } - if ((ret = dds_get_name(topic, tpname, sizeof(tpname))) < 0) { - DDS_ERROR("Failed to get topic name from reader [%s]", dds_strretcode(ret)); - goto err_get_name; - } else if (ret > MAX_TOPIC_NAME_SIZE) { - DDS_ERROR("topic name '%s...', name too long [%s]", tpname, dds_strretcode(ret)); - goto err_get_name_size; - } request = DurableSupport_request__alloc(); memcpy(request->requestid.client, dc.cfg.id, 16); request->requestid.seq = seq; - request->partitions._length = plen; - request->partitions._maximum = plen; - request->partitions._buffer = dds_sequence_string_allocbuf(plen); + request->partitions._length = 1; + request->partitions._maximum = 1; + request->partitions._buffer = dds_sequence_string_allocbuf(1); request->partitions._release = true; - for (i=0; i < plen; i++) { - request->partitions._buffer[i] = ddsrt_strdup(partitions[i]); - } + request->partitions._buffer[0] = ddsrt_strdup(partition); request->tpname = ddsrt_strdup(tpname); -// request->timeout = DDS_SECS(5); request->timeout = DDS_INFINITY; if ((ret = dds_write(com->wr_request, request)) < 0) { DDS_ERROR("failed to publish dc_request [%s]", dds_strretcode(-ret)); goto err_request_write; } DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "publish dc_request {\"client\":\"%s\", \"seq\":%" PRIu64 "}\n", dc.cfg.id_str, seq); - -err_get_topic: -err_get_name: -err_get_name_size: err_request_write: - dc_free_partitions(plen, partitions); - dds_delete_qos(rqos); DurableSupport_request_free(request, DDS_FREE_ALL); return ret; - -err_qget_partition: -err_get_qos: - dds_delete_qos(rqos); -err_alloc_rqos: - return DDS_RETCODE_ERROR; } static dds_return_t dc_com_request_dispose (struct com_t *com, dds_instance_handle_t ih) @@ -1177,54 +1221,63 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } -/* called when there is a match for a durable writer */ -static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publication_matched_status_t status, void *arg) +static struct proxy_set_t *dc_create_proxy_set (struct dc_t *dc, const char *partition, const char *tpname) { - struct dc_t *dc = (struct dc_t *)arg; - dds_instance_handle_t ih; - dds_builtintopic_endpoint_t *ep; + struct proxy_set_t *proxy_set = NULL; - /* a reader has matched with a durable writer. */ - /* check if the reader is a data container. - * If so, this might affect the quorum */ - assert(writer); - if ((ih = status.last_subscription_handle) == DDS_HANDLE_NIL) { - DDS_ERROR("failed to receive valid last_subscription_handle\n"); - goto err_last_subscription_handle; - } - if ((ep = dds_get_matched_subscription_data(writer, ih)) != NULL) { - if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { - /* A data container has matched with this writer. - * Check if the quorum is met. */ - dc_check_quorum_reached(dc, writer, true); - } - dds_builtintopic_free_endpoint(ep); - } else { - /* the endpoint is not available any more. - * Check if the quorem has been lost */ - dc_check_quorum_reached(dc, writer, false); + assert(partition); + assert(tpname); + proxy_set = (struct proxy_set_t *)ddsrt_malloc(sizeof(struct proxy_set_t)); + proxy_set->key.partition = ddsrt_strdup(partition); + proxy_set->key.tpname = ddsrt_strdup(tpname); + proxy_set->seq = 0; /* no pending request yet */ + ddsrt_avl_cinit(&proxy_set_reader_td, &proxy_set->readers); + ddsrt_avl_cinsert(&proxy_set_td, &dc->proxy_sets, proxy_set); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "proxy set '%s.%s' created\n", proxy_set->key.partition, proxy_set->key.tpname); + return proxy_set; +} + +static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, bool autocreate) +{ + struct proxy_set_key_t key; + struct proxy_set_t *proxy_set; + + assert(partition); + assert(tpname); + key.partition = ddsrt_strdup(partition); + key.tpname = ddsrt_strdup(tpname); + if (((proxy_set = ddsrt_avl_clookup (&proxy_set_td, &dc->proxy_sets, &key)) == NULL) && autocreate) { + proxy_set = dc_create_proxy_set(dc, partition, tpname); } -err_last_subscription_handle: - return; + ddsrt_free(key.partition); + ddsrt_free(key.tpname); + return proxy_set; } -static void dc_add_pending_request (struct dc_t *dc, struct pending_request_t *pr) +/* */ +static void dc_register_pending_request (struct dc_t *dc, struct proxy_set_t *proxy_set, const uint64_t seq) { + struct pending_request_t *pr; ddsrt_avl_ipath_t ipath; dds_return_t ret; - assert(pr); + assert(seq > 0); ddsrt_mutex_lock(&dc->pending_request_mutex); - if ((ddsrt_avl_clookup_ipath(&pending_requests_td, &dc->pending_requests, &pr->seq, &ipath)) != NULL) { - /* there is already an outstanding reader request for this reader */ - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "There is already an outstanding reader request with seq %" PRIu64 "\n", pr->seq); + if ((pr = ddsrt_avl_clookup_ipath(&pending_requests_td, &dc->pending_requests, &seq, &ipath)) != NULL) { + /* there is already an outstanding request with this sequence number */ + assert(pr->proxy_set == proxy_set); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "There is already an outstanding request with seq %" PRIu64 "\n", seq); ddsrt_mutex_unlock(&dc->pending_request_mutex); return; } + pr = (struct pending_request_t *)ddsrt_malloc(sizeof(struct pending_request_t)); + pr->key.seq = seq; + pr->proxy_set = proxy_set; + pr->exp_time = DDS_NEVER; /* pending request not yet available, add it to tree of pending request */ ddsrt_avl_cinsert(&pending_requests_td, &dc->pending_requests, pr); ddsrt_fibheap_insert(&pending_requests_fd, &dc->pending_requests_fh, pr); - if (pr == ddsrt_fibheap_min(&pending_requests_fd, &dc->pending_requests_fh)) { + if ((pr->exp_time != DDS_NEVER) && (pr == ddsrt_fibheap_min(&pending_requests_fd, &dc->pending_requests_fh))) { /* trigger the main loop in the recv_handler to recalculate the timeout */ if ((ret = dds_set_guardcondition(dc->com->pending_request_guard, true)) < 0) { DDS_ERROR("failed to set pending request guard to true [%s]", dds_strretcode(ret)); @@ -1233,65 +1286,169 @@ static void dc_add_pending_request (struct dc_t *dc, struct pending_request_t *p ddsrt_mutex_unlock(&dc->pending_request_mutex); } -/* publish a reader request - * The reader request is published as a transient-local topic which is - * keyed by the guid of this client and a monotonically increasing sequence number. - * Even though this is not recommended, this allows multiple requests from the - * same reader (because they have a different sequence number). - * - * For each outgoing request, a pending request entry will be created to administrate - * the outgoing requests. Pending requests can have a expiration. Expired pending - * requests will lead to removal of the pending request, and a dispose of the - * corresponding reader request to prevent that late joining - */ -static struct pending_request_t *dc_publish_reader_request (struct dc_t *dc, dds_entity_t reader, struct dds_rhc *rhc) +/* publish a request for a specific data set + * The request is published as a transient-local topic which is + * keyed by the guid of this client and a monotonically increasing + * sequence number. This allows multiple requests from the same client + * (because they have a different sequence number). */ +static int dc_request_data_for_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, const uint64_t seq) { - struct pending_request_t *pr; - dds_instance_handle_t ih; dds_return_t rc; - dds_time_t now = dds_time(); + assert(proxy_set); + assert(seq > 0); + assert(proxy_set->seq == seq); + /* register the request identified by seq with the proxy set + * We do this BEFORE we send the request, so that we are sure + * that when we receive the response the we can lookup the + * proxy set associated with this request */ + dc_register_pending_request(dc, proxy_set, seq); + if ((rc = dc_com_request_write(dc->com, proxy_set->key.partition, proxy_set->key.tpname, seq)) != DDS_RETCODE_OK) { + DDS_ERROR("Failed to publish dc_request #%" PRIu64 "\n", dc->seq); + } + return (rc == DDS_RETCODE_OK) ? 0 : -1; +} + +/* add the reader tree of readers for this proxy set */ +static void dc_register_reader_to_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, dds_guid_t guid, struct dds_rhc *rhc) +{ + struct proxy_set_reader_t *proxy_set_rd; + struct proxy_set_reader_key_t key; + char id_str[37]; + + key.guid = guid; + if ((proxy_set_rd = ddsrt_avl_clookup (&proxy_set_reader_td, &proxy_set->readers, &key)) == NULL) { + proxy_set_rd = (struct proxy_set_reader_t *)ddsrt_malloc(sizeof(struct proxy_set_reader_t)); + proxy_set_rd->key.guid = guid; + proxy_set_rd->rhc = rhc; + ddsrt_avl_cinsert(&proxy_set_reader_td, &proxy_set->readers, proxy_set_rd); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "reader \"%s\" added to proxy set '%s.%s'\n", dc_stringify_id(guid.v, id_str), proxy_set->key.partition, proxy_set->key.tpname); + } + assert(proxy_set_rd->rhc == rhc); +} + +static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reader, struct dds_rhc *rhc) +{ + dds_entity_t topic; + dds_return_t rc; + char tpname[MAX_TOPIC_NAME_SIZE]; + dds_qos_t *rqos; + uint32_t plen, i; + char **partitions; + struct proxy_set_t *proxy_set = NULL; + dds_instance_handle_t ih; + dds_guid_t guid; + char id_str[37]; + + /* LH: perhaps the qos should be added as parameter, since the caller already has the qos */ /* verify if the reader still exists; if not, delete the request */ if ((rc = dds_get_instance_handle(reader, &ih)) != DDS_RETCODE_OK) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "No need to publish dc_request, reader is not available\n"); - return NULL; - } - /* create a pending request entry and insert it in the table of pending requests */ - if ((pr = (struct pending_request_t *)ddsrt_malloc(sizeof(struct pending_request_t))) == NULL) { - DDS_ERROR("Failed to allocate a reader request\n"); - goto err_alloc_reader_request; - } - memset(pr, 0, sizeof(struct pending_request_t)); - pr->birth_time = now; - pr->ih = ih; /* handle that corresponds to the reader for which this request is done; key for the pending_request tree */ - pr->seq = ++(dc->seq); /* sequence number; key for the fibheap tree */ - pr->reader = reader; - pr->rhc = rhc; - /* LH: We currently never explicitly dispose a request to a DS on the same host - * (which is the only mode we currently support for now). In this way - * a disconnect with the DS will lead to a dispose of the request - * on the DS (by virtue of the autodispose property). A reconnect with - * the DS will lead to the request being received again. - * Once we allow sending requests to (multiple) remote DSs, we need to - * implement a mechanism to detect a disconnect with the DS, and - * perhaps choose another DS to send a request to. - * We also need to cancel requests to DSs that have not responded yet in - * case we received the required data from one of the DSs */ - pr->exp_time = DDS_NEVER; - /* add the pending request */ - dc_add_pending_request(dc, pr); - /* publish the request */ - if ((rc = dc_com_request_write(dc->com, reader, dc->seq)) != DDS_RETCODE_OK) { - DDS_ERROR("Failed to publish dc_request #%" PRIu64 "\n", dc->seq); - goto err_publish_reader_request; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "No need to create a proxy set, reader is not available [%s]\n", dds_strretcode(-rc)); + return; + } + /* get reader guid */ + if ((rc = dds_get_guid(reader, &guid)) < DDS_RETCODE_OK) { + DDS_ERROR("Unable to retrieve the guid of the reader [%s]\n", dds_strretcode(-rc)); + goto err_get_guid; + } + (void)dc_stringify_id(guid.v, id_str); + /* get topic name */ + if ((topic = dds_get_topic(reader)) < 0) { + DDS_ERROR("Unable to get topic from reader [%s]\n", dds_strretcode(-topic)); + goto err_get_topic; + } + if ((rc = dds_get_name(topic, tpname, sizeof(tpname))) < 0) { + DDS_ERROR("Failed to get topic name [%s]\n", dds_strretcode(-rc)); + goto err_get_name; + } else if (rc > MAX_TOPIC_NAME_SIZE) { + DDS_ERROR("Name for topic '%s...', name too long\n", tpname); + goto err_get_name_size; + } + /* get partitions of the reader */ + if ((rqos = dds_create_qos()) == NULL) { + DDS_ERROR("Failed to allocate reader qos\n"); + goto err_alloc_rqos; + } + if ((rc = dds_get_qos(reader, rqos)) < 0) { + DDS_ERROR("Failed to get topic qos [%s]\n", dds_strretcode(rc)); + goto err_get_qos; + } + if (!dds_qget_partition(rqos, &plen, &partitions)) { + DDS_ERROR("failed to get partitions from qos\n"); + goto err_qget_partition; + } + assert(plen > 0); + /* for each partition create a proxy set if it does not exist yet + * and request data for the proxy set (if not done so already) */ + for (i=0; i < plen; i++) { + proxy_set = dc_get_proxy_set(dc, partitions[i], tpname, true); + assert(proxy_set); + /* Add the reader and rhc to this proxy set. + * We do this BEFORE we send the request, so that we are sure + * that when we receive the response (possibly immediately after + * sending the request) the reader and rhc are present */ + dc_register_reader_to_proxy_set(dc, proxy_set, guid, rhc); + if (proxy_set->seq == 0) { + /* There is no pending request associated with this proxy set, + * so let's create a new pending request for this proxy set */ + proxy_set->seq = ++(dc->seq); + if ((dc_request_data_for_proxy_set(dc, proxy_set, proxy_set->seq)) < 0) { + /* We failed to request data for this proxy set. + * We could do several things now, e.g., 1) try again until we succeed, + * 2) notify the application that no historical data could be retrieved, + * or 3) commit suicide because we cannot guarantee eventual consistency. + * For now, I choose for the latter. After all, it is expected that sending + * a request should never fail. */ + abort(); + } + } /* else there is already an outstanding pending request for this + * proxy set. In that case there is no need to republish the request, + * we can just piggyback on the current outstanding request */ } - return pr; + dc_free_partitions(plen, partitions); + dds_delete_qos(rqos); + return; -err_publish_reader_request: - ddsrt_avl_cdelete(&pending_requests_td, &dc->pending_requests, pr); - cleanup_pending_request(pr); -err_alloc_reader_request: - return NULL; +err_qget_partition: +err_get_qos: + dds_delete_qos(rqos); +err_alloc_rqos: +err_get_name_size: +err_get_name: +err_get_topic: +err_get_guid: + return; +} + +/* called when there is a match for a durable writer */ +static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publication_matched_status_t status, void *arg) +{ + struct dc_t *dc = (struct dc_t *)arg; + dds_instance_handle_t ih; + dds_builtintopic_endpoint_t *ep; + + /* a reader has matched with a durable writer. */ + /* check if the reader is a data container. + * If so, this might affect the quorum */ + assert(writer); + if ((ih = status.last_subscription_handle) == DDS_HANDLE_NIL) { + DDS_ERROR("failed to receive valid last_subscription_handle\n"); + goto err_last_subscription_handle; + } + if ((ep = dds_get_matched_subscription_data(writer, ih)) != NULL) { + if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { + /* A data container has matched with this writer. + * Check if the quorum is met. */ + dc_check_quorum_reached(dc, writer, true); + } + dds_builtintopic_free_endpoint(ep); + } else { + /* the endpoint is not available any more. + * check if the quorum has been lost */ + dc_check_quorum_reached(dc, writer, false); + } +err_last_subscription_handle: + return; } /* dispose the request with key 'seq' */ @@ -1404,8 +1561,8 @@ static void dc_process_pending_request_guard (struct dc_t *dc, dds_time_t *timeo /* The head is expired. Remove the pending request from the priority queue * and dispose it to prevent that a DS reacts to an expired request */ if ((pr = ddsrt_fibheap_extract_min(&pending_requests_fd, &dc->pending_requests_fh)) != NULL) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "process pending request %" PRIu64 "\n", pr->seq); - dc_dispose_reader_request(dc, pr->seq); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "process pending request %" PRIu64 "\n", pr->key.seq); + dc_dispose_reader_request(dc, pr->key.seq); cleanup_pending_request(pr); } } while (true); @@ -1545,6 +1702,7 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom ddsrt_avl_cinit(&matched_request_readers_td, &dc.matched_request_readers); ddsrt_avl_cinit(&pending_requests_td, &dc.pending_requests); ddsrt_fibheap_init(&pending_requests_fd, &dc.pending_requests_fh); + ddsrt_avl_cinit(&proxy_set_td, &dc.proxy_sets); ddsrt_mutex_init(&dc.pending_request_mutex); ddsrt_cond_init(&dc.pending_request_cond); /* create the quorum listener */ @@ -1580,6 +1738,7 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom err_create_quorum_listener: ddsrt_cond_destroy(&dc.pending_request_cond); ddsrt_mutex_destroy(&dc.pending_request_mutex); + ddsrt_avl_cfree(&proxy_set_td, &dc.proxy_sets, cleanup_proxy_set); ddsrt_avl_cfree(&pending_requests_td, &dc.pending_requests, cleanup_pending_request); ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); @@ -1618,6 +1777,7 @@ dds_return_t dds_durability_fini (void) dc_com_free(dc.com); ddsrt_cond_destroy(&dc.pending_request_cond); ddsrt_mutex_destroy(&dc.pending_request_mutex); + ddsrt_avl_cfree(&proxy_set_td, &dc.proxy_sets, cleanup_proxy_set); ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); ddsrt_avl_cfree(&pending_requests_td, &dc.pending_requests, cleanup_pending_request); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); @@ -1681,8 +1841,8 @@ dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rh * We can now publish a dc_request for this durable reader. The * dc_request is published as a transient-local topic. This means * that a late joining DS will receive the DS as long as the request - * is not yet disposed.*/ - (void)dc_publish_reader_request(&dc, reader, rhc); + * is not yet disposed. */ + dc_create_proxy_sets_for_reader(&dc, reader, rhc); } dds_free(userdata); dds_delete_qos(parqos); From a72343c42950d3c7674f3372b6b6237916a29b75 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Mon, 11 Dec 2023 11:50:47 +0100 Subject: [PATCH 190/207] Add ability to receive responses from a ds Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 53 +- src/durability/src/dds_durability.c | 190 +++---- src/durability/src/durablesupport.c | 474 +++++++----------- 3 files changed, 256 insertions(+), 461 deletions(-) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index 8497b3e663..a101834c00 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -259,41 +259,10 @@ typedef uint16_t DurableSupport_responsetype_t; #define DurableSupport_responsetype_t__alloc() \ ((DurableSupport_responsetype_t*) dds_alloc (sizeof (DurableSupport_responsetype_t))); -typedef struct DurableSupport_request_id_t -{ - DurableSupport_id_t client; - uint64_t seq; -} DurableSupport_request_id_t; - -extern const dds_topic_descriptor_t DurableSupport_request_id_t_desc; - -#define DurableSupport_request_id_t__alloc() \ -((DurableSupport_request_id_t*) dds_alloc (sizeof (DurableSupport_request_id_t))); - -#define DurableSupport_request_id_t_free(d,o) \ -dds_sample_free ((d), &DurableSupport_request_id_t_desc, (o)) - -#ifndef DDS_SEQUENCE_STRING_DEFINED -#define DDS_SEQUENCE_STRING_DEFINED -typedef struct dds_sequence_string -{ - uint32_t _maximum; - uint32_t _length; - char **_buffer; - bool _release; -} dds_sequence_string; - -#define dds_sequence_string__alloc() \ -((dds_sequence_string*) dds_alloc (sizeof (dds_sequence_string))); - -#define dds_sequence_string_allocbuf(l) \ -((char **) dds_alloc ((l) * sizeof (char*))) -#endif /* DDS_SEQUENCE_STRING_DEFINED */ - typedef struct DurableSupport_request { - struct DurableSupport_request_id_t requestid; - dds_sequence_string partitions; + DurableSupport_id_t client; + char * partition; char * tpname; DurableSupport_duration_t timeout; } DurableSupport_request; @@ -308,29 +277,11 @@ dds_sample_free ((d), &DurableSupport_request_desc, (o)) #define DurableSupport_RESPONSETYPE_SET 1 #define DurableSupport_RESPONSETYPE_DATA 2 -#ifndef DDS_SEQUENCE_DURABLESUPPORT_REQUEST_ID_T_DEFINED -#define DDS_SEQUENCE_DURABLESUPPORT_REQUEST_ID_T_DEFINED -typedef struct dds_sequence_DurableSupport_request_id_t -{ - uint32_t _maximum; - uint32_t _length; - struct DurableSupport_request_id_t *_buffer; - bool _release; -} dds_sequence_DurableSupport_request_id_t; - -#define dds_sequence_DurableSupport_request_id_t__alloc() \ -((dds_sequence_DurableSupport_request_id_t*) dds_alloc (sizeof (dds_sequence_DurableSupport_request_id_t))); - -#define dds_sequence_DurableSupport_request_id_t_allocbuf(l) \ -((struct DurableSupport_request_id_t *) dds_alloc ((l) * sizeof (struct DurableSupport_request_id_t))) -#endif /* DDS_SEQUENCE_DURABLESUPPORT_REQUEST_ID_T_DEFINED */ - typedef struct DurableSupport_response_set_t { char * partition; char * tpname; uint32_t flags; - dds_sequence_DurableSupport_request_id_t requestids; } DurableSupport_response_set_t; #ifndef DDS_SEQUENCE_OCTET_DEFINED diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 718274cab1..7da86940d3 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -90,9 +90,54 @@ static char *dc_blob_image (dds_sequence_octet blob) return buf; } +static int dc_stringify_request (char *buf, size_t n, const DurableSupport_request *request, bool valid_data) +{ + size_t i = 0; + int l; + char id_str[37]; + int64_t sec; + uint32_t msec; + + if (buf == NULL) { + goto err; + } + if (request == NULL) { + buf[0] = '\0'; + return 0; + } + if (valid_data) { + /* also print non-key fields */ + if (request->timeout == DDS_INFINITY) { + if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"timeout\":\"never\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname)) < 0) { + goto err; + } + } else { + sec = (int64_t)(request->timeout / DDS_NSECS_IN_SEC); + msec = (uint32_t)((request->timeout % DDS_NSECS_IN_SEC) / DDS_NSECS_IN_MSEC); + if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"timeout\":%" PRId64 ".%03" PRIu32 "}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, sec, msec)) < 0) { + goto err; + } + } + } else { + /* only print key fields */ + if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname)) < 0) { + goto err; + } + } + i += (size_t)l; + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_request failed"); + return -1; +} + static int dc_stringify_response (char *buf, size_t n, const DurableSupport_response *response) { - size_t i = 0, j = 0; + size_t i = 0; int l; char *str; char id_str[37]; @@ -113,23 +158,10 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp } switch (response->body._d) { case DurableSupport_RESPONSETYPE_SET : - if ((l = snprintf(buf+i, n-i, "\"partition\":\"%s\", \"tpname\":\"%s\", \"flags\":\"0x%04" PRIx32 "\", \"requestids\":[", response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.flags)) < 0) { + if ((l = snprintf(buf+i, n-i, "\"partition\":\"%s\", \"tpname\":\"%s\", \"flags\":\"0x%04" PRIx32 "\"", response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.flags)) < 0) { goto err; } i += (size_t)l; - for (j=0; j < response->body._u.set.requestids._length; j++) { - DurableSupport_request_id_t requestid = response->body._u.set.requestids._buffer[j]; - if ((l = snprintf(buf+i, n-(size_t)i, "%s{\"client\":\"%s\", \"seq\":%" PRIu64 "}", (j==0) ? "" : ",", dc_stringify_id(requestid.client, id_str), requestid.seq)) < 0) { - goto err; - } - i += (size_t)l; - if (i >= n) { - goto trunc; - } - } - if (i < n) { - buf[i++] = ']'; - } break; case DurableSupport_RESPONSETYPE_DATA : str = dc_blob_image(response->body._u.data.blob); @@ -1085,27 +1117,28 @@ static void dc_com_free (struct com_t *com) #define MAX_TOPIC_NAME_SIZE 255 -static dds_return_t dc_com_request_write (struct com_t *com, const char *partition, const char *tpname, uint64_t seq) +static dds_return_t dc_com_request_write (struct com_t *com, const char *partition, const char *tpname) { /* note: we allow doing a request for volatile readers */ DurableSupport_request *request; dds_return_t ret = DDS_RETCODE_OK; + char str[1024]; + int l; + size_t len; request = DurableSupport_request__alloc(); - memcpy(request->requestid.client, dc.cfg.id, 16); - request->requestid.seq = seq; - request->partitions._length = 1; - request->partitions._maximum = 1; - request->partitions._buffer = dds_sequence_string_allocbuf(1); - request->partitions._release = true; - request->partitions._buffer[0] = ddsrt_strdup(partition); + memcpy(request->client, dc.cfg.id, 16); + request->partition = ddsrt_strdup(partition); request->tpname = ddsrt_strdup(tpname); request->timeout = DDS_INFINITY; + l = dc_stringify_request(str, sizeof(str), request, true); + assert(l > 0); + len = (size_t)l; if ((ret = dds_write(com->wr_request, request)) < 0) { - DDS_ERROR("failed to publish dc_request [%s]", dds_strretcode(-ret)); + DDS_ERROR("failed to publish dc_request %s%s [%s]", str, (len >= sizeof(str)) ? "..(trunc)" : "", dds_strretcode(-ret)); goto err_request_write; } - DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "publish dc_request {\"client\":\"%s\", \"seq\":%" PRIu64 "}\n", dc.cfg.id_str, seq); + DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "publish dc_request %s%s\n", str, (len >= sizeof(str)) ? "..(trunc)" : ""); err_request_write: DurableSupport_request_free(request, DDS_FREE_ALL); return ret; @@ -1198,6 +1231,7 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) * The memory must be released when done by returning the loan */ samples[0] = NULL; samplecount = dds_take_mask (rd, samples, info, MAX_SAMPLES, MAX_SAMPLES, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE); + if (samplecount < 0) { DDS_ERROR("failed to take dc_response [%s]", dds_strretcode(-samplecount)); } else { @@ -1254,61 +1288,6 @@ static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partit return proxy_set; } -/* */ -static void dc_register_pending_request (struct dc_t *dc, struct proxy_set_t *proxy_set, const uint64_t seq) -{ - struct pending_request_t *pr; - ddsrt_avl_ipath_t ipath; - dds_return_t ret; - - assert(seq > 0); - ddsrt_mutex_lock(&dc->pending_request_mutex); - if ((pr = ddsrt_avl_clookup_ipath(&pending_requests_td, &dc->pending_requests, &seq, &ipath)) != NULL) { - /* there is already an outstanding request with this sequence number */ - assert(pr->proxy_set == proxy_set); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "There is already an outstanding request with seq %" PRIu64 "\n", seq); - ddsrt_mutex_unlock(&dc->pending_request_mutex); - return; - } - pr = (struct pending_request_t *)ddsrt_malloc(sizeof(struct pending_request_t)); - pr->key.seq = seq; - pr->proxy_set = proxy_set; - pr->exp_time = DDS_NEVER; - /* pending request not yet available, add it to tree of pending request */ - ddsrt_avl_cinsert(&pending_requests_td, &dc->pending_requests, pr); - ddsrt_fibheap_insert(&pending_requests_fd, &dc->pending_requests_fh, pr); - if ((pr->exp_time != DDS_NEVER) && (pr == ddsrt_fibheap_min(&pending_requests_fd, &dc->pending_requests_fh))) { - /* trigger the main loop in the recv_handler to recalculate the timeout */ - if ((ret = dds_set_guardcondition(dc->com->pending_request_guard, true)) < 0) { - DDS_ERROR("failed to set pending request guard to true [%s]", dds_strretcode(ret)); - } - } - ddsrt_mutex_unlock(&dc->pending_request_mutex); -} - -/* publish a request for a specific data set - * The request is published as a transient-local topic which is - * keyed by the guid of this client and a monotonically increasing - * sequence number. This allows multiple requests from the same client - * (because they have a different sequence number). */ -static int dc_request_data_for_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, const uint64_t seq) -{ - dds_return_t rc; - - assert(proxy_set); - assert(seq > 0); - assert(proxy_set->seq == seq); - /* register the request identified by seq with the proxy set - * We do this BEFORE we send the request, so that we are sure - * that when we receive the response the we can lookup the - * proxy set associated with this request */ - dc_register_pending_request(dc, proxy_set, seq); - if ((rc = dc_com_request_write(dc->com, proxy_set->key.partition, proxy_set->key.tpname, seq)) != DDS_RETCODE_OK) { - DDS_ERROR("Failed to publish dc_request #%" PRIu64 "\n", dc->seq); - } - return (rc == DDS_RETCODE_OK) ? 0 : -1; -} - /* add the reader tree of readers for this proxy set */ static void dc_register_reader_to_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, dds_guid_t guid, struct dds_rhc *rhc) { @@ -1388,22 +1367,17 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade * that when we receive the response (possibly immediately after * sending the request) the reader and rhc are present */ dc_register_reader_to_proxy_set(dc, proxy_set, guid, rhc); - if (proxy_set->seq == 0) { - /* There is no pending request associated with this proxy set, - * so let's create a new pending request for this proxy set */ - proxy_set->seq = ++(dc->seq); - if ((dc_request_data_for_proxy_set(dc, proxy_set, proxy_set->seq)) < 0) { - /* We failed to request data for this proxy set. - * We could do several things now, e.g., 1) try again until we succeed, - * 2) notify the application that no historical data could be retrieved, - * or 3) commit suicide because we cannot guarantee eventual consistency. - * For now, I choose for the latter. After all, it is expected that sending - * a request should never fail. */ - abort(); - } - } /* else there is already an outstanding pending request for this - * proxy set. In that case there is no need to republish the request, - * we can just piggyback on the current outstanding request */ + /* send a request for this proxy set */ + if ((rc = dc_com_request_write(dc->com, proxy_set->key.partition, proxy_set->key.tpname)) != DDS_RETCODE_OK) { + DDS_ERROR("Failed to publish dc_request for proxy set %s.%s\n", proxy_set->key.partition, proxy_set->key.tpname); + /* We failed to request data for this proxy set. + * We could do several things now, e.g., 1) try again until we succeed, + * 2) notify the application that no historical data could be retrieved, + * or 3) commit suicide because we cannot guarantee eventual consistency. + * For now, I choose for the latter. After all, it is expected that sending + * a request should never fails. */ + abort(); + } } dc_free_partitions(plen, partitions); dds_delete_qos(rqos); @@ -1451,28 +1425,30 @@ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publicat return; } -/* dispose the request with key 'seq' */ -static void dc_dispose_reader_request (struct dc_t *dc, uint64_t seq) +/* dispose the request for the proxy set */ +static void dc_dispose_reader_request (struct dc_t *dc, struct proxy_set_t *proxy_set) { dds_return_t rc; dds_instance_handle_t ih; DurableSupport_request request; /* create a dummy request containing the key fields to retrieve the instance handle */ - memcpy(request.requestid.client, dc->cfg.id, 16); - request.requestid.seq = seq; + memcpy(request.client, dc->cfg.id, 16); + request.partition = ddsrt_strdup(proxy_set->key.partition); + request.tpname = ddsrt_strdup(proxy_set->key.tpname); if ((ih = dds_lookup_instance(dc->com->wr_request, &request)) == DDS_HANDLE_NIL) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dc_request #%" PRIu64 " not available, nothing to dispose\n", seq); - return; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dc_request for proxy set %s.%s not found, unable to dispose\n", request.partition, request.tpname); + goto err_dispose_reader_request; } if ((rc = dc_com_request_dispose(dc->com, ih)) != DDS_RETCODE_OK) { - DDS_ERROR("Failed to dispose dc_request #%" PRIu64 " [%s]\n", seq, dds_strretcode(-rc)); + DDS_ERROR("failed to dispose dc_request for proxy set %s.%s [%s]\n", request.partition, request.tpname, dds_strretcode(-rc)); goto err_dispose_reader_request; } - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dispose dc_request {\"client\":\"%s\", \"seq\":%" PRIu64 "}\n", dc->cfg.id_str, seq); - return; - + /* LH: todo: use dc_stringify_request, but only print the keys */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dispose dc_request {\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\"}\n", dc->cfg.id_str, request.partition, request.tpname); err_dispose_reader_request: + ddsrt_free(request.partition); + ddsrt_free(request.tpname); return; } @@ -1562,7 +1538,7 @@ static void dc_process_pending_request_guard (struct dc_t *dc, dds_time_t *timeo * and dispose it to prevent that a DS reacts to an expired request */ if ((pr = ddsrt_fibheap_extract_min(&pending_requests_fd, &dc->pending_requests_fh)) != NULL) { DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "process pending request %" PRIu64 "\n", pr->key.seq); - dc_dispose_reader_request(dc, pr->key.seq); + dc_dispose_reader_request(dc, pr->proxy_set); cleanup_pending_request(pr); } } while (true); diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index 019dc51c7b..c15192752f 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -586,212 +586,113 @@ const dds_topic_descriptor_t DurableSupport_bead_desc = .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_bead, .sz = TYPE_MAP_CDR_SZ_DurableSupport_bead } }; -static const uint32_t DurableSupport_request_id_t_ops [] = -{ - /* request_id_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), - DDS_OP_RTS -}; - -/* Type Information: - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] (#deps: 1) - - [MINIMAL 43f53a2be35b432cc735e9431a89] - [COMPLETE 852fffc913b7ee54aadae7a1859a] (#deps: 1) - - [COMPLETE aca4d5a256d39713924333e85c6d] -*/ -#define TYPE_INFO_CDR_DurableSupport_request_id_t (const unsigned char []){ \ - 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, \ - 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, \ - 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x40, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_request_id_t 148u -#define TYPE_MAP_CDR_DurableSupport_request_id_t (const unsigned char []){ \ - 0x8a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ - 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ - 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, \ - 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, \ - 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ - 0xe4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ - 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ - 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ - 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0xf1, \ - 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_request_id_t 444u -const dds_topic_descriptor_t DurableSupport_request_id_t_desc = -{ - .m_size = sizeof (DurableSupport_request_id_t), - .m_align = dds_alignof (DurableSupport_request_id_t), - .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 0u, - .m_typename = "DurableSupport::request_id_t", - .m_keys = NULL, - .m_nops = 4, - .m_ops = DurableSupport_request_id_t_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request_id_t, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request_id_t }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request_id_t, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request_id_t } -}; - static const uint32_t DurableSupport_request_ops [] = { /* request */ DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_EXT, offsetof (DurableSupport_request, requestid), (3u << 16u) + 10u /* request_id_t */, - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STR, offsetof (DurableSupport_request, partitions), - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, client), 16u, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, partition), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), DDS_OP_ADR | DDS_OP_TYPE_8BY | DDS_OP_FLAG_SGN, offsetof (DurableSupport_request, timeout), DDS_OP_RTS, - - /* request_id_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), - DDS_OP_RTS, - /* key: requestid.client */ - DDS_OP_KOF | 2, 1u /* order: 0 */, 1u /* order: 0 */, + /* key: client */ + DDS_OP_KOF | 1, 1u /* order: 0 */, + + /* key: partition */ + DDS_OP_KOF | 1, 4u /* order: 1 */, - /* key: requestid.seq */ - DDS_OP_KOF | 2, 1u /* order: 0 */, 4u /* order: 1 */ + /* key: tpname */ + DDS_OP_KOF | 1, 6u /* order: 2 */ }; -static const dds_key_descriptor_t DurableSupport_request_keys[2] = +static const dds_key_descriptor_t DurableSupport_request_keys[3] = { - { "requestid.client", 18, 0 }, - { "requestid.seq", 21, 1 } + { "client", 11, 0 }, + { "partition", 13, 1 }, + { "tpname", 15, 2 } }; /* Type Information: - [MINIMAL 20fb854c344bb02af8430115a676] (#deps: 3) - - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] + [MINIMAL 3f4b9832b556de33be4c31963879] (#deps: 2) - [MINIMAL 43f53a2be35b432cc735e9431a89] - [MINIMAL 84ce9c3d894c1483f859c00d5927] - [COMPLETE 2de91793545eff71a07b9e15f413] (#deps: 3) - - [COMPLETE 852fffc913b7ee54aadae7a1859a] + [COMPLETE 2992c8ff086f0c3d6eb4041c2b94] (#deps: 2) - [COMPLETE aca4d5a256d39713924333e85c6d] - [COMPLETE 023df3bd21223779cd1936cef928] */ #define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ - 0xf0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x20, 0xfb, 0x85, 0x4c, 0x34, 0x4b, 0xb0, 0x2a, 0xf8, 0x43, 0x01, \ - 0x15, 0xa6, 0x76, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ - 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, \ - 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x2d, 0xe9, 0x17, \ - 0x93, 0x54, 0x5e, 0xff, 0x71, 0xa0, 0x7b, 0x9e, 0x15, 0xf4, 0x13, 0x00, 0xce, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, \ - 0x7e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0xc0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x3f, 0x4b, 0x98, 0x32, 0xb5, 0x56, 0xde, 0x33, 0xbe, 0x4c, 0x31, \ + 0x96, 0x38, 0x79, 0x00, 0x75, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, \ + 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x29, 0x92, 0xc8, 0xff, 0x08, 0x6f, 0x0c, 0x3d, 0x6e, 0xb4, 0x04, \ + 0x1c, 0x2b, 0x94, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ 0x39, 0x00, 0x00, 0x00\ } -#define TYPE_INFO_CDR_SZ_DurableSupport_request 244u +#define TYPE_INFO_CDR_SZ_DurableSupport_request 196u #define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ - 0x3b, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf1, 0x20, 0xfb, 0x85, 0x4c, 0x34, 0x4b, 0xb0, \ - 0x2a, 0xf8, 0x43, 0x01, 0x15, 0xa6, 0x76, 0x00, 0x79, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, \ - 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x3c, 0xb0, 0x21, 0x74, 0x00, 0x00, 0x00, \ - 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, \ - 0x00, 0xae, 0xa4, 0x67, 0xe1, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, \ - 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, \ - 0x0f, 0xd5, 0x22, 0xa4, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, \ - 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, \ - 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ + 0xdb, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0x3f, 0x4b, 0x98, 0x32, 0xb5, 0x56, 0xde, \ + 0x33, 0xbe, 0x4c, 0x31, 0x96, 0x38, 0x79, 0x00, 0x71, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ + 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ + 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ - 0x0d, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf2, 0x2d, 0xe9, 0x17, 0x93, 0x54, 0x5e, 0xff, \ - 0x71, 0xa0, 0x7b, 0x9e, 0x15, 0xf4, 0x13, 0x00, 0xca, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x71, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0x29, 0x92, 0xc8, 0xff, 0x08, 0x6f, 0x0c, \ + 0x3d, 0x6e, 0xb4, 0x04, 0x1c, 0x2b, 0x94, 0x00, 0xbe, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, \ - 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x69, 0x64, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, \ - 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, \ - 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, \ - 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ - 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ - 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, \ - 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x75, 0x72, 0x61, \ - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf2, 0x2d, 0xe9, 0x17, \ - 0x93, 0x54, 0x5e, 0xff, 0x71, 0xa0, 0x7b, 0x9e, 0x15, 0xf4, 0x13, 0xf1, 0x20, 0xfb, 0x85, 0x4c, \ - 0x34, 0x4b, 0xb0, 0x2a, 0xf8, 0x43, 0x01, 0x15, 0xa6, 0x76, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, \ - 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, \ - 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ - 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, \ - 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, \ - 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, \ - 0xc0, 0x0d, 0x59, 0x27\ + 0x65, 0x73, 0x74, 0x00, 0x92, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, \ + 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, \ + 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, \ + 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x26, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, \ + 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, \ + 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x02, 0x3d, 0xf3, \ + 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x35, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0xf2, 0x29, 0x92, 0xc8, 0xff, 0x08, 0x6f, 0x0c, 0x3d, 0x6e, 0xb4, 0x04, 0x1c, 0x2b, 0x94, 0xf1, \ + 0x3f, 0x4b, 0x98, 0x32, 0xb5, 0x56, 0xde, 0x33, 0xbe, 0x4c, 0x31, 0x96, 0x38, 0x79, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, 0x3d, 0xf3, \ + 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, 0x9c, 0x3d, \ + 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_request 980u +#define TYPE_MAP_CDR_SZ_DurableSupport_request 698u const dds_topic_descriptor_t DurableSupport_request_desc = { .m_size = sizeof (DurableSupport_request), .m_align = dds_alignof (DurableSupport_request), .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 2u, + .m_nkeys = 3u, .m_typename = "DurableSupport::request", .m_keys = DurableSupport_request_keys, - .m_nops = 10, + .m_nops = 6, .m_ops = DurableSupport_request_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request }, @@ -810,7 +711,7 @@ static const uint32_t DurableSupport_response_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_response_content, _d), 2u, (12u << 16u) + 4u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 9 /* response_set_t */, 1, offsetof (DurableSupport_response_content, _u.set), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 24 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 13 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, DDS_OP_RTS, /* response_set_t */ @@ -818,13 +719,6 @@ static const uint32_t DurableSupport_response_ops [] = DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, partition), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, tpname), DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_response_set_t, flags), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_response_set_t, requestids), sizeof (DurableSupport_request_id_t), (4u << 16u) + 5u /* request_id_t */, - DDS_OP_RTS, - - /* request_id_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_id_t, client), 16u, - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_request_id_t, seq), DDS_OP_RTS, /* response_data_t */ @@ -838,168 +732,142 @@ static const uint32_t DurableSupport_response_ops [] = static const dds_key_descriptor_t DurableSupport_response_keys[1] = { - { "id", 45, 0 } + { "id", 34, 0 } }; /* Type Information: - [MINIMAL 930d49afed28329dc1db60ef7617] (#deps: 6) + [MINIMAL cf1872b677b74fe96238ec83b9a2] (#deps: 5) - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 6bc43f8b4741bc316540a0ef7b88] + - [MINIMAL 8691a7e3485bf0cdaeaf8f18ae96] - [MINIMAL 80455e796dd3437163cb532089da] - - [MINIMAL 82d72a61dfdf9b101310caab1550] - - [MINIMAL 28dabddcc42d4b6a3d640fd522a4] + - [MINIMAL 93ae2a1819f89109310333cdd898] - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE 75c71ab3f8db547e64f5b5212bc9] (#deps: 6) + [COMPLETE 41db4720b87e5b250e570da55eff] (#deps: 5) - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE 699d1f1db9ab7829fc4aa3be1028] + - [COMPLETE f9cb4201664aea89e45563ec138a] - [COMPLETE eec1bad6badde73f40ef199fedcc] - - [COMPLETE cb1a215003014659ba61115bccb5] - - [COMPLETE 852fffc913b7ee54aadae7a1859a] + - [COMPLETE df8d519cc0ad7b43f266d2a4d8e9] - [COMPLETE 008875599776c39ce0c1fe897846] */ #define TYPE_INFO_CDR_DurableSupport_response (const unsigned char []){ \ - 0x80, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x93, 0x0d, 0x49, 0xaf, 0xed, 0x28, 0x32, 0x9d, 0xc1, 0xdb, 0x60, \ - 0xef, 0x76, 0x17, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x50, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xa0, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0xcf, 0x18, 0x72, 0xb6, 0x77, 0xb7, 0x4f, 0xe9, 0x62, 0x38, 0xec, \ + 0x83, 0xb9, 0xa2, 0x00, 0x55, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, 0x41, 0xbc, 0x31, 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0x00, \ + 0xf1, 0x86, 0x91, 0xa7, 0xe3, 0x48, 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0x00, \ 0x7c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x82, 0xd7, 0x2a, 0x61, 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, 0x15, 0x50, 0x00, \ - 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, \ - 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ - 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x75, 0xc7, 0x1a, 0xb3, 0xf8, 0xdb, 0x54, 0x7e, 0x64, 0xf5, 0xb5, \ - 0x21, 0x2b, 0xc9, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ - 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x69, 0x9d, 0x1f, 0x1d, 0xb9, 0xab, 0x78, 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0x00, \ - 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, \ - 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xcb, 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, 0x5b, 0xcc, 0xb5, 0x00, \ - 0xbd, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, \ - 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x93, 0xae, 0x2a, 0x18, 0x19, 0xf8, 0x91, 0x09, 0x31, 0x03, 0x33, 0xcd, 0xd8, 0x98, 0x00, \ + 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, \ + 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0xa0, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x41, 0xdb, 0x47, \ + 0x20, 0xb8, 0x7e, 0x5b, 0x25, 0x0e, 0x57, 0x0d, 0xa5, 0x5e, 0xff, 0x00, 0x87, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ + 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xf9, 0xcb, 0x42, 0x01, 0x66, 0x4a, 0xea, \ + 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, 0x8a, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, \ + 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, \ + 0x43, 0xf2, 0x66, 0xd2, 0xa4, 0xd8, 0xe9, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ 0x57, 0x00, 0x00, 0x00\ } -#define TYPE_INFO_CDR_SZ_DurableSupport_response 388u +#define TYPE_INFO_CDR_SZ_DurableSupport_response 340u #define TYPE_MAP_CDR_DurableSupport_response (const unsigned char []){ \ - 0x58, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0x93, 0x0d, 0x49, 0xaf, 0xed, 0x28, 0x32, \ - 0x9d, 0xc1, 0xdb, 0x60, 0xef, 0x76, 0x17, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0xdc, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xf1, 0xcf, 0x18, 0x72, 0xb6, 0x77, 0xb7, 0x4f, \ + 0xe9, 0x62, 0x38, 0xec, 0x83, 0xb9, 0xa2, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, \ - 0x41, 0xbc, 0x31, 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x86, 0x91, 0xa7, 0xe3, 0x48, \ + 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, \ - 0x41, 0xbc, 0x31, 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x86, 0x91, 0xa7, 0xe3, 0x48, \ + 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ 0x54, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x82, 0xd7, 0x2a, 0x61, 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, 0x15, \ - 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ + 0x01, 0x00, 0xf1, 0x93, 0xae, 0x2a, 0x18, 0x19, 0xf8, 0x91, 0x09, 0x31, 0x03, 0x33, 0xcd, 0xd8, \ + 0x98, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x82, 0xd7, 0x2a, 0x61, \ - 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, 0x15, 0x50, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x93, 0xae, 0x2a, 0x18, \ + 0x19, 0xf8, 0x91, 0x09, 0x31, 0x03, 0x33, 0xcd, 0xd8, 0x98, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ 0x7e, 0x75, 0xc0, 0xed, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, \ - 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, \ - 0x01, 0x00, 0x00, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, \ - 0x22, 0xa4, 0x7c, 0x2c, 0x0f, 0x37, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, \ - 0x64, 0x0f, 0xd5, 0x22, 0xa4, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ - 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe0, 0x68, 0xc2, 0xde, 0xf1, \ - 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, \ - 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0xc3, 0x03, 0x00, 0x00, \ - 0x07, 0x00, 0x00, 0x00, 0xf2, 0x75, 0xc7, 0x1a, 0xb3, 0xf8, 0xdb, 0x54, 0x7e, 0x64, 0xf5, 0xb5, \ - 0x21, 0x2b, 0xc9, 0x00, 0x83, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ - 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x69, \ - 0x9d, 0x1f, 0x1d, 0xb9, 0xab, 0x78, 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, \ - 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x69, 0x9d, 0x1f, \ - 0x1d, 0xb9, 0xab, 0x78, 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0x00, 0xb3, 0x00, 0x00, 0x00, \ - 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, \ - 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xcb, \ - 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, 0x5b, 0xcc, 0xb5, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x00, \ - 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, \ - 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, \ - 0xed, 0xcc, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, \ + 0x58, 0x68, 0xd6, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, \ + 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, \ + 0x03, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xf2, 0x41, 0xdb, 0x47, 0x20, 0xb8, 0x7e, 0x5b, \ + 0x25, 0x0e, 0x57, 0x0d, 0xa5, 0x5e, 0xff, 0x00, 0x83, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, \ + 0x6f, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xf9, 0xcb, 0x42, 0x01, 0x66, 0x4a, 0xea, 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, \ + 0x8a, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, \ + 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, \ + 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ + 0xf2, 0xf9, 0xcb, 0x42, 0x01, 0x66, 0x4a, 0xea, 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, 0x8a, 0x00, \ + 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, \ + 0x74, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0xee, \ + 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x00, \ + 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, 0x43, 0xf2, 0x66, 0xd2, 0xa4, 0xd8, \ + 0xe9, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, \ + 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, \ + 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, \ + 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, 0x43, 0xf2, 0x66, \ + 0xd2, 0xa4, 0xd8, 0xe9, 0x88, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x27, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, \ - 0x00, 0xf2, 0xcb, 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, 0x5b, 0xcc, 0xb5, \ - 0xb9, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, \ - 0x5f, 0x74, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0x85, 0x2f, 0xff, 0xc9, \ - 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x64, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x85, 0x2f, \ - 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, 0x9a, 0x7a, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x02, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ - 0x46, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, \ - 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, \ - 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0x75, 0xc7, 0x1a, \ - 0xb3, 0xf8, 0xdb, 0x54, 0x7e, 0x64, 0xf5, 0xb5, 0x21, 0x2b, 0xc9, 0xf1, 0x93, 0x0d, 0x49, 0xaf, \ - 0xed, 0x28, 0x32, 0x9d, 0xc1, 0xdb, 0x60, 0xef, 0x76, 0x17, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, \ - 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x69, 0x9d, 0x1f, 0x1d, 0xb9, 0xab, 0x78, \ - 0x29, 0xfc, 0x4a, 0xa3, 0xbe, 0x10, 0x28, 0xf1, 0x6b, 0xc4, 0x3f, 0x8b, 0x47, 0x41, 0xbc, 0x31, \ - 0x65, 0x40, 0xa0, 0xef, 0x7b, 0x88, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ - 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, \ - 0x53, 0x20, 0x89, 0xda, 0xf2, 0xcb, 0x1a, 0x21, 0x50, 0x03, 0x01, 0x46, 0x59, 0xba, 0x61, 0x11, \ - 0x5b, 0xcc, 0xb5, 0xf1, 0x82, 0xd7, 0x2a, 0x61, 0xdf, 0xdf, 0x9b, 0x10, 0x13, 0x10, 0xca, 0xab, \ - 0x15, 0x50, 0xf2, 0x85, 0x2f, 0xff, 0xc9, 0x13, 0xb7, 0xee, 0x54, 0xaa, 0xda, 0xe7, 0xa1, 0x85, \ - 0x9a, 0xf1, 0x28, 0xda, 0xbd, 0xdc, 0xc4, 0x2d, 0x4b, 0x6a, 0x3d, 0x64, 0x0f, 0xd5, 0x22, 0xa4, \ - 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0xf1, \ - 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ + 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, \ + 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, \ + 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ + 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ + 0x53, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x20, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, \ + 0x61, 0x5f, 0x74, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, \ + 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, \ + 0xf2, 0x41, 0xdb, 0x47, 0x20, 0xb8, 0x7e, 0x5b, 0x25, 0x0e, 0x57, 0x0d, 0xa5, 0x5e, 0xff, 0xf1, \ + 0xcf, 0x18, 0x72, 0xb6, 0x77, 0xb7, 0x4f, 0xe9, 0x62, 0x38, 0xec, 0x83, 0xb9, 0xa2, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0xf9, 0xcb, 0x42, \ + 0x01, 0x66, 0x4a, 0xea, 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, 0x8a, 0xf1, 0x86, 0x91, 0xa7, 0xe3, \ + 0x48, 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, \ + 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, \ + 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, \ + 0x43, 0xf2, 0x66, 0xd2, 0xa4, 0xd8, 0xe9, 0xf1, 0x93, 0xae, 0x2a, 0x18, 0x19, 0xf8, 0x91, 0x09, \ + 0x31, 0x03, 0x33, 0xcd, 0xd8, 0x98, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, \ + 0xc1, 0xfe, 0x89, 0x78, 0x46, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, \ + 0x94, 0xaa, 0xe8, 0x44\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_response 1790u +#define TYPE_MAP_CDR_SZ_DurableSupport_response 1444u const dds_topic_descriptor_t DurableSupport_response_desc = { .m_size = sizeof (DurableSupport_response), @@ -1008,7 +876,7 @@ const dds_topic_descriptor_t DurableSupport_response_desc = .m_nkeys = 1u, .m_typename = "DurableSupport::response", .m_keys = DurableSupport_response_keys, - .m_nops = 22, + .m_nops = 17, .m_ops = DurableSupport_response_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_response, .sz = TYPE_INFO_CDR_SZ_DurableSupport_response }, From c538a644b9e73d8be7dbb3bee094ebb181728972 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Thu, 14 Dec 2023 21:10:19 +0100 Subject: [PATCH 191/207] Deliver data beads per data set to a dc, and allow delivery of data beads to a dc to be aborted Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 6 + src/durability/src/dds_durability.c | 308 +++++++++++++++--- src/durability/src/durablesupport.c | 217 ++++++------ 3 files changed, 395 insertions(+), 136 deletions(-) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index a101834c00..a430da24e1 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -259,6 +259,11 @@ typedef uint16_t DurableSupport_responsetype_t; #define DurableSupport_responsetype_t__alloc() \ ((DurableSupport_responsetype_t*) dds_alloc (sizeof (DurableSupport_responsetype_t))); +typedef uint64_t DurableSupport_delivery_id_t; + +#define DurableSupport_delivery_id_t__alloc() \ +((DurableSupport_delivery_id_t*) dds_alloc (sizeof (DurableSupport_delivery_id_t))); + typedef struct DurableSupport_request { DurableSupport_id_t client; @@ -279,6 +284,7 @@ dds_sample_free ((d), &DurableSupport_request_desc, (o)) #define DurableSupport_RESPONSETYPE_DATA 2 typedef struct DurableSupport_response_set_t { + DurableSupport_delivery_id_t delivery_id; char * partition; char * tpname; uint32_t flags; diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 7da86940d3..5cfad75937 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -32,6 +32,10 @@ #define DC_UNUSED_ARG(x) ((void)x) +#define DC_FLAG_SET_NOT_FOUND (((uint32_t)0x01) << 10) +#define DC_FLAG_SET_BEGIN (((uint32_t)0x01) << 11) +#define DC_FLAG_SET_END (((uint32_t)0x01) << 12) + #define TRACE(...) DDS_CLOG (DDS_LC_DUR, &domaingv->logconfig, __VA_ARGS__) /************* start of common functions ****************/ @@ -158,7 +162,7 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp } switch (response->body._d) { case DurableSupport_RESPONSETYPE_SET : - if ((l = snprintf(buf+i, n-i, "\"partition\":\"%s\", \"tpname\":\"%s\", \"flags\":\"0x%04" PRIx32 "\"", response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.flags)) < 0) { + if ((l = snprintf(buf+i, n-i, "\"delivery_id\":%" PRIu64 ",\"partition\":\"%s\", \"tpname\":\"%s\", \"flags\":\"0x%04" PRIx32 "\"", response->body._u.set.delivery_id, response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.flags)) < 0) { goto err; } i += (size_t)l; @@ -341,6 +345,27 @@ static const ddsrt_avl_ctreedef_t pending_requests_td = DDSRT_AVL_CTREEDEF_INITI static const ddsrt_fibheap_def_t pending_requests_fd = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct pending_request_t, fhnode), cmp_exp_time); + +struct delivery_ctx_t { + ddsrt_avl_node_t node; + DurableSupport_id_t id; /* id of the ds; key of the delivery context */ + uint64_t delivery_id; /* the id of the delivery by this ds; this is a monotonic increased sequence number */ + struct proxy_set_t *proxy_set; /* current proxy_set for which responses are being received, NULL if not known */ +}; + +static int delivery_ctx_cmp (const void *a, const void *b) +{ + return memcmp(a, b, 16); +} + +static void cleanup_delivery_ctx (void *n) +{ + struct delivery_ctx *delivery_ctx = (struct delivery_ctx *)n; + ddsrt_free(delivery_ctx); +} + +static const ddsrt_avl_ctreedef_t delivery_ctx_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct delivery_ctx_t, node), offsetof (struct delivery_ctx_t, id), delivery_ctx_cmp, 0); + /* Administration to keep track of the request readers of a ds * that can act as a target to send requests for historical data to.. * Based on this administration requests for historical data are published immediately, @@ -427,6 +452,8 @@ struct dc_t { ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on a ds that match with my request writer */ ddsrt_avl_ctree_t proxy_sets; /* tree containing the sets for which data has to be provided by a ds */ uint32_t nr_of_matched_dc_requests; /* indicates the number of matched dc_request readers for the dc_request writer of this client */ + struct delivery_ctx_t *delivery_ctx; /* reference to current delivery context, NULL if none */ + ddsrt_avl_ctree_t delivery_ctxs; /* table of delivery contexts, keyed by ds id */ }; static struct dc_t dc = { 0 }; /* static durable client structure */ @@ -1218,6 +1245,232 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } +static struct proxy_set_t *dc_create_proxy_set (struct dc_t *dc, const char *partition, const char *tpname) +{ + struct proxy_set_t *proxy_set = NULL; + + assert(partition); + assert(tpname); + proxy_set = (struct proxy_set_t *)ddsrt_malloc(sizeof(struct proxy_set_t)); + proxy_set->key.partition = ddsrt_strdup(partition); + proxy_set->key.tpname = ddsrt_strdup(tpname); + proxy_set->seq = 0; /* no pending request yet */ + ddsrt_avl_cinit(&proxy_set_reader_td, &proxy_set->readers); + ddsrt_avl_cinsert(&proxy_set_td, &dc->proxy_sets, proxy_set); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "proxy set '%s.%s' created\n", proxy_set->key.partition, proxy_set->key.tpname); + return proxy_set; +} + +static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, bool autocreate) +{ + struct proxy_set_key_t key; + struct proxy_set_t *proxy_set; + + assert(partition); + assert(tpname); + key.partition = ddsrt_strdup(partition); + key.tpname = ddsrt_strdup(tpname); + if (((proxy_set = ddsrt_avl_clookup (&proxy_set_td, &dc->proxy_sets, &key)) == NULL) && autocreate) { + proxy_set = dc_create_proxy_set(dc, partition, tpname); + } + ddsrt_free(key.partition); + ddsrt_free(key.tpname); + return proxy_set; +} + +/* lookup the delivery context for the ds identified by id + * if not found and autocreate=true, then create the delivery context */ +static struct delivery_ctx_t *dc_get_delivery_ctx (struct dc_t *dc, DurableSupport_id_t id, bool autocreate) +{ + struct delivery_ctx_t *delivery_ctx = NULL; + + if ((dc->delivery_ctx != NULL) && (memcmp(dc->delivery_ctx->id,id,16) == 0)) { + delivery_ctx = dc->delivery_ctx; + } else if (((delivery_ctx = ddsrt_avl_clookup (&delivery_ctx_td, &dc->delivery_ctxs, id)) == NULL) && autocreate) { + delivery_ctx = ddsrt_malloc(sizeof(struct delivery_ctx_t)); + memcpy(delivery_ctx->id,id,16); + delivery_ctx->delivery_id = 0; + delivery_ctx->proxy_set = NULL; + ddsrt_avl_cinsert(&delivery_ctx_td, &dc->delivery_ctxs, delivery_ctx); + } + return delivery_ctx; +} + +/* Remove the current delivery */ +static void dc_remove_current_delivery (struct dc_t *dc) +{ + struct delivery_ctx_t *delivery_ctx; + ddsrt_avl_dpath_t dpath; + + if (dc->delivery_ctx) { + + if ((delivery_ctx = ddsrt_avl_clookup_dpath(&delivery_ctx_td, &dc->delivery_ctxs, dc->delivery_ctx->id, &dpath)) != NULL) { + assert(dc->delivery_ctx == delivery_ctx); + /* remove the delivery ctx from the tree */ + ddsrt_avl_cdelete_dpath(&delivery_ctx_td, &dc->delivery_ctxs, delivery_ctx, &dpath); + cleanup_delivery_ctx(delivery_ctx); + } + /* reset the current delivery ctx */ + dc->delivery_ctx = NULL; + } +} + +/* Abort the current delivery (i.e., dc->delivery_ctx) */ +static void dc_abort_current_delivery (struct dc_t *dc) +{ + char id_str[37]; + + assert(dc->delivery_ctx); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "aborting delivery %" PRIu64 " from ds \"%s\"\n", + dc->delivery_ctx->delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str)); + /* todo: reschedule the proxy set */ + + /* remove the current delivery ctx */ + dc_remove_current_delivery(dc); +} + +/* open the delivery context for the ds identified by id */ +static void dc_open_delivery (struct dc_t *dc, DurableSupport_response *response) +{ + char id_str[37]; + uint64_t delivery_id; + + assert(response); + assert(response->body._u.set.flags & DC_FLAG_SET_BEGIN); + delivery_id = response->body._u.set.delivery_id; + /* now create the new delivery context */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, true)) == NULL) { + DDS_ERROR("unable to create an delivery context for ds \"%s\" and delivery id %" PRIu64 "\n", dc_stringify_id(response->id, id_str), delivery_id); + abort(); + } + /* set the delivery_id and proxy set for this delivery context */ + dc->delivery_ctx->delivery_id = delivery_id; + if ((dc->delivery_ctx->proxy_set = dc_get_proxy_set(dc, response->body._u.set.partition, response->body._u.set.tpname, false)) == NULL) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "no proxy set for \"%s.%s\" found, ignore delivery\n", response->body._u.set.partition, response->body._u.set.tpname); + /* abort this delivery context */ + dc_abort_current_delivery(dc); + return; + } + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s\" opened\n", + delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str), dc->delivery_ctx->proxy_set->key.partition, dc->delivery_ctx->proxy_set->key.tpname); +} + +/* close the current delivery context for the ds identified by id */ +static void dc_close_delivery (struct dc_t *dc, DurableSupport_id_t id, DurableSupport_response_set_t *response_set) +{ + char id_str[37]; + + DC_UNUSED_ARG(response_set); + DC_UNUSED_ARG(id); + assert(response_set); + assert(response_set->flags & DC_FLAG_SET_END); + assert(memcmp(dc->delivery_ctx->id,id,16) == 0); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s\" closed\n", + dc->delivery_ctx->delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str), dc->delivery_ctx->proxy_set->key.partition, dc->delivery_ctx->proxy_set->key.tpname); + /* todo: mark the proxy set as complete */ + + /* remove current delivery ctx */ + dc_remove_current_delivery(dc); +} + +static void dc_process_set_response_begin(struct dc_t *dc, DurableSupport_response *response) +{ + assert(response); + assert(response->body._d == DurableSupport_RESPONSETYPE_SET); + /* A response set begin is received. If there already exists an open delivery + * context for this ds which has not been ended correctly, then this + * previous delivery has failed and needs to be aborted. */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, false)) != NULL) { + assert(memcmp(dc->delivery_ctx->id, response->id, 16) == 0); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "current open delivery %" PRIu64 " has missed an end\n", dc->delivery_ctx->delivery_id); + /* abort the currently open delivery */ + dc_abort_current_delivery(dc); + } + assert(dc->delivery_ctx == NULL); + /* open the new delivery */ + dc_open_delivery(dc, response); +} + +static void dc_process_set_response_end (struct dc_t *dc, DurableSupport_response *response) +{ + char id_str[37]; + + /* A response set end is received. Lookup the existing delivery context for this ds */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, false)) != NULL) { + assert(memcmp(dc->delivery_ctx->id, response->id, 16) == 0); + /* verify that this response set end belongs the currently opened delivery. + * by comparing the delivery_id. If they do not match, then this response + * set end does not belong to the currently opened set. This means that + * delivery of the currently opened set has failed and needs to be aborted. */ + if (dc->delivery_ctx->delivery_id != response->body._u.set.delivery_id) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "current open delivery %" PRIu64 " does not belong to end delivery %" PRIu64 "\n", + dc->delivery_ctx->delivery_id, response->body._u.set.delivery_id); + /* abort the currently open delivery */ + dc_abort_current_delivery(dc); + } else { + /* the end belongs to the correct begin; we have received all data for the set + * and can properly close the delivery */ + dc_close_delivery(dc, response->id, &response->body._u.set); + } + } else { + /* an end was received without a begin; no need to abort */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "end delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s\" received, but no corresponding open delivery found\n", + response->body._u.set.delivery_id, dc_stringify_id(response->id, id_str), response->body._u.set.partition, response->body._u.set.tpname); + } +} + +static void dc_process_set_response_not_found(struct dc_t *dc, DurableSupport_response *response) +{ + /* the set indicated in the response does not exist at the ds. + * This can for example happen when a transient reader has been created, + * but no transient writer exists. In such cases we can mark the reader + * as complete. + */ + DC_UNUSED_ARG(dc); + DC_UNUSED_ARG(response); +} + +static void dc_process_set_response (struct dc_t *dc, DurableSupport_response *response) +{ + assert(response->body._d == DurableSupport_RESPONSETYPE_SET); + if (response->body._u.set.flags & DC_FLAG_SET_BEGIN) { + dc_process_set_response_begin(dc, response); + } else if (response->body._u.set.flags & DC_FLAG_SET_END) { + dc_process_set_response_end(dc, response); + } else if (response->body._u.set.flags & DC_FLAG_SET_NOT_FOUND) { + dc_process_set_response_not_found(dc, response); + } else { + DDS_ERROR("invalid response set flag 0x%04" PRIx32, response->body._u.set.flags); + } +} + +static void dc_process_data_response (struct dc_t *dc, DurableSupport_response *response) +{ + struct proxy_set_t *proxy_set = NULL; + + /* TODO: + * A DS also has a response reader (by virtue of the CycloneDDS instance it runs). + * Currently, a DS therefore also receives responses that it sends itself. + * Because they is no proxy set the data is not injected, but I still like + * to have that a ds never receives responses. */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, false)) == NULL) { + /* There is no delivery context for this data, which means that this node + * did not request data for this set. If we do receive data, then we + * can safely ignore it. */ + return; + } + if ((proxy_set = dc->delivery_ctx->proxy_set) == NULL) { + /* There is no proxy set for this data, which means that this node + * did not request data for this set. If we do receive data, then we + * can safely ignore it. */ + return; + } + /* A response_set begin has been received. Because data delivery is reliable, + * we are sure that we missed no responses, so the data response that we received + * must belong to the proxy set. */ +// printf("LH *** inject data from proxy set \"%s.%s\"\n", proxy_set->key.partition, proxy_set->key.tpname); +} + static int dc_process_response (dds_entity_t rd, struct dc_t *dc) { #define MAX_SAMPLES 100 @@ -1246,6 +1499,17 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) /* LH: TODO: add statistics for responses */ DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dc_response %s%s\n", str, (len >= sizeof(str)) ? "..(trunc)" : ""); + /* deliver the received response to the readers belonging to the proxy set */ + switch (response->body._d) { + case DurableSupport_RESPONSETYPE_SET: + dc_process_set_response(dc, response); + break; + case DurableSupport_RESPONSETYPE_DATA: + dc_process_data_response(dc, response); + break; + default : + DDS_ERROR("invalid response type %" PRIu16, response->body._d); + } } } (void)dds_return_loan(rd, samples, samplecount); @@ -1255,39 +1519,6 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } -static struct proxy_set_t *dc_create_proxy_set (struct dc_t *dc, const char *partition, const char *tpname) -{ - struct proxy_set_t *proxy_set = NULL; - - assert(partition); - assert(tpname); - proxy_set = (struct proxy_set_t *)ddsrt_malloc(sizeof(struct proxy_set_t)); - proxy_set->key.partition = ddsrt_strdup(partition); - proxy_set->key.tpname = ddsrt_strdup(tpname); - proxy_set->seq = 0; /* no pending request yet */ - ddsrt_avl_cinit(&proxy_set_reader_td, &proxy_set->readers); - ddsrt_avl_cinsert(&proxy_set_td, &dc->proxy_sets, proxy_set); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "proxy set '%s.%s' created\n", proxy_set->key.partition, proxy_set->key.tpname); - return proxy_set; -} - -static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, bool autocreate) -{ - struct proxy_set_key_t key; - struct proxy_set_t *proxy_set; - - assert(partition); - assert(tpname); - key.partition = ddsrt_strdup(partition); - key.tpname = ddsrt_strdup(tpname); - if (((proxy_set = ddsrt_avl_clookup (&proxy_set_td, &dc->proxy_sets, &key)) == NULL) && autocreate) { - proxy_set = dc_create_proxy_set(dc, partition, tpname); - } - ddsrt_free(key.partition); - ddsrt_free(key.tpname); - return proxy_set; -} - /* add the reader tree of readers for this proxy set */ static void dc_register_reader_to_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, dds_guid_t guid, struct dds_rhc *rhc) { @@ -1589,8 +1820,8 @@ static uint32_t recv_handler (void *a) } /* set the request listener to learn about the existence of matching request readers. - * Because matches may have occurred already before */ - + * This purpose of this function is acquire matched subscriptions for late joining + * request writers. */ static dds_return_t activate_request_listener (struct dc_t *dc) { dds_return_t rc, ret; @@ -1674,6 +1905,8 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom dc.cfg.ident = ddsrt_strdup(DEFAULT_IDENT); dc.selected_request_reader_ih = DDS_HANDLE_NIL; dc.nr_of_matched_dc_requests = 0; + dc.delivery_ctx = NULL; /* initially no current open delivery context */ + ddsrt_avl_cinit(&delivery_ctx_td, &dc.delivery_ctxs); ddsrt_avl_cinit(&server_td, &dc.servers); ddsrt_avl_cinit(&matched_request_readers_td, &dc.matched_request_readers); ddsrt_avl_cinit(&pending_requests_td, &dc.pending_requests); @@ -1738,7 +1971,7 @@ dds_return_t dds_durability_fini (void) return DDS_RETCODE_OK; } if (dc.com) { - /* indicate the the durable client is teminating */ + /* indicate the the durable client is terminating */ ddsrt_atomic_st32 (&dc.termflag, 1); /* force the dc thread to terminate */ if ((rc = dds_waitset_set_trigger(dc.com->ws, true)) < 0) { @@ -1751,6 +1984,7 @@ dds_return_t dds_durability_fini (void) dds_delete_listener(dc.request_listener); dds_delete_listener(dc.quorum_listener); dc_com_free(dc.com); + ddsrt_avl_cfree(&delivery_ctx_td, &dc.delivery_ctxs, cleanup_delivery_ctx); ddsrt_cond_destroy(&dc.pending_request_cond); ddsrt_mutex_destroy(&dc.pending_request_mutex); ddsrt_avl_cfree(&proxy_set_td, &dc.proxy_sets, cleanup_proxy_set); diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index c15192752f..e59f18b323 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -711,11 +711,12 @@ static const uint32_t DurableSupport_response_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_response_content, _d), 2u, (12u << 16u) + 4u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 9 /* response_set_t */, 1, offsetof (DurableSupport_response_content, _u.set), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 13 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 15 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, DDS_OP_RTS, /* response_set_t */ DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_response_set_t, delivery_id), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, partition), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, tpname), DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_response_set_t, flags), @@ -732,142 +733,161 @@ static const uint32_t DurableSupport_response_ops [] = static const dds_key_descriptor_t DurableSupport_response_keys[1] = { - { "id", 34, 0 } + { "id", 36, 0 } }; /* Type Information: - [MINIMAL cf1872b677b74fe96238ec83b9a2] (#deps: 5) + [MINIMAL 730b9fd245b7a2458badcdadd452] (#deps: 6) - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 8691a7e3485bf0cdaeaf8f18ae96] + - [MINIMAL b2788efd3d9c71afbf128dd8d568] - [MINIMAL 80455e796dd3437163cb532089da] - - [MINIMAL 93ae2a1819f89109310333cdd898] + - [MINIMAL 26fb4226a2ccc89e6a040bf4add4] + - [MINIMAL d8398b259af5a04792e296996c27] - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE 41db4720b87e5b250e570da55eff] (#deps: 5) + [COMPLETE 11d82f7f8e658cff91d8836b578f] (#deps: 6) - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE f9cb4201664aea89e45563ec138a] + - [COMPLETE b6edd532689bbbb0dee0ee93c7ae] - [COMPLETE eec1bad6badde73f40ef199fedcc] - - [COMPLETE df8d519cc0ad7b43f266d2a4d8e9] + - [COMPLETE 6c90b4bf595ec04bb56d1fd6e2b5] + - [COMPLETE 7b005a124ff7bda9c39eb4003556] - [COMPLETE 008875599776c39ce0c1fe897846] */ #define TYPE_INFO_CDR_DurableSupport_response (const unsigned char []){ \ - 0x50, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xa0, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0xcf, 0x18, 0x72, 0xb6, 0x77, 0xb7, 0x4f, 0xe9, 0x62, 0x38, 0xec, \ - 0x83, 0xb9, 0xa2, 0x00, 0x55, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x80, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x73, 0x0b, 0x9f, 0xd2, 0x45, 0xb7, 0xa2, 0x45, 0x8b, 0xad, 0xcd, \ + 0xad, 0xd4, 0x52, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x86, 0x91, 0xa7, 0xe3, 0x48, 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0x00, \ + 0xf1, 0xb2, 0x78, 0x8e, 0xfd, 0x3d, 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0x00, \ 0x7c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x93, 0xae, 0x2a, 0x18, 0x19, 0xf8, 0x91, 0x09, 0x31, 0x03, 0x33, 0xcd, 0xd8, 0x98, 0x00, \ - 0x47, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, \ - 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0xa0, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x41, 0xdb, 0x47, \ - 0x20, 0xb8, 0x7e, 0x5b, 0x25, 0x0e, 0x57, 0x0d, 0xa5, 0x5e, 0xff, 0x00, 0x87, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xf9, 0xcb, 0x42, 0x01, 0x66, 0x4a, 0xea, \ - 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, 0x8a, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, \ - 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, \ - 0x43, 0xf2, 0x66, 0xd2, 0xa4, 0xd8, 0xe9, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x26, 0xfb, 0x42, 0x26, 0xa2, 0xcc, 0xc8, 0x9e, 0x6a, 0x04, 0x0b, 0xf4, 0xad, 0xd4, 0x00, \ + 0x67, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ + 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ + 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x11, 0xd8, 0x2f, 0x7f, 0x8e, 0x65, 0x8c, 0xff, 0x91, 0xd8, 0x83, \ + 0x6b, 0x57, 0x8f, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xb6, 0xed, 0xd5, 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, 0xe0, 0xee, 0x93, 0xc7, 0xae, 0x00, \ + 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, \ + 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, 0xc0, 0x4b, 0xb5, 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0x00, \ + 0xbc, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, \ + 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ 0x57, 0x00, 0x00, 0x00\ } -#define TYPE_INFO_CDR_SZ_DurableSupport_response 340u +#define TYPE_INFO_CDR_SZ_DurableSupport_response 388u #define TYPE_MAP_CDR_DurableSupport_response (const unsigned char []){ \ - 0xdc, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xf1, 0xcf, 0x18, 0x72, 0xb6, 0x77, 0xb7, 0x4f, \ - 0xe9, 0x62, 0x38, 0xec, 0x83, 0xb9, 0xa2, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x20, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0x73, 0x0b, 0x9f, 0xd2, 0x45, 0xb7, 0xa2, \ + 0x45, 0x8b, 0xad, 0xcd, 0xad, 0xd4, 0x52, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x86, 0x91, 0xa7, 0xe3, 0x48, \ - 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xb2, 0x78, 0x8e, 0xfd, 0x3d, \ + 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x86, 0x91, 0xa7, 0xe3, 0x48, \ - 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0xb2, 0x78, 0x8e, 0xfd, 0x3d, \ + 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ 0x54, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x93, 0xae, 0x2a, 0x18, 0x19, 0xf8, 0x91, 0x09, 0x31, 0x03, 0x33, 0xcd, 0xd8, \ - 0x98, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ + 0x01, 0x00, 0xf1, 0x26, 0xfb, 0x42, 0x26, 0xa2, 0xcc, 0xc8, 0x9e, 0x6a, 0x04, 0x0b, 0xf4, 0xad, \ + 0xd4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x93, 0xae, 0x2a, 0x18, \ - 0x19, 0xf8, 0x91, 0x09, 0x31, 0x03, 0x33, 0xcd, 0xd8, 0x98, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x7e, 0x75, 0xc0, 0xed, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, \ - 0x58, 0x68, 0xd6, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, \ - 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, \ - 0x03, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xf2, 0x41, 0xdb, 0x47, 0x20, 0xb8, 0x7e, 0x5b, \ - 0x25, 0x0e, 0x57, 0x0d, 0xa5, 0x5e, 0xff, 0x00, 0x83, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, \ - 0x6f, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xf9, 0xcb, 0x42, 0x01, 0x66, 0x4a, 0xea, 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, \ - 0x8a, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, \ - 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, \ - 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ - 0xf2, 0xf9, 0xcb, 0x42, 0x01, 0x66, 0x4a, 0xea, 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, 0x8a, 0x00, \ - 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, \ - 0x74, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0xee, \ - 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x00, \ - 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, 0x43, 0xf2, 0x66, 0xd2, 0xa4, 0xd8, \ - 0xe9, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, \ - 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, \ - 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x26, 0xfb, 0x42, 0x26, \ + 0xa2, 0xcc, 0xc8, 0x9e, 0x6a, 0x04, 0x0b, 0xf4, 0xad, 0xd4, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ + 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x7c, 0x4b, 0x99, \ + 0xfe, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x7e, 0x75, 0xc0, 0xed, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, \ + 0x58, 0x68, 0xd6, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ + 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, \ + 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \ + 0xee, 0x26, 0x90, 0x8b, 0x7f, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0x11, 0xd8, 0x2f, \ + 0x7f, 0x8e, 0x65, 0x8c, 0xff, 0x91, 0xd8, 0x83, 0x6b, 0x57, 0x8f, 0x00, 0x83, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xb6, 0xed, 0xd5, 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, \ + 0xe0, 0xee, 0x93, 0xc7, 0xae, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, \ + 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, \ + 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x10, 0x02, 0x00, 0x00, 0xf2, 0xb6, 0xed, 0xd5, 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, 0xe0, 0xee, \ + 0x93, 0xc7, 0xae, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ + 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, \ + 0x11, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, \ + 0xcc, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, 0xc0, 0x4b, 0xb5, \ + 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, \ + 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, \ + 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, \ + 0xc0, 0x4b, 0xb5, 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0xb8, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, \ - 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, 0x43, 0xf2, 0x66, \ - 0xd2, 0xa4, 0xd8, 0xe9, 0x88, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x27, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ - 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, \ - 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, \ - 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ - 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ + 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x7b, \ + 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, \ + 0x73, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, \ + 0x00, 0x35, 0x56, 0x00, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, \ + 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, \ + 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, \ 0x53, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x20, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, \ 0x61, 0x5f, 0x74, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, \ - 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, \ - 0xf2, 0x41, 0xdb, 0x47, 0x20, 0xb8, 0x7e, 0x5b, 0x25, 0x0e, 0x57, 0x0d, 0xa5, 0x5e, 0xff, 0xf1, \ - 0xcf, 0x18, 0x72, 0xb6, 0x77, 0xb7, 0x4f, 0xe9, 0x62, 0x38, 0xec, 0x83, 0xb9, 0xa2, 0xf2, 0xac, \ + 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0xf2, 0x11, 0xd8, 0x2f, 0x7f, 0x8e, 0x65, 0x8c, 0xff, 0x91, 0xd8, 0x83, 0x6b, 0x57, 0x8f, 0xf1, \ + 0x73, 0x0b, 0x9f, 0xd2, 0x45, 0xb7, 0xa2, 0x45, 0x8b, 0xad, 0xcd, 0xad, 0xd4, 0x52, 0xf2, 0xac, \ 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0xf9, 0xcb, 0x42, \ - 0x01, 0x66, 0x4a, 0xea, 0x89, 0xe4, 0x55, 0x63, 0xec, 0x13, 0x8a, 0xf1, 0x86, 0x91, 0xa7, 0xe3, \ - 0x48, 0x5b, 0xf0, 0xcd, 0xae, 0xaf, 0x8f, 0x18, 0xae, 0x96, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0xb6, 0xed, 0xd5, \ + 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, 0xe0, 0xee, 0x93, 0xc7, 0xae, 0xf1, 0xb2, 0x78, 0x8e, 0xfd, \ + 0x3d, 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, \ 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, \ - 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0xdf, 0x8d, 0x51, 0x9c, 0xc0, 0xad, 0x7b, \ - 0x43, 0xf2, 0x66, 0xd2, 0xa4, 0xd8, 0xe9, 0xf1, 0x93, 0xae, 0x2a, 0x18, 0x19, 0xf8, 0x91, 0x09, \ - 0x31, 0x03, 0x33, 0xcd, 0xd8, 0x98, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, \ - 0xc1, 0xfe, 0x89, 0x78, 0x46, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, \ - 0x94, 0xaa, 0xe8, 0x44\ + 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, 0xc0, \ + 0x4b, 0xb5, 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0xf1, 0x26, 0xfb, 0x42, 0x26, 0xa2, 0xcc, 0xc8, 0x9e, \ + 0x6a, 0x04, 0x0b, 0xf4, 0xad, 0xd4, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, \ + 0x9e, 0xb4, 0x00, 0x35, 0x56, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, \ + 0x96, 0x99, 0x6c, 0x27, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, \ + 0x89, 0x78, 0x46, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, \ + 0xe8, 0x44\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_response 1444u +#define TYPE_MAP_CDR_SZ_DurableSupport_response 1666u const dds_topic_descriptor_t DurableSupport_response_desc = { .m_size = sizeof (DurableSupport_response), @@ -876,10 +896,9 @@ const dds_topic_descriptor_t DurableSupport_response_desc = .m_nkeys = 1u, .m_typename = "DurableSupport::response", .m_keys = DurableSupport_response_keys, - .m_nops = 17, + .m_nops = 18, .m_ops = DurableSupport_response_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_response, .sz = TYPE_INFO_CDR_SZ_DurableSupport_response }, .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_response, .sz = TYPE_MAP_CDR_SZ_DurableSupport_response } }; - From 7e6c1f85d8b4412f6122017340fe2e119810bf86 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Wed, 20 Dec 2023 09:16:02 +0100 Subject: [PATCH 192/207] Data delivery to local readers Signed-off-by: TheFixer --- src/durability/src/dds_durability.c | 107 +++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 3 deletions(-) diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 5cfad75937..1dc1617c18 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -22,6 +22,7 @@ #include "dds__writer.h" #include "dds/ddsi/ddsi_endpoint.h" #include "dds/ddsrt/avl.h" +#include "dds/ddsi/ddsi_serdata.h" #define DEFAULT_QOURUM 1 #define DEFAULT_IDENT "durable_support" @@ -236,6 +237,7 @@ static int cmp_proxy_set_reader (const void *a, const void *b) struct proxy_set_reader_t { ddsrt_avl_node_t node; struct proxy_set_reader_key_t key; + dds_entity_t reader; struct dds_rhc *rhc; }; @@ -1444,9 +1446,57 @@ static void dc_process_set_response (struct dc_t *dc, DurableSupport_response *r } } +#if 0 +int dc_deliver_blob () +{ +} +#endif + +/* todo: this function is hared between ds and client */ +static enum ddsi_serdata_kind get_serdata_kind (uint8_t kind) +{ + enum ddsi_serdata_kind result = SDK_EMPTY; + + if (kind == 0) { + result = SDK_EMPTY; + } else if (kind == 1) { + result = SDK_KEY; + } else if (kind == 2) { + result = SDK_DATA; + } else { + DDS_ERROR("Invalid serdata kind %d", kind); + abort(); + } + return result; +} + +/* These are the offsets used in the data responses. + * TODO: These definitions should actually be shared between the ds and the client. + */ +#define RESPONSE_HEADER_OFFSET_WT 8 +#define RESPONSE_HEADER_OFFSET_SEQNUM 16 +#define RESPONSE_HEADER_OFFSET_WRITER_GUID 24 +#define RESPONSE_HEADER_OFFSET_SERDATA_KIND 40 +#define RESPONSE_HEADER_OFFSET_SERDATA 41 + + static void dc_process_data_response (struct dc_t *dc, DurableSupport_response *response) { struct proxy_set_t *proxy_set = NULL; + ddsrt_avl_citer_t it; + const struct ddsi_sertype *sertype; + struct ddsi_serdata *serdata; + uint32_t response_size, serdata_size;; + uint32_t serdata_offset; + ddsrt_iovec_t data_out; + int64_t wt; + uint64_t seqnum; + enum ddsi_serdata_kind serdata_kind; + dds_guid_t wguid; + dds_return_t ret = DDS_RETCODE_OK; + bool autodispose; + struct proxy_set_reader_t *proxy_set_rd; + char id_str[37]; /* TODO: * A DS also has a response reader (by virtue of the CycloneDDS instance it runs). @@ -1468,7 +1518,57 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * /* A response_set begin has been received. Because data delivery is reliable, * we are sure that we missed no responses, so the data response that we received * must belong to the proxy set. */ -// printf("LH *** inject data from proxy set \"%s.%s\"\n", proxy_set->key.partition, proxy_set->key.tpname); + response_size = response->body._u.data.blob._length; + serdata_offset = ddsrt_fromBE4u(*((uint32_t *)response->body._u.data.blob._buffer)); + wt = ddsrt_fromBE8(*((int64_t *)(response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_WT))); + seqnum = ddsrt_fromBE8u(*((uint64_t *)(response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_SEQNUM))); + memcpy(&wguid.v, response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_WRITER_GUID, 16); + serdata_kind = get_serdata_kind(*((uint8_t *)response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_SERDATA_KIND)); + /* We could now potentially figure out if the response that has been received + * contains fields that we cannot interpret. We can find that out by comparing + * the received response_offset with my own RESPONSE_HEADER_OFFSET_SERDATA. + * If serdata_offset > RESPONSE_HEADER_OFFSET_SERDATA then this is an indication + * that the ds has more fields than this client can interpret. */ + /* get the serdata */ + serdata_size = response_size - serdata_offset; + data_out.iov_len = serdata_size; + data_out.iov_base = response->body._u.data.blob._buffer + serdata_offset; + /* now deliver the data to the local readers that have an interest in the data */ + for (proxy_set_rd = ddsrt_avl_citer_first (&proxy_set_reader_td, &proxy_set->readers, &it); proxy_set_rd; proxy_set_rd = ddsrt_avl_citer_next (&it)) { + dds_entity_t reader = proxy_set_rd->reader; + /* in order to insert the data in the rhc of the reader we first + * need to resolve the type of the reader */ + if ((ret = dds_get_entity_sertype (reader, &sertype)) < 0) { + /* We failed to get the sertype. If it happens I do not consider + * this my problem, it is a problem in CycloneDDS. + * For now I silently ignore the data. After all, I cannot + * deliver the data to this reader! */ + continue; + } + /* get the serdata */ + if ((serdata = ddsi_serdata_from_ser_iov (sertype, serdata_kind, 1, &data_out, serdata_size)) == NULL) { + /* Failed to get the serdata. If it happens I do not consider + * this my problem, it is a problem in CycloneDDS. The only thing + * I can do is to handle this case. For now I silently ignore the data. + */ + goto err_serdata; + } + serdata->sequence_number = seqnum; + serdata->timestamp.v = wt; + memcpy(&serdata->writer_guid, &wguid, 16); + autodispose = false; /* TODO: we have to retrieve the autodispose setting of the writer! */ + if ((ret = dds_reader_store_historical_serdata(reader, wguid, autodispose, serdata)) != DDS_RETCODE_OK) { + DDS_ERROR("Failed to deliver historical data to reader \"%s\" [%s]\n", dc_stringify_id(proxy_set_rd->key.guid.v, id_str), dds_strretcode(ret)); + goto err_store_historical_serdata; + } + ddsi_serdata_to_ser_unref(serdata, &data_out); + } + return; + +err_store_historical_serdata: + ddsi_serdata_to_ser_unref(serdata, &data_out); +err_serdata: + return; } static int dc_process_response (dds_entity_t rd, struct dc_t *dc) @@ -1520,7 +1620,7 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) } /* add the reader tree of readers for this proxy set */ -static void dc_register_reader_to_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, dds_guid_t guid, struct dds_rhc *rhc) +static void dc_register_reader_to_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, dds_guid_t guid, dds_entity_t reader, struct dds_rhc *rhc) { struct proxy_set_reader_t *proxy_set_rd; struct proxy_set_reader_key_t key; @@ -1530,6 +1630,7 @@ static void dc_register_reader_to_proxy_set (struct dc_t *dc, struct proxy_set_t if ((proxy_set_rd = ddsrt_avl_clookup (&proxy_set_reader_td, &proxy_set->readers, &key)) == NULL) { proxy_set_rd = (struct proxy_set_reader_t *)ddsrt_malloc(sizeof(struct proxy_set_reader_t)); proxy_set_rd->key.guid = guid; + proxy_set_rd->reader = reader; proxy_set_rd->rhc = rhc; ddsrt_avl_cinsert(&proxy_set_reader_td, &proxy_set->readers, proxy_set_rd); DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "reader \"%s\" added to proxy set '%s.%s'\n", dc_stringify_id(guid.v, id_str), proxy_set->key.partition, proxy_set->key.tpname); @@ -1597,7 +1698,7 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade * We do this BEFORE we send the request, so that we are sure * that when we receive the response (possibly immediately after * sending the request) the reader and rhc are present */ - dc_register_reader_to_proxy_set(dc, proxy_set, guid, rhc); + dc_register_reader_to_proxy_set(dc, proxy_set, guid, reader, rhc); /* send a request for this proxy set */ if ((rc = dc_com_request_write(dc->com, proxy_set->key.partition, proxy_set->key.tpname)) != DDS_RETCODE_OK) { DDS_ERROR("Failed to publish dc_request for proxy set %s.%s\n", proxy_set->key.partition, proxy_set->key.tpname); From ff823efdaf149aeb919d8ef4b160ae434afcd39f Mon Sep 17 00:00:00 2001 From: TheFixer Date: Sat, 30 Dec 2023 21:59:03 +0100 Subject: [PATCH 193/207] Encode the writer's autodispose setting in response beads Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 6 + src/durability/src/dds_durability.c | 15 +- src/durability/src/durablesupport.c | 372 ++++++++++-------- 3 files changed, 214 insertions(+), 179 deletions(-) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index a430da24e1..837ca56dfc 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -177,6 +177,11 @@ typedef struct DurableSupport_set_t dds_sequence_DurableSupport_id_t addressees; } DurableSupport_set_t; +typedef struct DurableSupport_writer_properties_t +{ + bool autodispose; +} DurableSupport_writer_properties_t; + #ifndef DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED #define DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED typedef struct dds_sequence_DurableSupport_range @@ -197,6 +202,7 @@ typedef struct dds_sequence_DurableSupport_range typedef struct DurableSupport_writer_t { DurableSupport_id_t id; + struct DurableSupport_writer_properties_t properties; uint32_t flags; dds_sequence_DurableSupport_range ranges; } DurableSupport_writer_t; diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 1dc1617c18..d79aba4ad6 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -1473,11 +1473,12 @@ static enum ddsi_serdata_kind get_serdata_kind (uint8_t kind) /* These are the offsets used in the data responses. * TODO: These definitions should actually be shared between the ds and the client. */ -#define RESPONSE_HEADER_OFFSET_WT 8 -#define RESPONSE_HEADER_OFFSET_SEQNUM 16 -#define RESPONSE_HEADER_OFFSET_WRITER_GUID 24 -#define RESPONSE_HEADER_OFFSET_SERDATA_KIND 40 -#define RESPONSE_HEADER_OFFSET_SERDATA 41 +#define RESPONSE_HEADER_OFFSET_WT 8 +#define RESPONSE_HEADER_OFFSET_SEQNUM 16 +#define RESPONSE_HEADER_OFFSET_WRITER_GUID 24 +#define RESPONSE_HEADER_OFFSET_SERDATA_KIND 40 +#define RESPONSE_HEADER_OFFSET_SERDATA_AUTODISPOSE 41 +#define RESPONSE_HEADER_OFFSET_SERDATA 42 static void dc_process_data_response (struct dc_t *dc, DurableSupport_response *response) @@ -1494,7 +1495,7 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * enum ddsi_serdata_kind serdata_kind; dds_guid_t wguid; dds_return_t ret = DDS_RETCODE_OK; - bool autodispose; + bool autodispose = 0; struct proxy_set_reader_t *proxy_set_rd; char id_str[37]; @@ -1523,6 +1524,7 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * wt = ddsrt_fromBE8(*((int64_t *)(response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_WT))); seqnum = ddsrt_fromBE8u(*((uint64_t *)(response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_SEQNUM))); memcpy(&wguid.v, response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_WRITER_GUID, 16); + autodispose = *((uint8_t *)response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_SERDATA_AUTODISPOSE); serdata_kind = get_serdata_kind(*((uint8_t *)response->body._u.data.blob._buffer + RESPONSE_HEADER_OFFSET_SERDATA_KIND)); /* We could now potentially figure out if the response that has been received * contains fields that we cannot interpret. We can find that out by comparing @@ -1556,7 +1558,6 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * serdata->sequence_number = seqnum; serdata->timestamp.v = wt; memcpy(&serdata->writer_guid, &wguid, 16); - autodispose = false; /* TODO: we have to retrieve the autodispose setting of the writer! */ if ((ret = dds_reader_store_historical_serdata(reader, wguid, autodispose, serdata)) != DDS_RETCODE_OK) { DDS_ERROR("Failed to deliver historical data to reader \"%s\" [%s]\n", dc_stringify_id(proxy_set_rd->key.guid.v, id_str), dds_strretcode(ret)); goto err_store_historical_serdata; diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index e59f18b323..4b91e5a5cc 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -286,7 +286,7 @@ static const uint32_t DurableSupport_bead_ops [] = DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 17 /* session_t */, 1, offsetof (DurableSupport_content, _u.session), 0u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 19 /* set_t */, 2, offsetof (DurableSupport_content, _u.set), 0u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 31 /* writer_t */, 3, offsetof (DurableSupport_content, _u.writer), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 44 /* data_t */, 4, offsetof (DurableSupport_content, _u.data), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 51 /* data_t */, 4, offsetof (DurableSupport_content, _u.data), 0u, DDS_OP_RTS, /* session_t */ @@ -308,8 +308,14 @@ static const uint32_t DurableSupport_bead_ops [] = /* writer_t */ DDS_OP_DLC, DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_writer_t, id), 16u, + DDS_OP_ADR | DDS_OP_TYPE_EXT, offsetof (DurableSupport_writer_t, properties), (3u << 16u) + 10u /* writer_properties_t */, DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_writer_t, flags), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_writer_t, ranges), sizeof (DurableSupport_range), (4u << 16u) + 5u /* range */, + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_writer_t, ranges), sizeof (DurableSupport_range), (4u << 16u) + 9u /* range */, + DDS_OP_RTS, + + /* writer_properties_t */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_TYPE_BLN, offsetof (DurableSupport_writer_properties_t, autodispose), DDS_OP_RTS, /* range */ @@ -329,82 +335,87 @@ static const uint32_t DurableSupport_bead_ops [] = static const dds_key_descriptor_t DurableSupport_bead_keys[1] = { - { "id", 73, 0 } + { "id", 80, 0 } }; /* Type Information: - [MINIMAL 1915eb63b1ad4283c95c42298512] (#deps: 9) + [MINIMAL ec4a62f36aef58a53c25ca352c96] (#deps: 10) - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 219813f96895eb7a5bddfe02219f] + - [MINIMAL 8081d593c0e4df1bcd51ee4ff1ef] - [MINIMAL 80455e796dd3437163cb532089da] - [MINIMAL 7fe2256248fb0dc7c6a9b6c616fb] - [MINIMAL d8398b259af5a04792e296996c27] - [MINIMAL 0d686e35dcd446cd843b793a485c] - - [MINIMAL 2f19a070996d925b553ac288a028] + - [MINIMAL 889fb89d6714387ca74c9aa42719] + - [MINIMAL 7d1dfbcf78261b30f20d1dadb067] - [MINIMAL ef038b7b19448c9ce27fa1c268cd] - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE a89c569f6d508f3372a8c6407126] (#deps: 10) + [COMPLETE 17238b8e235b286c8fdcbeb41197] (#deps: 11) - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE 28eef02baeaad008f0cda9febf47] + - [COMPLETE 1b1b74c5e6971d9d84029a5e04d3] - [COMPLETE 105e7fa73d9700c1960716873c88] - [COMPLETE 5de973c540260a829429a905efcd] - [COMPLETE 838f13c80cfd7a0061fb91f88e49] - [COMPLETE 9c5d42ec81585355d169823828eb] - [COMPLETE dd9a1bfb3c68ff5066e4b763a939] - - [COMPLETE 1b62cfe76a5bdbc5e39d9f6d3975] + - [COMPLETE e6c4e5bb805c08c1d9e923e071ea] + - [COMPLETE 7a239210b1658deca81e1474b300] - [COMPLETE d8d43c2295c185a21b9591a7126c] - [COMPLETE a092964f6f76e3d643846ba36f9b] */ #define TYPE_INFO_CDR_DurableSupport_bead (const unsigned char []){ \ - 0x28, 0x02, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x00, 0x01, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x19, 0x15, 0xeb, 0x63, 0xb1, 0xad, 0x42, 0x83, 0xc9, 0x5c, 0x42, \ - 0x29, 0x85, 0x12, 0x00, 0x55, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, \ - 0x09, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x58, 0x02, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x18, 0x01, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0xec, 0x4a, 0x62, 0xf3, 0x6a, 0xef, 0x58, 0xa5, 0x3c, 0x25, 0xca, \ + 0x35, 0x2c, 0x96, 0x00, 0x55, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, \ + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x21, 0x98, 0x13, 0xf9, 0x68, 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0x00, \ + 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, 0xf1, 0xef, 0x00, \ 0xcc, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0x00, \ 0x55, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, \ - 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, \ - 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, 0x28, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, \ - 0x37, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, \ - 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0x18, 0x01, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa8, 0x9c, 0x56, \ - 0x9f, 0x6d, 0x50, 0x8f, 0x33, 0x72, 0xa8, 0xc6, 0x40, 0x71, 0x26, 0x00, 0x83, 0x00, 0x00, 0x00, \ - 0x0a, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x28, 0xee, 0xf0, 0x2b, 0xae, 0xaa, 0xd0, \ - 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, 0x47, 0x00, 0x13, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, \ - 0x39, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, \ - 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, \ - 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, \ - 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0x00, \ - 0xb5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, 0x5b, 0xdb, \ - 0xc5, 0xe3, 0x9d, 0x9f, 0x6d, 0x39, 0x75, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, \ + 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, 0x19, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, 0x1d, 0xad, 0xb0, 0x67, 0x00, \ + 0x27, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, \ + 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x37, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ + 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x30, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x23, 0x8b, 0x8e, 0x23, 0x5b, 0x28, 0x6c, 0x8f, 0xdc, 0xbe, \ + 0xb4, 0x11, 0x97, 0x00, 0x83, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, \ + 0x0b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, 0x97, 0x1d, 0x9d, 0x84, 0x02, 0x9a, 0x5e, 0x04, 0xd3, 0x00, \ + 0x13, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, \ + 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, 0x39, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, \ + 0x8d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, \ + 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, \ + 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, \ + 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0x00, 0xb5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0x00, \ + 0xd5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, \ + 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, \ 0x61, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, \ 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x00, 0x4f, 0x00, 0x00, 0x00\ } -#define TYPE_INFO_CDR_SZ_DurableSupport_bead 556u +#define TYPE_INFO_CDR_SZ_DurableSupport_bead 604u #define TYPE_MAP_CDR_DurableSupport_bead (const unsigned char []){ \ - 0xc0, 0x03, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xf1, 0x19, 0x15, 0xeb, 0x63, 0xb1, 0xad, 0x42, \ - 0x83, 0xc9, 0x5c, 0x42, 0x29, 0x85, 0x12, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x18, 0x04, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xf1, 0xec, 0x4a, 0x62, 0xf3, 0x6a, 0xef, 0x58, \ + 0xa5, 0x3c, 0x25, 0xca, 0x35, 0x2c, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x21, 0x98, 0x13, 0xf9, 0x68, \ - 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, \ + 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, 0xf1, 0xef, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x21, 0x98, 0x13, 0xf9, 0x68, \ - 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, \ + 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, 0xf1, 0xef, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, \ 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ 0xa4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -413,8 +424,8 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, \ 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, \ - 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xa8, 0x2f, 0xee, 0xe3, \ + 0x01, 0x00, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xa8, 0x2f, 0xee, 0xe3, \ 0x24, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x04, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ @@ -438,139 +449,156 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, \ 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x73, 0xed, \ - 0xc9, 0x6c, 0xf1, 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, \ - 0x28, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0xc9, 0x6c, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, \ + 0x19, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, \ - 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, \ - 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x8d, 0x81, 0x02, 0xfb, 0xf1, 0xef, \ - 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x00, 0x00, \ - 0x33, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x08, 0x26, 0x40, 0x3e, 0xc6, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x08, 0x1c, 0x78, 0xb4, 0x86, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, \ - 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \ - 0xee, 0x26, 0x90, 0x8b, 0xcf, 0x05, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xf2, 0xa8, 0x9c, 0x56, \ - 0x9f, 0x6d, 0x50, 0x8f, 0x33, 0x72, 0xa8, 0xc6, 0x40, 0x71, 0x26, 0x00, 0x7f, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x62, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0x28, 0xee, 0xf0, 0x2b, 0xae, 0xaa, 0xd0, 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, \ - 0x47, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, \ - 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, \ - 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ - 0xf2, 0x28, 0xee, 0xf0, 0x2b, 0xae, 0xaa, 0xd0, 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, 0x47, 0x00, \ - 0x0f, 0x01, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x00, 0x13, 0x00, 0x00, 0x00, \ - 0x11, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, \ - 0x88, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, \ - 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x08, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, \ - 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, \ - 0x5b, 0xdb, 0xc5, 0xe3, 0x9d, 0x9f, 0x6d, 0x39, 0x75, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xa0, \ - 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, \ - 0x00, 0x00, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, \ - 0x3c, 0x88, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x62, 0x65, 0x61, 0x64, 0x74, 0x79, 0x70, 0x65, \ - 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x5d, 0xe9, \ - 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x89, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ + 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, \ + 0x0d, 0x1d, 0xad, 0xb0, 0x67, 0x74, 0x69, 0x3d, 0x2f, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, \ + 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x8d, 0x81, 0x02, 0xfb, 0xf1, 0x7d, \ + 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, 0x1d, 0xad, 0xb0, 0x67, 0x00, 0x00, 0x00, \ + 0x23, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x01, 0x1c, 0x63, 0x57, 0x19, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, \ + 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x26, 0x40, 0x3e, 0xc6, 0x00, \ + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x1c, 0x78, 0xb4, 0x86, 0xf1, \ + 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, \ + 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0x6f, 0x06, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x23, 0x8b, 0x8e, 0x23, 0x5b, 0x28, 0x6c, 0x8f, 0xdc, 0xbe, \ + 0xb4, 0x11, 0x97, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x62, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, \ + 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, \ + 0x97, 0x1d, 0x9d, 0x84, 0x02, 0x9a, 0x5e, 0x04, 0xd3, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ + 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, 0x97, 0x1d, \ + 0x9d, 0x84, 0x02, 0x9a, 0x5e, 0x04, 0xd3, 0x00, 0x0f, 0x01, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, \ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x63, 0x6f, 0x6e, 0x74, \ + 0x65, 0x6e, 0x74, 0x00, 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, \ + 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5d, \ + 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, \ + 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, \ + 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, \ + 0xea, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, \ + 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, \ + 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x83, \ - 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x6b, 0x69, 0x6e, 0x64, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, \ - 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, \ - 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, \ - 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, \ - 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, \ - 0x82, 0x38, 0x28, 0xeb, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x62, 0x65, 0x61, 0x64, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, \ + 0xa9, 0x05, 0xef, 0xcd, 0x89, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x22, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, \ - 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, \ - 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, \ - 0xb1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, \ - 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, \ - 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, \ - 0x5c, 0x6d, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, \ - 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, 0x5b, 0xdb, 0xc5, 0xe3, 0x9d, \ - 0x9f, 0x6d, 0x39, 0x75, 0xa1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, \ - 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, \ - 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x5d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x74, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, \ + 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6b, 0x69, 0x6e, 0x64, \ + 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x9c, \ + 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, 0x00, 0x00, \ + 0x0b, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x00, 0x00, \ + 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, \ + 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, \ + 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x9c, 0x5d, \ + 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x39, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, \ + 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0xb1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x61, 0x6e, 0x67, \ - 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6c, 0x62, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, \ - 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x4b, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x61, 0x74, 0x61, \ - 0x5f, 0x74, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, \ - 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0xf2, 0xa8, 0x9c, 0x56, 0x9f, 0x6d, 0x50, 0x8f, 0x33, 0x72, 0xa8, 0xc6, 0x40, 0x71, 0x26, 0xf1, \ - 0x19, 0x15, 0xeb, 0x63, 0xb1, 0xad, 0x42, 0x83, 0xc9, 0x5c, 0x42, 0x29, 0x85, 0x12, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x28, 0xee, 0xf0, \ - 0x2b, 0xae, 0xaa, 0xd0, 0x08, 0xf0, 0xcd, 0xa9, 0xfe, 0xbf, 0x47, 0xf1, 0x21, 0x98, 0x13, 0xf9, \ - 0x68, 0x95, 0xeb, 0x7a, 0x5b, 0xdd, 0xfe, 0x02, 0x21, 0x9f, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, \ - 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, \ - 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, \ - 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, \ - 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, \ - 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, \ - 0x53, 0x20, 0x89, 0xda, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, \ - 0x38, 0x28, 0xeb, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ - 0x6c, 0x27, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, \ - 0x39, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, \ - 0xf2, 0x1b, 0x62, 0xcf, 0xe7, 0x6a, 0x5b, 0xdb, 0xc5, 0xe3, 0x9d, 0x9f, 0x6d, 0x39, 0x75, 0xf1, \ - 0x2f, 0x19, 0xa0, 0x70, 0x99, 0x6d, 0x92, 0x5b, 0x55, 0x3a, 0xc2, 0x88, 0xa0, 0x28, 0xf2, 0xd8, \ - 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, 0xef, 0x03, \ - 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0xf2, 0xa0, 0x92, 0x96, \ - 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, \ - 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x74, 0x5f, \ + 0x74, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, \ + 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xe6, 0xc4, \ + 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0xd1, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, \ + 0x1e, 0x14, 0x74, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x70, 0x72, 0x6f, 0x70, \ + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, \ + 0x73, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, \ + 0x01, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, \ + 0x12, 0x6c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, \ + 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, 0x00, \ + 0x5a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x24, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, \ + 0x72, 0x74, 0x69, 0x65, 0x73, 0x5f, 0x74, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, \ + 0x61, 0x75, 0x74, 0x6f, 0x64, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x00, 0x00, 0x00, 0xf2, 0xd8, \ + 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x00, \ + 0x5d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x6c, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, \ + 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, \ + 0x4b, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, \ + 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, \ + 0x6c, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x23, 0x8b, 0x8e, 0x23, 0x5b, 0x28, \ + 0x6c, 0x8f, 0xdc, 0xbe, 0xb4, 0x11, 0x97, 0xf1, 0xec, 0x4a, 0x62, 0xf3, 0x6a, 0xef, 0x58, 0xa5, \ + 0x3c, 0x25, 0xca, 0x35, 0x2c, 0x96, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, \ + 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, 0x97, 0x1d, 0x9d, 0x84, 0x02, 0x9a, \ + 0x5e, 0x04, 0xd3, 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, \ + 0xf1, 0xef, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, \ + 0x88, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, \ + 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0xf1, \ + 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0xf2, 0x83, \ + 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0xf1, 0x80, 0x45, \ + 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x9c, 0x5d, 0x42, \ + 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0xf1, 0xd8, 0x39, 0x8b, 0x25, \ + 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, \ + 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, \ + 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, \ + 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, \ + 0xa7, 0x4c, 0x9a, 0xa4, 0x27, 0x19, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, \ + 0x1e, 0x14, 0x74, 0xb3, 0x00, 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, \ + 0x1d, 0xad, 0xb0, 0x67, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, \ + 0xa7, 0x12, 0x6c, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, \ + 0x68, 0xcd, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, \ + 0x9b, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_bead 2794u +#define TYPE_MAP_CDR_SZ_DurableSupport_bead 3072u const dds_topic_descriptor_t DurableSupport_bead_desc = { .m_size = sizeof (DurableSupport_bead), @@ -579,7 +607,7 @@ const dds_topic_descriptor_t DurableSupport_bead_desc = .m_nkeys = 1u, .m_typename = "DurableSupport::bead", .m_keys = DurableSupport_bead_keys, - .m_nops = 35, + .m_nops = 39, .m_ops = DurableSupport_bead_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_bead, .sz = TYPE_INFO_CDR_SZ_DurableSupport_bead }, From 4eae0d745e09cd808c1de287ab49f2d3b97298c7 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 2 Jan 2024 10:48:16 +0100 Subject: [PATCH 194/207] Inject historical data as unregistered when the proxy writer is not (yet?) discovered Signed-off-by: TheFixer --- src/core/ddsc/src/dds_reader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index 9cb4cdfb41..043f468ed1 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -537,8 +537,8 @@ dds_return_t dds_reader_store_historical_serdata (dds_entity_t reader, dds_guid_ ret = DDS_RETCODE_BAD_PARAMETER; goto fail_tk_builtin; } - /* historical data is always unregistered */ - if (!ddsi_builtintopic_is_visible(gv->builtin_topic_interface, &ddsiguid, ddsi_get_entity_vendorid(&rd->e))) { + /* inject historical data as unregistered when the proxy writer is not (yet?) discovered */ + if (ddsi_entidx_lookup_proxy_writer_guid (gv->entity_index, &ddsiguid) == NULL) { serdata->statusinfo |= DDSI_STATUSINFO_UNREGISTER; } /* set the writer guid of the serdata */ From eb317168f33a427220205ead83df1e69ffbc2a18 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 5 Jan 2024 14:24:40 +0100 Subject: [PATCH 195/207] Fix crash when printing octet sequence, and improve printing of truncated octet sequences Signed-off-by: TheFixer --- src/durability/src/dds_durability.c | 99 +++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 27 deletions(-) diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index d79aba4ad6..aa48020a43 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -66,33 +66,78 @@ static char *dc_responsetype_image (DurableSupport_responsetype_t type) } } -static char *dc_blob_image (dds_sequence_octet blob) +static int dc_blob_image (dds_sequence_octet blob, char *buf, size_t n) { - char *buf; - uint32_t len; - uint32_t n; - uint32_t i; + uint32_t nrofbytes = 2 * blob._length + 1; /* the number of bytes to fill when the complete blob is stored, including the '\0' */ + uint32_t j; + size_t i = 0; + int l; -#define BLOB_IMAGE_SIZE 24 - len = (blob._length < BLOB_IMAGE_SIZE) ? blob._length : BLOB_IMAGE_SIZE; - n = len*2+1; - buf = ddsrt_malloc(n); - if (len < BLOB_IMAGE_SIZE) { - for (i=0; i < len; i++) { - sprintf(buf+i*2, "%02x", (char)blob._buffer[i]); + if (buf == NULL) { + /* no space allocated for display */ + return -1; + } + if (n == 0) { + /* do not print anything */ + return 0; + } + if (nrofbytes <= n) { + /* the complete blob fits in buf */ + for (j=0; j < blob._length; j++) { + if ((l = snprintf(buf+i, n-i, "%02x", (uint8_t)blob._buffer[j])) < 0) { + goto err; + } + assert(l < (int)(n-i)); /* never truncated */ + i += (size_t)l; } } else { - for (i=0; i < 11; i++) { - sprintf(buf+i*2, "%02x", (char)blob._buffer[i]); - } - strcpy(buf+22, "..."); - for (i=0; i < 11; i++) { - sprintf(buf+25+i*2, "%02x", (char)blob._buffer[len-11+i]); + /* The blob does not fit in buf. + * if n < 5 then we display '..'; + * if n >=5 and n < 7 we display 'AB..' + * if n > 7 we display 'AB..XY' (where the length of the head and tail varies depending on buf size n) + */ + if (n < 5) { + if ((l = snprintf(buf+i, n-i, "..")) < 0) { + goto err; + } + i += (size_t)l; + } else if (n < 7) { + if ((l = snprintf(buf+i, n-i, "%02x..", (uint8_t)blob._buffer[0])) < 0) { + goto err; + } + } else { + /* calculate head and tail part */ + size_t np = ((n-1) - 2) / 4; + size_t k; + /* print head */ + for (k=0; k < np; k++) { + if ((l = snprintf(buf+i, n-i, "%02x", (uint8_t)blob._buffer[k])) < 0) { + goto err; + } + assert(l < (int)(n-i)); /* impossible to overflow buf */ + i += (size_t)l; + } + /* print separator '..' */ + if ((l = snprintf(buf+i, n-i, "%s", "..")) < 0) { + goto err; + } + assert(l < (int)(n-i)); /* impossible to overflow buf */ + i += (size_t)l; + /* print tail */ + for (k=0; k < np; k++) { + if ((l = snprintf(buf+i, n-i, "%02x", (uint8_t)blob._buffer[blob._length - np + k])) < 0) { + goto err; + } + assert(l < (int)(n-i)); /* impossible to overflow buf */ + i += (size_t)l; + } } } - buf[2*len] = '\0'; -#undef BLOB_IMAGE_SIZE - return buf; + l = (int)i; + return (l >= (int)n) ? 0 /* no more space in buf */ : l; + +err: + return -1; } static int dc_stringify_request (char *buf, size_t n, const DurableSupport_request *request, bool valid_data) @@ -144,8 +189,8 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp { size_t i = 0; int l; - char *str; char id_str[37]; + char blob_str[64]; if (buf == NULL) { goto err; @@ -169,12 +214,12 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp i += (size_t)l; break; case DurableSupport_RESPONSETYPE_DATA : - str = dc_blob_image(response->body._u.data.blob); - if ((l = snprintf(buf+i, n-i, "\"blob\":\"%s\"", str)) < 0) { - ddsrt_free(str); + if (dc_blob_image(response->body._u.data.blob, blob_str, sizeof(blob_str)) < 0) { + goto err; + } + if ((l = snprintf(buf+i, n-i, "\"blob\":\"%s\"", blob_str)) < 0) { goto err; } - ddsrt_free(str); i += (size_t)l; break; default: @@ -2282,7 +2327,7 @@ dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) /* Check if the quorum for a durable writer is reached. * If not, we will head bang until the quorum is reached. - * To prevent starvation we use a 10ms sleep in between. + * To prevent starvation we use a 10ms sleep in between successive headbangs. * When the quorum is reached within the max_blocking_time, * DDS_RETCODE_OK is returned, otherwise DDS_PRECONDITION_NOT_MET * is returned. The max_blocking_time itself is retrieved lazily From 30c1db18da7fd0707e5709300996792dfa228e2a Mon Sep 17 00:00:00 2001 From: TheFixer Date: Wed, 7 Feb 2024 11:52:40 +0100 Subject: [PATCH 196/207] Add //CycloneDDS/Domain/Durability/Quorum configuration option to set the quorum Signed-off-by: TheFixer --- docs/manual/config/config_file_reference.rst | 36 +++++++++++++++--- docs/manual/options.md | 24 ++++++++++-- etc/cyclonedds.rnc | 15 ++++++-- etc/cyclonedds.xsd | 24 ++++++++++-- src/core/ddsi/defconfig.c | 7 +++- src/core/ddsi/include/dds/ddsi/ddsi_config.h | 4 ++ src/core/ddsi/src/ddsi__cfgelems.h | 39 ++++++++++++++++++++ 7 files changed, 133 insertions(+), 16 deletions(-) diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index 8afbd11780..fd0a2b1169 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -22,7 +22,7 @@ CycloneDDS configuration ******************* Attributes: :ref:`Id` -Children: :ref:`Compatibility`, :ref:`Discovery`, :ref:`General`, :ref:`Internal|Unsupported`, :ref:`Partitioning`, :ref:`SSL`, :ref:`Security|DDSSecurity`, :ref:`SharedMemory`, :ref:`Sizing`, :ref:`TCP`, :ref:`Threads`, :ref:`Tracing` +Children: :ref:`Compatibility`, :ref:`Discovery`, :ref:`Discovery`, :ref:`General`, :ref:`Internal|Unsupported`, :ref:`Partitioning`, :ref:`SSL`, :ref:`Security|DDSSecurity`, :ref:`SharedMemory`, :ref:`Sizing`, :ref:`TCP`, :ref:`Threads`, :ref:`Tracing` The General element specifying Domain related settings. @@ -393,6 +393,32 @@ String extension for domain id that remote participants must match to be discove The default value is: ```` +.. _`//CycloneDDS/Domain/Durability`: + +//CycloneDDS/Domain/Durability +============================== + +Children: `//CycloneDDS/Domain/Durability/Quorum`_ + +This element specifies settings related to durable data. + + +.. _`//CycloneDDS/Domain/Durability/Quorum`: + +//CycloneDDS/Domain/Durability/Quorum +------------------------------------- + +Integer + +This element specifies the minimum number of durable services that must be available before a durable writer can successfully publish durable data. The value must be equal or higher to 1 to ensure that there is at least one durable service present in the network that can receive the durable data and make it available to late joiners. By specifying a number higher than 1, additional fault tolerance can be achieved. + +As long as the number of available durable services drops below the specified quorum, durable writers will not be able to publish durable data. Any attempt to do so by calling dds\_write() (or one of its variants) will return DDS\_RETCODE\_TIMEOUT if the quorum is not reached within the configured max\_blocking\_time. + +The default quorum value is set to 1. + +The default value is: ``1`` + + .. _`//CycloneDDS/Domain/General`: //CycloneDDS/Domain/General @@ -2717,11 +2743,11 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: ``none`` .. - generated from ddsi_config.h[e6e75c7c07b3b91a92715063cfd8abdd0fbd8b08] + generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] - generated from ddsi__cfgelems.h[69679834d0a592a339803ed27e3966adc900d592] - generated from ddsi_config.c[8d7ef0ae962a47cb2138de27ac0f6751e3393c66] - generated from _confgen.h[9554f1d72645c0b8bb66ffbfbc3c0fb664fc1a43] + generated from ddsi__cfgelems.h[0fe5caa90873f3af7436f0f201edeccaea9fedd4] + generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] + generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] generated from generate_md.c[789b92e422631684352909cfb8bf43f6ceb16a01] diff --git a/docs/manual/options.md b/docs/manual/options.md index b38dfce0be..ea8dfe448d 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -6,7 +6,7 @@ CycloneDDS configuration ## //CycloneDDS/Domain Attributes: [Id](#cycloneddsdomainid) -Children: [Compatibility](#cycloneddsdomaincompatibility), [Discovery](#cycloneddsdomaindiscovery), [General](#cycloneddsdomaingeneral), [Internal](#cycloneddsdomaininternal), [Partitioning](#cycloneddsdomainpartitioning), [SSL](#cycloneddsdomainssl), [Security](#cycloneddsdomainsecurity), [SharedMemory](#cycloneddsdomainsharedmemory), [Sizing](#cycloneddsdomainsizing), [TCP](#cycloneddsdomaintcp), [Threads](#cycloneddsdomainthreads), [Tracing](#cycloneddsdomaintracing) +Children: [Compatibility](#cycloneddsdomaincompatibility), [Discovery](#cycloneddsdomaindiscovery), [Durability](#cycloneddsdomaindurability), [General](#cycloneddsdomaingeneral), [Internal](#cycloneddsdomaininternal), [Partitioning](#cycloneddsdomainpartitioning), [SSL](#cycloneddsdomainssl), [Security](#cycloneddsdomainsecurity), [SharedMemory](#cycloneddsdomainsharedmemory), [Sizing](#cycloneddsdomainsizing), [TCP](#cycloneddsdomaintcp), [Threads](#cycloneddsdomainthreads), [Tracing](#cycloneddsdomaintracing) The General element specifying Domain related settings. @@ -258,6 +258,24 @@ String extension for domain id that remote participants must match to be discove The default value is: `` +### //CycloneDDS/Domain/Durability +Children: [Quorum](#cycloneddsdomaindurabilityquorum) + +This element specifies settings related to durable data. + + +#### //CycloneDDS/Domain/Durability/Quorum +Integer + +This element specifies the minimum number of durable services that must be available before a durable writer can successfully publish durable data. The value must be equal or higher to 1 to ensure that there is at least one durable service present in the network that can receive the durable data and make it available to late joiners. By specifying a number higher than 1, additional fault tolerance can be achieved. + +As long as the number of available durable services drops below the specified quorum, durable writers will not be able to publish durable data. Any attempt to do so by calling dds\_write() (or one of its variants) will return DDS\_RETCODE\_TIMEOUT if the quorum is not reached within the configured max\_blocking\_time. + +The default quorum value is set to 1. + +The default value is: `1` + + ### //CycloneDDS/Domain/General Children: [AllowMulticast](#cycloneddsdomaingeneralallowmulticast), [DontRoute](#cycloneddsdomaingeneraldontroute), [EnableMulticastLoopback](#cycloneddsdomaingeneralenablemulticastloopback), [EntityAutoNaming](#cycloneddsdomaingeneralentityautonaming), [ExternalNetworkAddress](#cycloneddsdomaingeneralexternalnetworkaddress), [ExternalNetworkMask](#cycloneddsdomaingeneralexternalnetworkmask), [FragmentSize](#cycloneddsdomaingeneralfragmentsize), [Interfaces](#cycloneddsdomaingeneralinterfaces), [MaxMessageSize](#cycloneddsdomaingeneralmaxmessagesize), [MaxRexmitMessageSize](#cycloneddsdomaingeneralmaxrexmitmessagesize), [MulticastRecvNetworkInterfaceAddresses](#cycloneddsdomaingeneralmulticastrecvnetworkinterfaceaddresses), [MulticastTimeToLive](#cycloneddsdomaingeneralmulticasttimetolive), [RedundantNetworking](#cycloneddsdomaingeneralredundantnetworking), [Transport](#cycloneddsdomaingeneraltransport), [UseIPv6](#cycloneddsdomaingeneraluseipv) @@ -1907,9 +1925,9 @@ While none prevents any message from being written to a DDSI2 log file. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest. The default value is: `none` - + - + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index 713aa27299..1ed01cd022 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -187,6 +187,16 @@ CycloneDDS configuration""" ] ] }? }? & [ a:documentation [ xml:lang="en" """ +

    This element specifies settings related to durable data.

    """ ] ] + element Durability { + [ a:documentation [ xml:lang="en" """ +

    This element specifies the minimum number of durable services that must be available before a durable writer can successfully publish durable data. The value must be equal or higher to 1 to ensure that there is at least one durable service present in the network that can receive the durable data and make it available to late joiners. By specifying a number higher than 1, additional fault tolerance can be achieved.

    As long as the number of available durable services drops below the specified quorum, durable writers will not be able to publish durable data. Any attempt to do so by calling dds_write() (or one of its variants) will return DDS_RETCODE_TIMEOUT if the quorum is not reached within the configured max_blocking_time.

    The default quorum value is set to 1.

    +

    The default value is: 1

    """ ] ] + element Quorum { + xsd:integer + }? + }? + & [ a:documentation [ xml:lang="en" """

    The General element specifies overall Cyclone DDS service settings.

    """ ] ] element General { [ a:documentation [ xml:lang="en" """ @@ -1320,10 +1330,9 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
    duration_inf = xsd:token { pattern = "inf|0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)" } memsize = xsd:token { pattern = "0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B" } } -# generated from ddsi_config.h[e6e75c7c07b3b91a92715063cfd8abdd0fbd8b08] +# generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] # generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] - -# generated from ddsi__cfgelems.h[de6d6357eef2d532b2450cec9732702107d2a03c] +# generated from ddsi__cfgelems.h[0fe5caa90873f3af7436f0f201edeccaea9fedd4] # generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] # generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] # generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index 8b5d8c15c6..9c61abcc4a 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -20,6 +20,7 @@ CycloneDDS configuration + @@ -303,6 +304,24 @@ CycloneDDS configuration <p>The default value is: <code>&lt;empty&gt;</code></p> + + + +<p>This element specifies settings related to durable data.</p> + + + + + + + + + + +<p>This element specifies the minimum number of durable services that must be available before a durable writer can successfully publish durable data. The value must be equal or higher to 1 to ensure that there is at least one durable service present in the network that can receive the durable data and make it available to late joiners. By specifying a number higher than 1, additional fault tolerance can be achieved.</p> <p>As long as the number of available durable services drops below the specified quorum, durable writers will not be able to publish durable data. Any attempt to do so by calling dds_write() (or one of its variants) will return DDS_RETCODE_TIMEOUT if the quorum is not reached within the configured max_blocking_time.</p><p>The default quorum value is set to 1.</p> +<p>The default value is: <code>1</code></p> + + @@ -1980,10 +1999,9 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - + - - + diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index 565f587998..3f541abdd8 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -21,6 +21,9 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->fragment_size = UINT16_C (1344); #ifdef DDS_HAS_SECURITY #endif /* DDS_HAS_SECURITY */ +#ifdef DDS_HAS_DURABILITY + cfg->quorum = UINT32_C (1); +#endif /* DDS_HAS_DURABILITY */ #ifdef DDS_HAS_NETWORK_PARTITIONS #endif /* DDS_HAS_NETWORK_PARTITIONS */ cfg->rbuf_size = UINT32_C (1048576); @@ -99,9 +102,9 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->ssl_min_version.minor = 3; #endif /* DDS_HAS_TCP_TLS */ } -/* generated from ddsi_config.h[e6e75c7c07b3b91a92715063cfd8abdd0fbd8b08] */ +/* generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] */ /* generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] */ -/* generated from ddsi__cfgelems.h[de6d6357eef2d532b2450cec9732702107d2a03c] */ +/* generated from ddsi__cfgelems.h[0fe5caa90873f3af7436f0f201edeccaea9fedd4] */ /* generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] */ /* generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] */ /* generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] */ diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_config.h b/src/core/ddsi/include/dds/ddsi/ddsi_config.h index e240e85a72..a198d24f7d 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_config.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_config.h @@ -431,6 +431,10 @@ struct ddsi_config struct ddsi_config_omg_security_listelem *omg_security_configuration; #endif +#ifdef DDS_HAS_DURABILITY + uint32_t quorum; /* quorum threshold for durable publishers */ +#endif + /* deprecated shm options */ int enable_shm; char *shm_locator; diff --git a/src/core/ddsi/src/ddsi__cfgelems.h b/src/core/ddsi/src/ddsi__cfgelems.h index 97d243e9fa..671e724081 100644 --- a/src/core/ddsi/src/ddsi__cfgelems.h +++ b/src/core/ddsi/src/ddsi__cfgelems.h @@ -2102,6 +2102,32 @@ static struct cfgelem tracing_cfgelems[] = { END_MARKER }; +#ifdef DDS_HAS_DURABILITY + +static struct cfgelem durability_cfgelems[] = { + INT("Quorum", NULL, 1, "1", + MEMBER(quorum), + FUNCTIONS(0, uf_pos_uint, 0, pf_uint), + DESCRIPTION( + "

    This element specifies the minimum number of durable services " + "that must be available before a durable writer can successfully " + "publish durable data. The value must be equal or higher to 1 to ensure " + "that there is at least one durable service present in the network that " + "can receive the durable data and make it available to late joiners. " + "By specifying a number higher than 1, additional fault tolerance can be " + "achieved.

    " + "

    As long as the number of available durable services drops below the specified " + "quorum, durable writers will not be able to publish durable data. Any " + "attempt to do so by calling dds_write() (or one of its variants) " + "will return DDS_RETCODE_TIMEOUT if the quorum is not reached within the " + "configured max_blocking_time.

    " + "

    The default quorum value is set to 1.

    " + )), + END_MARKER +}; + +#endif + /* Multiplicity = 0 is a special for Domain/[@Id] as it has some special processing to only process relevant configuration sections. */ static struct cfgelem domain_cfgattrs[] = { @@ -2135,6 +2161,16 @@ static struct cfgelem domain_cfgelems[] = { MAXIMUM(1)), /* Security must occur at most once, but INT_MAX is required because of the way its processed (for now) */ #endif +#ifdef DDS_HAS_DURABILITY + GROUP("Durability", durability_cfgelems, NULL, 1, + NOMEMBER, + NOFUNCTIONS, + DESCRIPTION( + "

    This element specifies settings related to durable data.

    " + ), + BEHIND_FLAG("DDS_HAS_DURABILITY") + ), +#endif #ifdef DDS_HAS_NETWORK_PARTITIONS GROUP("Partitioning", partitioning_cfgelems, NULL, 1, NOMEMBER, @@ -2242,6 +2278,9 @@ static struct cfgelem root_cfgelems[] = { MOVED("TCP", "CycloneDDS/Domain/TCP"), #if DDS_HAS_SECURITY MOVED("DDSSecurity", "CycloneDDS/Domain/Security"), +#endif +#if DDS_HAS_DURABILITY + MOVED("Durability", "CycloneDDS/Domain/Durability"), #endif MOVED("SharedMemory", "CycloneDDS/Domain/SharedMemory"), #if DDS_HAS_TCP_TLS From 28ec521b16580e3070214c710ed42bd29a6f3a53 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Mon, 18 Mar 2024 09:10:15 +0100 Subject: [PATCH 197/207] Add type_id to dc_request and dc_response Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 4 + src/durability/src/dds_durability.c | 73 ++- src/durability/src/durablesupport.c | 589 +++++++++--------- 3 files changed, 356 insertions(+), 310 deletions(-) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index 837ca56dfc..2f8adc59b7 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -103,6 +103,7 @@ typedef struct DurableSupport_set { char * partition; char * tpname; + char * type_id; uint32_t flags; dds_sequence_DurableSupport_writer writers; } DurableSupport_set; @@ -173,6 +174,7 @@ typedef struct DurableSupport_set_t { char * partition; char * tpname; + char * type_id; uint32_t flags; dds_sequence_DurableSupport_id_t addressees; } DurableSupport_set_t; @@ -275,6 +277,7 @@ typedef struct DurableSupport_request DurableSupport_id_t client; char * partition; char * tpname; + char * type_id; DurableSupport_duration_t timeout; } DurableSupport_request; @@ -293,6 +296,7 @@ typedef struct DurableSupport_response_set_t DurableSupport_delivery_id_t delivery_id; char * partition; char * tpname; + char * type_id; uint32_t flags; } DurableSupport_response_set_t; diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index aa48020a43..0345f60dab 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -23,6 +23,7 @@ #include "dds/ddsi/ddsi_endpoint.h" #include "dds/ddsrt/avl.h" #include "dds/ddsi/ddsi_serdata.h" +#include "dds/ddsi/ddsi_typelib.h" #define DEFAULT_QOURUM 1 #define DEFAULT_IDENT "durable_support" @@ -33,9 +34,9 @@ #define DC_UNUSED_ARG(x) ((void)x) -#define DC_FLAG_SET_NOT_FOUND (((uint32_t)0x01) << 10) -#define DC_FLAG_SET_BEGIN (((uint32_t)0x01) << 11) -#define DC_FLAG_SET_END (((uint32_t)0x01) << 12) +#define DC_FLAG_SET_NOT_FOUND (((uint32_t)0x01) << 16) +#define DC_FLAG_SET_BEGIN (((uint32_t)0x01) << 17) +#define DC_FLAG_SET_END (((uint32_t)0x01) << 18) #define TRACE(...) DDS_CLOG (DDS_LC_DUR, &domaingv->logconfig, __VA_ARGS__) @@ -158,19 +159,19 @@ static int dc_stringify_request (char *buf, size_t n, const DurableSupport_reque if (valid_data) { /* also print non-key fields */ if (request->timeout == DDS_INFINITY) { - if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"timeout\":\"never\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname)) < 0) { + if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"timeout\":\"never\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, request->type_id)) < 0) { goto err; } } else { sec = (int64_t)(request->timeout / DDS_NSECS_IN_SEC); msec = (uint32_t)((request->timeout % DDS_NSECS_IN_SEC) / DDS_NSECS_IN_MSEC); - if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"timeout\":%" PRId64 ".%03" PRIu32 "}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, sec, msec)) < 0) { + if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"timeout\":%" PRId64 ".%03" PRIu32 "}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, request->type_id, sec, msec)) < 0) { goto err; } } } else { /* only print key fields */ - if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname)) < 0) { + if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, request->type_id)) < 0) { goto err; } } @@ -208,7 +209,7 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp } switch (response->body._d) { case DurableSupport_RESPONSETYPE_SET : - if ((l = snprintf(buf+i, n-i, "\"delivery_id\":%" PRIu64 ",\"partition\":\"%s\", \"tpname\":\"%s\", \"flags\":\"0x%04" PRIx32 "\"", response->body._u.set.delivery_id, response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.flags)) < 0) { + if ((l = snprintf(buf+i, n-i, "\"delivery_id\":%" PRIu64 ",\"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"flags\":\"0x%04" PRIx32 "\"", response->body._u.set.delivery_id, response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.type_id, response->body._u.set.flags)) < 0) { goto err; } i += (size_t)l; @@ -298,7 +299,7 @@ static const ddsrt_avl_ctreedef_t proxy_set_reader_td = DDSRT_AVL_CTREEDEF_INITI struct proxy_set_key_t { char *partition; /* partition name */ char *tpname; /* topic name */ - /* todo: typeid */ + char *type_id; /* type id */ }; struct proxy_set_t { @@ -326,6 +327,12 @@ static int cmp_proxy_set (const void *a, const void *b) } else if (cmp > 0) { return 1; } + /* compare type id */ + if ((cmp = strcmp(k1->type_id, k2->type_id)) < 0) { + return -1; + } else if (cmp > 0) { + return 1; + } return 0; } @@ -336,6 +343,7 @@ static void cleanup_proxy_set (void *n) ddsrt_avl_cfree(&proxy_set_reader_td, &proxy_set->readers, cleanup_proxy_set_reader); ddsrt_free(proxy_set->key.partition); ddsrt_free(proxy_set->key.tpname); + ddsrt_free(proxy_set->key.type_id); ddsrt_free(proxy_set); } @@ -1191,7 +1199,7 @@ static void dc_com_free (struct com_t *com) #define MAX_TOPIC_NAME_SIZE 255 -static dds_return_t dc_com_request_write (struct com_t *com, const char *partition, const char *tpname) +static dds_return_t dc_com_request_write (struct com_t *com, const char *partition, const char *tpname, const char *type_id) { /* note: we allow doing a request for volatile readers */ DurableSupport_request *request; @@ -1204,6 +1212,7 @@ static dds_return_t dc_com_request_write (struct com_t *com, const char *partiti memcpy(request->client, dc.cfg.id, 16); request->partition = ddsrt_strdup(partition); request->tpname = ddsrt_strdup(tpname); + request->type_id = ddsrt_strdup(type_id); request->timeout = DDS_INFINITY; l = dc_stringify_request(str, sizeof(str), request, true); assert(l > 0); @@ -1292,7 +1301,7 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } -static struct proxy_set_t *dc_create_proxy_set (struct dc_t *dc, const char *partition, const char *tpname) +static struct proxy_set_t *dc_create_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, const char *type_id) { struct proxy_set_t *proxy_set = NULL; @@ -1301,14 +1310,15 @@ static struct proxy_set_t *dc_create_proxy_set (struct dc_t *dc, const char *par proxy_set = (struct proxy_set_t *)ddsrt_malloc(sizeof(struct proxy_set_t)); proxy_set->key.partition = ddsrt_strdup(partition); proxy_set->key.tpname = ddsrt_strdup(tpname); + proxy_set->key.type_id = ddsrt_strdup(type_id); proxy_set->seq = 0; /* no pending request yet */ ddsrt_avl_cinit(&proxy_set_reader_td, &proxy_set->readers); ddsrt_avl_cinsert(&proxy_set_td, &dc->proxy_sets, proxy_set); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "proxy set '%s.%s' created\n", proxy_set->key.partition, proxy_set->key.tpname); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "proxy set '%s.%s<%s>' created\n", proxy_set->key.partition, proxy_set->key.tpname, proxy_set->key.type_id); return proxy_set; } -static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, bool autocreate) +static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, const char *type_id, bool autocreate) { struct proxy_set_key_t key; struct proxy_set_t *proxy_set; @@ -1317,11 +1327,13 @@ static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partit assert(tpname); key.partition = ddsrt_strdup(partition); key.tpname = ddsrt_strdup(tpname); + key.type_id = ddsrt_strdup(type_id); if (((proxy_set = ddsrt_avl_clookup (&proxy_set_td, &dc->proxy_sets, &key)) == NULL) && autocreate) { - proxy_set = dc_create_proxy_set(dc, partition, tpname); + proxy_set = dc_create_proxy_set(dc, partition, tpname, type_id); } ddsrt_free(key.partition); ddsrt_free(key.tpname); + ddsrt_free(key.type_id); return proxy_set; } @@ -1392,14 +1404,14 @@ static void dc_open_delivery (struct dc_t *dc, DurableSupport_response *respons } /* set the delivery_id and proxy set for this delivery context */ dc->delivery_ctx->delivery_id = delivery_id; - if ((dc->delivery_ctx->proxy_set = dc_get_proxy_set(dc, response->body._u.set.partition, response->body._u.set.tpname, false)) == NULL) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "no proxy set for \"%s.%s\" found, ignore delivery\n", response->body._u.set.partition, response->body._u.set.tpname); + if ((dc->delivery_ctx->proxy_set = dc_get_proxy_set(dc, response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.type_id, false)) == NULL) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "no proxy set for \"%s.%s<%s>\" found, ignore delivery\n", response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.type_id); /* abort this delivery context */ dc_abort_current_delivery(dc); return; } - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s\" opened\n", - delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str), dc->delivery_ctx->proxy_set->key.partition, dc->delivery_ctx->proxy_set->key.tpname); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s<%s>\" opened\n", + delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str), dc->delivery_ctx->proxy_set->key.partition, dc->delivery_ctx->proxy_set->key.tpname, dc->delivery_ctx->proxy_set->key.type_id); } /* close the current delivery context for the ds identified by id */ @@ -1693,16 +1705,21 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade uint32_t plen, i; char **partitions; struct proxy_set_t *proxy_set = NULL; - dds_instance_handle_t ih; dds_guid_t guid; char id_str[37]; + dds_typeinfo_t *typeinfo; + ddsi_typeid_t *tid = NULL; + struct ddsi_typeid_str tidstr = { 0 }; - /* LH: perhaps the qos should be added as parameter, since the caller already has the qos */ - /* verify if the reader still exists; if not, delete the request */ - if ((rc = dds_get_instance_handle(reader, &ih)) != DDS_RETCODE_OK) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "No need to create a proxy set, reader is not available [%s]\n", dds_strretcode(-rc)); - return; + if ((rc = dds_get_typeinfo(reader, &typeinfo)) != DDS_RETCODE_OK) { + DDS_ERROR("Unable to retrieve typeinfo [%s]\n", dds_strretcode(-rc)); + goto err_get_typeinfo; + } + if ((tid = ddsi_typeinfo_typeid(typeinfo, DDSI_TYPEID_KIND_COMPLETE)) == NULL) { + DDS_ERROR("Unable to retrieve typeid [%s]\n", dds_strretcode(-rc)); + goto err_typeid; } + (void)ddsi_make_typeid_str(&tidstr, tid); /* get reader guid */ if ((rc = dds_get_guid(reader, &guid)) < DDS_RETCODE_OK) { DDS_ERROR("Unable to retrieve the guid of the reader [%s]\n", dds_strretcode(-rc)); @@ -1738,7 +1755,7 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade /* for each partition create a proxy set if it does not exist yet * and request data for the proxy set (if not done so already) */ for (i=0; i < plen; i++) { - proxy_set = dc_get_proxy_set(dc, partitions[i], tpname, true); + proxy_set = dc_get_proxy_set(dc, partitions[i], tpname, tidstr.str, true); assert(proxy_set); /* Add the reader and rhc to this proxy set. * We do this BEFORE we send the request, so that we are sure @@ -1746,7 +1763,7 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade * sending the request) the reader and rhc are present */ dc_register_reader_to_proxy_set(dc, proxy_set, guid, reader, rhc); /* send a request for this proxy set */ - if ((rc = dc_com_request_write(dc->com, proxy_set->key.partition, proxy_set->key.tpname)) != DDS_RETCODE_OK) { + if ((rc = dc_com_request_write(dc->com, proxy_set->key.partition, proxy_set->key.tpname, proxy_set->key.type_id)) != DDS_RETCODE_OK) { DDS_ERROR("Failed to publish dc_request for proxy set %s.%s\n", proxy_set->key.partition, proxy_set->key.tpname); /* We failed to request data for this proxy set. * We could do several things now, e.g., 1) try again until we succeed, @@ -1759,6 +1776,8 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade } dc_free_partitions(plen, partitions); dds_delete_qos(rqos); + dds_free_typeinfo(typeinfo); + ddsrt_free(tid); return; err_qget_partition: @@ -1769,6 +1788,10 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade err_get_name: err_get_topic: err_get_guid: + ddsrt_free(tid); +err_typeid: + dds_free_typeinfo(typeinfo); +err_get_typeinfo: return; } diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index 4b91e5a5cc..2395d59455 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -106,6 +106,7 @@ static const uint32_t DurableSupport_state_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, partition), DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, tpname), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, type_id), DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_set, flags), DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_set, writers), sizeof (DurableSupport_writer), (4u << 16u) + 5u /* writer */, DDS_OP_RTS, @@ -129,62 +130,63 @@ static const uint32_t DurableSupport_state_ops [] = static const dds_key_descriptor_t DurableSupport_state_keys[1] = { - { "id", 40, 0 } + { "id", 42, 0 } }; /* Type Information: - [MINIMAL 29c25c35d5510f091b9d2951e87d] (#deps: 4) + [MINIMAL 9546da84e880713f59c93561b8d8] (#deps: 4) - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 4c34d21c8ec2020e687b75390553] + - [MINIMAL 0edda7680861b44f54f71e189994] - [MINIMAL 7b73d4df4f265b2da8c52f3c3a8e] - [MINIMAL ef038b7b19448c9ce27fa1c268cd] - [COMPLETE a4dc41b7052cef5bfdb62c313d77] (#deps: 4) + [COMPLETE 174aa20548235aee4aff5111d8a2] (#deps: 4) - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE ec0a17f45bf4c4917bb5db3c5b18] + - [COMPLETE 0b9ecead7e5e9db531d5a4ef26b1] - [COMPLETE 3be64a4fbc92a7b2f612cbd52a3a] - [COMPLETE d8d43c2295c185a21b9591a7126c] */ #define TYPE_INFO_CDR_DurableSupport_state (const unsigned char []){ \ 0x20, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x29, 0xc2, 0x5c, 0x35, 0xd5, 0x51, 0x0f, 0x09, 0x1b, 0x9d, 0x29, \ - 0x51, 0xe8, 0x7d, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x95, 0x46, 0xda, 0x84, 0xe8, 0x80, 0x71, 0x3f, 0x59, 0xc9, 0x35, \ + 0x61, 0xb8, 0xd8, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, 0x05, 0x53, 0x00, \ - 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, \ + 0xf1, 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, 0x94, 0x00, \ + 0x7a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, \ 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, \ 0x37, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa4, 0xdc, 0x41, 0xb7, 0x05, 0x2c, 0xef, 0x5b, 0xfd, 0xb6, 0x2c, \ - 0x31, 0x3d, 0x77, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x4a, 0xa2, 0x05, 0x48, 0x23, 0x5a, 0xee, 0x4a, 0xff, 0x51, \ + 0x11, 0xd8, 0xa2, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xec, 0x0a, 0x17, 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, 0x3c, 0x5b, 0x18, 0x00, \ - 0xae, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, \ + 0xf2, 0x0b, 0x9e, 0xce, 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0x00, \ + 0xca, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, \ 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, \ 0x61, 0x00, 0x00, 0x00\ } #define TYPE_INFO_CDR_SZ_DurableSupport_state 292u #define TYPE_MAP_CDR_DurableSupport_state (const unsigned char []){ \ - 0xef, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf1, 0x29, 0xc2, 0x5c, 0x35, 0xd5, 0x51, 0x0f, \ - 0x09, 0x1b, 0x9d, 0x29, 0x51, 0xe8, 0x7d, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0xff, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf1, 0x95, 0x46, 0xda, 0x84, 0xe8, 0x80, 0x71, \ + 0x3f, 0x59, 0xc9, 0x35, 0x61, 0xb8, 0xd8, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0xb0, 0x68, 0x93, 0x1c, \ 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ - 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, 0x05, 0x53, 0x17, 0x8d, \ + 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, 0x94, 0x17, 0x8d, \ 0x51, 0x02, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, \ 0x89, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x10, 0x02, 0xf1, 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, 0x05, \ - 0x53, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, \ + 0x10, 0x02, 0xf1, 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, \ + 0x94, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x0b, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, \ + 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x0c, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, 0x0b, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, \ 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0xbf, 0x63, 0x9b, 0x5f, 0xf1, 0x7b, \ 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0x00, 0x00, 0x00, \ 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -198,8 +200,8 @@ static const dds_key_descriptor_t DurableSupport_state_keys[1] = 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x26, \ 0x40, 0x3e, 0xc6, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x1c, \ - 0x78, 0xb4, 0x86, 0x00, 0xe5, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf2, 0xa4, 0xdc, 0x41, \ - 0xb7, 0x05, 0x2c, 0xef, 0x5b, 0xfd, 0xb6, 0x2c, 0x31, 0x3d, 0x77, 0x00, 0x9b, 0x00, 0x00, 0x00, \ + 0x78, 0xb4, 0x86, 0x00, 0x01, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x4a, 0xa2, \ + 0x05, 0x48, 0x23, 0x5a, 0xee, 0x4a, 0xff, 0x51, 0x11, 0xd8, 0xa2, 0x00, 0x9b, 0x00, 0x00, 0x00, \ 0xf2, 0x51, 0x02, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ 0x73, 0x74, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ @@ -208,55 +210,57 @@ static const dds_key_descriptor_t DurableSupport_state_keys[1] = 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0x70, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, \ 0x27, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, \ - 0xec, 0x0a, 0x17, 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, 0x3c, 0x5b, 0x18, 0x00, 0x00, \ + 0x0b, 0x9e, 0xce, 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0x00, 0x00, \ 0x05, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, \ 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0xec, 0x0a, 0x17, \ - 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, 0x3c, 0x5b, 0x18, 0x00, 0xaa, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x0b, 0x9e, 0xce, \ + 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0x00, 0xc6, 0x00, 0x00, 0x00, \ 0xf2, 0x51, 0x0a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x73, 0x65, 0x74, 0x00, 0x82, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ + 0x73, 0x65, 0x74, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x31, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, \ - 0xbc, 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, \ - 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, \ - 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ - 0x29, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, \ - 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, \ - 0x07, 0x00, 0x00, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, \ - 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x5d, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x6c, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x9a, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf2, 0xa4, 0xdc, 0x41, 0xb7, 0x05, 0x2c, 0xef, \ - 0x5b, 0xfd, 0xb6, 0x2c, 0x31, 0x3d, 0x77, 0xf1, 0x29, 0xc2, 0x5c, 0x35, 0xd5, 0x51, 0x0f, 0x09, \ - 0x1b, 0x9d, 0x29, 0x51, 0xe8, 0x7d, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, \ - 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0xec, 0x0a, 0x17, 0xf4, 0x5b, 0xf4, 0xc4, 0x91, 0x7b, 0xb5, 0xdb, \ - 0x3c, 0x5b, 0x18, 0xf1, 0x4c, 0x34, 0xd2, 0x1c, 0x8e, 0xc2, 0x02, 0x0e, 0x68, 0x7b, 0x75, 0x39, \ - 0x05, 0x53, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, \ - 0x3a, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, \ - 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, \ - 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd\ + 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, \ + 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, \ + 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, \ + 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x77, 0x72, 0x69, 0x74, \ + 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, 0xf6, \ + 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, \ + 0x65, 0x72, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, \ + 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, \ + 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x5d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x61, 0x6e, 0x67, \ + 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6c, 0x62, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x4a, 0xa2, 0x05, 0x48, 0x23, 0x5a, 0xee, 0x4a, 0xff, 0x51, \ + 0x11, 0xd8, 0xa2, 0xf1, 0x95, 0x46, 0xda, 0x84, 0xe8, 0x80, 0x71, 0x3f, 0x59, 0xc9, 0x35, 0x61, \ + 0xb8, 0xd8, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ + 0xf2, 0x0b, 0x9e, 0xce, 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0xf1, \ + 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, 0x94, 0xf2, 0x3b, \ + 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0xf1, 0x7b, 0x73, \ + 0xd4, 0xdf, 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0xf2, 0xd8, 0xd4, 0x3c, \ + 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, 0xef, 0x03, 0x8b, 0x7b, \ + 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_state 1406u +#define TYPE_MAP_CDR_SZ_DurableSupport_state 1450u const dds_topic_descriptor_t DurableSupport_state_desc = { .m_size = sizeof (DurableSupport_state), @@ -265,7 +269,7 @@ const dds_topic_descriptor_t DurableSupport_state_desc = .m_nkeys = 1u, .m_typename = "DurableSupport::state", .m_keys = DurableSupport_state_keys, - .m_nops = 20, + .m_nops = 21, .m_ops = DurableSupport_state_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_state, .sz = TYPE_INFO_CDR_SZ_DurableSupport_state }, @@ -285,8 +289,8 @@ static const uint32_t DurableSupport_bead_ops [] = DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_content, _d), 4u, (20u << 16u) + 4u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 17 /* session_t */, 1, offsetof (DurableSupport_content, _u.session), 0u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 19 /* set_t */, 2, offsetof (DurableSupport_content, _u.set), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 31 /* writer_t */, 3, offsetof (DurableSupport_content, _u.writer), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 51 /* data_t */, 4, offsetof (DurableSupport_content, _u.data), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 33 /* writer_t */, 3, offsetof (DurableSupport_content, _u.writer), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 53 /* data_t */, 4, offsetof (DurableSupport_content, _u.data), 0u, DDS_OP_RTS, /* session_t */ @@ -299,6 +303,7 @@ static const uint32_t DurableSupport_bead_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, partition), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, tpname), + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, type_id), DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_set_t, flags), DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_ARR, offsetof (DurableSupport_set_t, addressees), sizeof (DurableSupport_id_t), (8u << 16u) + 4u, DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, 0u, 16u, @@ -335,29 +340,29 @@ static const uint32_t DurableSupport_bead_ops [] = static const dds_key_descriptor_t DurableSupport_bead_keys[1] = { - { "id", 80, 0 } + { "id", 82, 0 } }; /* Type Information: - [MINIMAL ec4a62f36aef58a53c25ca352c96] (#deps: 10) + [MINIMAL 333a527587be11928ad9cbfa1803] (#deps: 10) - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 8081d593c0e4df1bcd51ee4ff1ef] + - [MINIMAL e4bc4a05081322db5581a91d817f] - [MINIMAL 80455e796dd3437163cb532089da] - [MINIMAL 7fe2256248fb0dc7c6a9b6c616fb] - [MINIMAL d8398b259af5a04792e296996c27] - - [MINIMAL 0d686e35dcd446cd843b793a485c] + - [MINIMAL 5068289639b114fecda3f2c2ebd6] - [MINIMAL 889fb89d6714387ca74c9aa42719] - [MINIMAL 7d1dfbcf78261b30f20d1dadb067] - [MINIMAL ef038b7b19448c9ce27fa1c268cd] - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE 17238b8e235b286c8fdcbeb41197] (#deps: 11) + [COMPLETE a10b59cc2ac5234a0ab0c89deed6] (#deps: 11) - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE 1b1b74c5e6971d9d84029a5e04d3] + - [COMPLETE ad3badfa4313f0bde4a077931856] - [COMPLETE 105e7fa73d9700c1960716873c88] - [COMPLETE 5de973c540260a829429a905efcd] - [COMPLETE 838f13c80cfd7a0061fb91f88e49] - [COMPLETE 9c5d42ec81585355d169823828eb] - - [COMPLETE dd9a1bfb3c68ff5066e4b763a939] + - [COMPLETE e2beee99b860e5aa4c372c3b5655] - [COMPLETE e6c4e5bb805c08c1d9e923e071ea] - [COMPLETE 7a239210b1658deca81e1474b300] - [COMPLETE d8d43c2295c185a21b9591a7126c] @@ -365,37 +370,37 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = */ #define TYPE_INFO_CDR_DurableSupport_bead (const unsigned char []){ \ 0x58, 0x02, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x18, 0x01, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0xec, 0x4a, 0x62, 0xf3, 0x6a, 0xef, 0x58, 0xa5, 0x3c, 0x25, 0xca, \ - 0x35, 0x2c, 0x96, 0x00, 0x55, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x33, 0x3a, 0x52, 0x75, 0x87, 0xbe, 0x11, 0x92, 0x8a, 0xd9, 0xcb, \ + 0xfa, 0x18, 0x03, 0x00, 0x55, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, \ 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, 0xf1, 0xef, 0x00, \ + 0xf1, 0xe4, 0xbc, 0x4a, 0x05, 0x08, 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0x00, \ 0xcc, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0x00, \ 0x55, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, \ - 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, \ + 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, 0xb1, 0x14, 0xfe, 0xcd, 0xa3, 0xf2, 0xc2, 0xeb, 0xd6, 0x00, \ + 0x7a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, \ 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, 0x19, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, 0x1d, 0xad, 0xb0, 0x67, 0x00, \ 0x27, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, \ 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x37, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x30, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x23, 0x8b, 0x8e, 0x23, 0x5b, 0x28, 0x6c, 0x8f, 0xdc, 0xbe, \ - 0xb4, 0x11, 0x97, 0x00, 0x83, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa1, 0x0b, 0x59, 0xcc, 0x2a, 0xc5, 0x23, 0x4a, 0x0a, 0xb0, 0xc8, \ + 0x9d, 0xee, 0xd6, 0x00, 0x83, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, \ 0x0b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, 0x97, 0x1d, 0x9d, 0x84, 0x02, 0x9a, 0x5e, 0x04, 0xd3, 0x00, \ + 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, 0x13, 0xf0, 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0x00, \ 0x13, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, \ 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, 0x39, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, \ 0x8d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, \ 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, \ - 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, \ - 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0x00, 0xb5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, 0xe5, \ + 0xaa, 0x4c, 0x37, 0x2c, 0x3b, 0x56, 0x55, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0x00, \ 0xd5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, \ 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ @@ -405,24 +410,24 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = } #define TYPE_INFO_CDR_SZ_DurableSupport_bead 604u #define TYPE_MAP_CDR_DurableSupport_bead (const unsigned char []){ \ - 0x18, 0x04, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xf1, 0xec, 0x4a, 0x62, 0xf3, 0x6a, 0xef, 0x58, \ - 0xa5, 0x3c, 0x25, 0xca, 0x35, 0x2c, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x28, 0x04, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xf1, 0x33, 0x3a, 0x52, 0x75, 0x87, 0xbe, 0x11, \ + 0x92, 0x8a, 0xd9, 0xcb, 0xfa, 0x18, 0x03, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, \ - 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, 0xf1, 0xef, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xe4, 0xbc, 0x4a, 0x05, 0x08, \ + 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, \ - 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, 0xf1, 0xef, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0xe4, 0xbc, 0x4a, 0x05, 0x08, \ + 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, \ 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ 0xa4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, \ 0xfb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0xd6, 0xf4, 0x0c, \ - 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, \ - 0xd4, 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, \ + 0xb1, 0x14, 0xfe, 0xcd, 0xa3, 0xf2, 0xc2, 0xeb, 0xd6, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, \ 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xa8, 0x2f, 0xee, 0xe3, \ @@ -441,13 +446,14 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x06, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, 0x46, 0xcd, \ - 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, 0xb1, 0x14, 0xfe, \ + 0xcd, 0xa3, 0xf2, 0xc2, 0xeb, 0xd6, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ - 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, \ + 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x73, 0xed, \ 0xc9, 0x6c, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, \ 0x19, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ @@ -470,23 +476,23 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, \ 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0x6f, 0x06, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x23, 0x8b, 0x8e, 0x23, 0x5b, 0x28, 0x6c, 0x8f, 0xdc, 0xbe, \ - 0xb4, 0x11, 0x97, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0x8b, 0x06, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0xf2, 0xa1, 0x0b, 0x59, 0xcc, 0x2a, 0xc5, 0x23, 0x4a, 0x0a, 0xb0, 0xc8, \ + 0x9d, 0xee, 0xd6, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x62, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, \ 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, \ - 0x97, 0x1d, 0x9d, 0x84, 0x02, 0x9a, 0x5e, 0x04, 0xd3, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, \ + 0x13, 0xf0, 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, 0x97, 0x1d, \ - 0x9d, 0x84, 0x02, 0x9a, 0x5e, 0x04, 0xd3, 0x00, 0x0f, 0x01, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, 0x13, 0xf0, \ + 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0x00, 0x0f, 0x01, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, \ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x63, 0x6f, 0x6e, 0x74, \ 0x65, 0x6e, 0x74, 0x00, 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, \ @@ -495,8 +501,8 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, \ 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, \ - 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, 0xe5, 0xaa, 0x4c, 0x37, 0x2c, 0x3b, 0x56, \ + 0x55, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, \ 0xea, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ @@ -527,78 +533,80 @@ static const dds_key_descriptor_t DurableSupport_bead_keys[1] = 0xf2, 0x30, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, 0x68, \ - 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0xb1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, \ + 0xe5, 0xaa, 0x4c, 0x37, 0x2c, 0x3b, 0x56, 0x55, 0xcd, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x74, 0x5f, \ - 0x74, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ + 0x74, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, \ - 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xe6, 0xc4, \ - 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0xd1, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, \ + 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ + 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x72, \ + 0x65, 0x73, 0x73, 0x65, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, \ + 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0xd1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, \ + 0x65, 0x72, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, \ + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, \ + 0x65, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ + 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, \ + 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, \ + 0x07, 0x00, 0x00, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x7a, 0x23, \ + 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, 0x00, 0x5a, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, \ - 0x1e, 0x14, 0x74, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x70, 0x72, 0x6f, 0x70, \ - 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, \ - 0x73, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, \ - 0x01, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, \ - 0x12, 0x6c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, \ - 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, 0x00, \ - 0x5a, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x24, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, \ - 0x72, 0x74, 0x69, 0x65, 0x73, 0x5f, 0x74, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, \ - 0x61, 0x75, 0x74, 0x6f, 0x64, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x00, 0x00, 0x00, 0xf2, 0xd8, \ - 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x00, \ - 0x5d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x6c, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, \ - 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, \ - 0x4b, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, \ - 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, \ - 0x6c, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x23, 0x8b, 0x8e, 0x23, 0x5b, 0x28, \ - 0x6c, 0x8f, 0xdc, 0xbe, 0xb4, 0x11, 0x97, 0xf1, 0xec, 0x4a, 0x62, 0xf3, 0x6a, 0xef, 0x58, 0xa5, \ - 0x3c, 0x25, 0xca, 0x35, 0x2c, 0x96, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, \ - 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x1b, 0x1b, 0x74, 0xc5, 0xe6, 0x97, 0x1d, 0x9d, 0x84, 0x02, 0x9a, \ - 0x5e, 0x04, 0xd3, 0xf1, 0x80, 0x81, 0xd5, 0x93, 0xc0, 0xe4, 0xdf, 0x1b, 0xcd, 0x51, 0xee, 0x4f, \ - 0xf1, 0xef, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, \ - 0x88, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, \ - 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0xf1, \ - 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0xf2, 0x83, \ - 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0xf1, 0x80, 0x45, \ - 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x9c, 0x5d, 0x42, \ - 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0xf1, 0xd8, 0x39, 0x8b, 0x25, \ - 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0xf2, 0xdd, 0x9a, 0x1b, 0xfb, 0x3c, \ - 0x68, 0xff, 0x50, 0x66, 0xe4, 0xb7, 0x63, 0xa9, 0x39, 0xf1, 0x0d, 0x68, 0x6e, 0x35, 0xdc, 0xd4, \ - 0x46, 0xcd, 0x84, 0x3b, 0x79, 0x3a, 0x48, 0x5c, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, \ - 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, \ - 0xa7, 0x4c, 0x9a, 0xa4, 0x27, 0x19, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, \ - 0x1e, 0x14, 0x74, 0xb3, 0x00, 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, \ - 0x1d, 0xad, 0xb0, 0x67, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, \ - 0xa7, 0x12, 0x6c, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, \ - 0x68, 0xcd, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, \ - 0x9b, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ + 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, \ + 0x73, 0x5f, 0x74, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x61, 0x75, 0x74, 0x6f, \ + 0x64, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, \ + 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x6c, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0xf2, 0xa0, 0x92, \ + 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x4b, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \ + 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x01, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0xf2, 0xa1, 0x0b, 0x59, 0xcc, 0x2a, 0xc5, 0x23, 0x4a, 0x0a, 0xb0, 0xc8, \ + 0x9d, 0xee, 0xd6, 0xf1, 0x33, 0x3a, 0x52, 0x75, 0x87, 0xbe, 0x11, 0x92, 0x8a, 0xd9, 0xcb, 0xfa, \ + 0x18, 0x03, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ + 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, 0x13, 0xf0, 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0xf1, \ + 0xe4, 0xbc, 0x4a, 0x05, 0x08, 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0xf2, 0x10, \ + 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0xf1, 0x80, 0x45, \ + 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x5d, 0xe9, 0x73, \ + 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0xf1, 0x7f, 0xe2, 0x25, 0x62, \ + 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, \ + 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, \ + 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, \ + 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, \ + 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, 0xe5, 0xaa, 0x4c, \ + 0x37, 0x2c, 0x3b, 0x56, 0x55, 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, 0xb1, 0x14, 0xfe, 0xcd, 0xa3, \ + 0xf2, 0xc2, 0xeb, 0xd6, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, \ + 0xe0, 0x71, 0xea, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, \ + 0x27, 0x19, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, \ + 0x00, 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, 0x1d, 0xad, 0xb0, 0x67, \ + 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, \ + 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0xf2, 0xa0, \ + 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0xf1, 0xa5, 0x80, \ + 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_bead 3072u +#define TYPE_MAP_CDR_SZ_DurableSupport_bead 3116u const dds_topic_descriptor_t DurableSupport_bead_desc = { .m_size = sizeof (DurableSupport_bead), @@ -607,7 +615,7 @@ const dds_topic_descriptor_t DurableSupport_bead_desc = .m_nkeys = 1u, .m_typename = "DurableSupport::bead", .m_keys = DurableSupport_bead_keys, - .m_nops = 39, + .m_nops = 40, .m_ops = DurableSupport_bead_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_bead, .sz = TYPE_INFO_CDR_SZ_DurableSupport_bead }, @@ -621,44 +629,49 @@ static const uint32_t DurableSupport_request_ops [] = DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, client), 16u, DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, partition), DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, type_id), DDS_OP_ADR | DDS_OP_TYPE_8BY | DDS_OP_FLAG_SGN, offsetof (DurableSupport_request, timeout), DDS_OP_RTS, /* key: client */ DDS_OP_KOF | 1, 1u /* order: 0 */, - + /* key: partition */ DDS_OP_KOF | 1, 4u /* order: 1 */, /* key: tpname */ - DDS_OP_KOF | 1, 6u /* order: 2 */ + DDS_OP_KOF | 1, 6u /* order: 2 */, + + /* key: type_id */ + DDS_OP_KOF | 1, 8u /* order: 3 */ }; -static const dds_key_descriptor_t DurableSupport_request_keys[3] = +static const dds_key_descriptor_t DurableSupport_request_keys[4] = { - { "client", 11, 0 }, - { "partition", 13, 1 }, - { "tpname", 15, 2 } + { "client", 13, 0 }, + { "partition", 15, 1 }, + { "tpname", 17, 2 }, + { "type_id", 19, 3 } }; /* Type Information: - [MINIMAL 3f4b9832b556de33be4c31963879] (#deps: 2) + [MINIMAL dd0d9462a253e8cce609462197f1] (#deps: 2) - [MINIMAL 43f53a2be35b432cc735e9431a89] - [MINIMAL 84ce9c3d894c1483f859c00d5927] - [COMPLETE 2992c8ff086f0c3d6eb4041c2b94] (#deps: 2) + [COMPLETE 798973adc9bb497149ff155ebd9a] (#deps: 2) - [COMPLETE aca4d5a256d39713924333e85c6d] - [COMPLETE 023df3bd21223779cd1936cef928] */ #define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ 0xc0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x3f, 0x4b, 0x98, 0x32, 0xb5, 0x56, 0xde, 0x33, 0xbe, 0x4c, 0x31, \ - 0x96, 0x38, 0x79, 0x00, 0x75, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0xdd, 0x0d, 0x94, 0x62, 0xa2, 0x53, 0xe8, 0xcc, 0xe6, 0x09, 0x46, \ + 0x21, 0x97, 0xf1, 0x00, 0x85, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, \ 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x29, 0x92, 0xc8, 0xff, 0x08, 0x6f, 0x0c, 0x3d, 0x6e, 0xb4, 0x04, \ - 0x1c, 0x2b, 0x94, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x79, 0x89, 0x73, 0xad, 0xc9, 0xbb, 0x49, 0x71, 0x49, 0xff, 0x15, \ + 0x5e, 0xbd, 0x9a, 0x00, 0xde, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ @@ -666,61 +679,64 @@ static const dds_key_descriptor_t DurableSupport_request_keys[3] = } #define TYPE_INFO_CDR_SZ_DurableSupport_request 196u #define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ - 0xdb, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0x3f, 0x4b, 0x98, 0x32, 0xb5, 0x56, 0xde, \ - 0x33, 0xbe, 0x4c, 0x31, 0x96, 0x38, 0x79, 0x00, 0x71, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0xeb, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0xdd, 0x0d, 0x94, 0x62, 0xa2, 0x53, 0xe8, \ + 0xcc, 0xe6, 0x09, 0x46, 0x21, 0x97, 0xf1, 0x00, 0x81, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ - 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ + 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, \ + 0x19, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ - 0x71, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0x29, 0x92, 0xc8, 0xff, 0x08, 0x6f, 0x0c, \ - 0x3d, 0x6e, 0xb4, 0x04, 0x1c, 0x2b, 0x94, 0x00, 0xbe, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0x8d, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0x79, 0x89, 0x73, 0xad, 0xc9, 0xbb, 0x49, \ + 0x71, 0x49, 0xff, 0x15, 0x5e, 0xbd, 0x9a, 0x00, 0xda, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x00, 0x92, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ + 0x65, 0x73, 0x74, 0x00, 0xae, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, \ 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, \ 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, \ 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x26, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, \ - 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, \ - 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x02, 0x3d, 0xf3, \ - 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x35, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0xf2, 0x29, 0x92, 0xc8, 0xff, 0x08, 0x6f, 0x0c, 0x3d, 0x6e, 0xb4, 0x04, 0x1c, 0x2b, 0x94, 0xf1, \ - 0x3f, 0x4b, 0x98, 0x32, 0xb5, 0x56, 0xde, 0x33, 0xbe, 0x4c, 0x31, 0x96, 0x38, 0x79, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, 0x3d, 0xf3, \ - 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, 0x9c, 0x3d, \ - 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ + 0x16, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, \ + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, \ + 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, \ + 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ + 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, \ + 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x75, 0x72, 0x61, \ + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0x79, 0x89, 0x73, \ + 0xad, 0xc9, 0xbb, 0x49, 0x71, 0x49, 0xff, 0x15, 0x5e, 0xbd, 0x9a, 0xf1, 0xdd, 0x0d, 0x94, 0x62, \ + 0xa2, 0x53, 0xe8, 0xcc, 0xe6, 0x09, 0x46, 0x21, 0x97, 0xf1, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, \ + 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, \ + 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, \ + 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_request 698u +#define TYPE_MAP_CDR_SZ_DurableSupport_request 742u const dds_topic_descriptor_t DurableSupport_request_desc = { .m_size = sizeof (DurableSupport_request), .m_align = dds_alignof (DurableSupport_request), .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 3u, + .m_nkeys = 4u, .m_typename = "DurableSupport::request", .m_keys = DurableSupport_request_keys, - .m_nops = 6, + .m_nops = 7, .m_ops = DurableSupport_request_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request }, @@ -739,7 +755,7 @@ static const uint32_t DurableSupport_response_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_response_content, _d), 2u, (12u << 16u) + 4u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 9 /* response_set_t */, 1, offsetof (DurableSupport_response_content, _u.set), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 15 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 17 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, DDS_OP_RTS, /* response_set_t */ @@ -747,6 +763,7 @@ static const uint32_t DurableSupport_response_ops [] = DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_response_set_t, delivery_id), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, partition), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, tpname), + DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, type_id), DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_response_set_t, flags), DDS_OP_RTS, @@ -754,119 +771,120 @@ static const uint32_t DurableSupport_response_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_response_data_t, blob), DDS_OP_RTS, - + /* key: id */ DDS_OP_KOF | 1, 1u /* order: 0 */ }; static const dds_key_descriptor_t DurableSupport_response_keys[1] = { - { "id", 36, 0 } + { "id", 38, 0 } }; /* Type Information: - [MINIMAL 730b9fd245b7a2458badcdadd452] (#deps: 6) + [MINIMAL 7172db81541171f4d3215f317121] (#deps: 6) - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL b2788efd3d9c71afbf128dd8d568] + - [MINIMAL adf1bdbb30b9d6975e377ee51fa4] - [MINIMAL 80455e796dd3437163cb532089da] - - [MINIMAL 26fb4226a2ccc89e6a040bf4add4] + - [MINIMAL 19656e10c4f1e4cd8e04106c5b0f] - [MINIMAL d8398b259af5a04792e296996c27] - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE 11d82f7f8e658cff91d8836b578f] (#deps: 6) + [COMPLETE eb98abe5dd8d7bfb5b2507da617d] (#deps: 6) - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE b6edd532689bbbb0dee0ee93c7ae] + - [COMPLETE 5c1f20e6410aad78dfe023066879] - [COMPLETE eec1bad6badde73f40ef199fedcc] - - [COMPLETE 6c90b4bf595ec04bb56d1fd6e2b5] + - [COMPLETE e4730a78f541604cc1a1a037ef05] - [COMPLETE 7b005a124ff7bda9c39eb4003556] - [COMPLETE 008875599776c39ce0c1fe897846] */ #define TYPE_INFO_CDR_DurableSupport_response (const unsigned char []){ \ 0x80, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x73, 0x0b, 0x9f, 0xd2, 0x45, 0xb7, 0xa2, 0x45, 0x8b, 0xad, 0xcd, \ - 0xad, 0xd4, 0x52, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x71, 0x72, 0xdb, 0x81, 0x54, 0x11, 0x71, 0xf4, 0xd3, 0x21, 0x5f, \ + 0x31, 0x71, 0x21, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xb2, 0x78, 0x8e, 0xfd, 0x3d, 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0x00, \ + 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, 0xb9, 0xd6, 0x97, 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0x00, \ 0x7c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x26, 0xfb, 0x42, 0x26, 0xa2, 0xcc, 0xc8, 0x9e, 0x6a, 0x04, 0x0b, 0xf4, 0xad, 0xd4, 0x00, \ - 0x67, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ + 0xf1, 0x19, 0x65, 0x6e, 0x10, 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, 0x5b, 0x0f, 0x00, \ + 0x77, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x11, 0xd8, 0x2f, 0x7f, 0x8e, 0x65, 0x8c, 0xff, 0x91, 0xd8, 0x83, \ - 0x6b, 0x57, 0x8f, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0xeb, 0x98, 0xab, 0xe5, 0xdd, 0x8d, 0x7b, 0xfb, 0x5b, 0x25, 0x07, \ + 0xda, 0x61, 0x7d, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xb6, 0xed, 0xd5, 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, 0xe0, 0xee, 0x93, 0xc7, 0xae, 0x00, \ + 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, 0x78, 0xdf, 0xe0, 0x23, 0x06, 0x68, 0x79, 0x00, \ 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, \ 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, 0xc0, 0x4b, 0xb5, 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0x00, \ - 0xbc, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, \ + 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, 0x60, 0x4c, 0xc1, 0xa1, 0xa0, 0x37, 0xef, 0x05, 0x00, \ + 0xd8, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, \ 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ 0x57, 0x00, 0x00, 0x00\ } #define TYPE_INFO_CDR_SZ_DurableSupport_response 388u #define TYPE_MAP_CDR_DurableSupport_response (const unsigned char []){ \ - 0x20, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0x73, 0x0b, 0x9f, 0xd2, 0x45, 0xb7, 0xa2, \ - 0x45, 0x8b, 0xad, 0xcd, 0xad, 0xd4, 0x52, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x30, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0x71, 0x72, 0xdb, 0x81, 0x54, 0x11, 0x71, \ + 0xf4, 0xd3, 0x21, 0x5f, 0x31, 0x71, 0x21, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xb2, 0x78, 0x8e, 0xfd, 0x3d, \ - 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, \ + 0xb9, 0xd6, 0x97, 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0xb2, 0x78, 0x8e, 0xfd, 0x3d, \ - 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, \ + 0xb9, 0xd6, 0x97, 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ 0x54, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x26, 0xfb, 0x42, 0x26, 0xa2, 0xcc, 0xc8, 0x9e, 0x6a, 0x04, 0x0b, 0xf4, 0xad, \ - 0xd4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ + 0x01, 0x00, 0xf1, 0x19, 0x65, 0x6e, 0x10, 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, 0x5b, \ + 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x26, 0xfb, 0x42, 0x26, \ - 0xa2, 0xcc, 0xc8, 0x9e, 0x6a, 0x04, 0x0b, 0xf4, 0xad, 0xd4, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x19, 0x65, 0x6e, 0x10, \ + 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, 0x5b, 0x0f, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x7c, 0x4b, 0x99, \ 0xfe, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x7e, 0x75, 0xc0, 0xed, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, \ + 0x7e, 0x75, 0xc0, 0xed, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x94, 0x75, 0x7c, 0xae, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, \ 0x58, 0x68, 0xd6, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, \ 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \ - 0xee, 0x26, 0x90, 0x8b, 0x7f, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0x11, 0xd8, 0x2f, \ - 0x7f, 0x8e, 0x65, 0x8c, 0xff, 0x91, 0xd8, 0x83, 0x6b, 0x57, 0x8f, 0x00, 0x83, 0x00, 0x00, 0x00, \ + 0xee, 0x26, 0x90, 0x8b, 0x9b, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0xeb, 0x98, 0xab, \ + 0xe5, 0xdd, 0x8d, 0x7b, 0xfb, 0x5b, 0x25, 0x07, 0xda, 0x61, 0x7d, 0x00, 0x83, 0x00, 0x00, 0x00, \ 0xf2, 0x51, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, \ 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xb6, 0xed, 0xd5, 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, \ - 0xe0, 0xee, 0x93, 0xc7, 0xae, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, 0x78, 0xdf, \ + 0xe0, 0x23, 0x06, 0x68, 0x79, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, \ 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, \ 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x10, 0x02, 0x00, 0x00, 0xf2, 0xb6, 0xed, 0xd5, 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, 0xe0, 0xee, \ - 0x93, 0xc7, 0xae, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, \ + 0x10, 0x02, 0x00, 0x00, 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, 0x78, 0xdf, 0xe0, 0x23, \ + 0x06, 0x68, 0x79, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, \ 0x11, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, \ 0xcc, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, 0xc0, 0x4b, 0xb5, \ - 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, 0x60, 0x4c, 0xc1, \ + 0xa1, 0xa0, 0x37, 0xef, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, \ 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ @@ -875,47 +893,48 @@ static const dds_key_descriptor_t DurableSupport_response_keys[1] = 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, \ 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, \ - 0xc0, 0x4b, 0xb5, 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0xb8, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, \ + 0x60, 0x4c, 0xc1, 0xa1, 0xa0, 0x37, 0xef, 0x05, 0xd4, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, \ - 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x7b, \ + 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x7b, \ 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, 0x00, 0x00, \ 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, \ - 0x73, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, \ - 0x00, 0x35, 0x56, 0x00, 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, \ - 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, \ - 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, \ - 0x53, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x20, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, \ - 0x61, 0x5f, 0x74, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, \ - 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0xf2, 0x11, 0xd8, 0x2f, 0x7f, 0x8e, 0x65, 0x8c, 0xff, 0x91, 0xd8, 0x83, 0x6b, 0x57, 0x8f, 0xf1, \ - 0x73, 0x0b, 0x9f, 0xd2, 0x45, 0xb7, 0xa2, 0x45, 0x8b, 0xad, 0xcd, 0xad, 0xd4, 0x52, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0xb6, 0xed, 0xd5, \ - 0x32, 0x68, 0x9b, 0xbb, 0xb0, 0xde, 0xe0, 0xee, 0x93, 0xc7, 0xae, 0xf1, 0xb2, 0x78, 0x8e, 0xfd, \ - 0x3d, 0x9c, 0x71, 0xaf, 0xbf, 0x12, 0x8d, 0xd8, 0xd5, 0x68, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, \ - 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, \ - 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x6c, 0x90, 0xb4, 0xbf, 0x59, 0x5e, 0xc0, \ - 0x4b, 0xb5, 0x6d, 0x1f, 0xd6, 0xe2, 0xb5, 0xf1, 0x26, 0xfb, 0x42, 0x26, 0xa2, 0xcc, 0xc8, 0x9e, \ - 0x6a, 0x04, 0x0b, 0xf4, 0xad, 0xd4, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, \ - 0x9e, 0xb4, 0x00, 0x35, 0x56, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, \ - 0x96, 0x99, 0x6c, 0x27, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, \ - 0x89, 0x78, 0x46, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, \ - 0xe8, 0x44\ + 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, \ + 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ + 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, \ + 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x5f, \ + 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xf2, 0x00, 0x88, \ + 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x53, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, \ + 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0xeb, 0x98, 0xab, \ + 0xe5, 0xdd, 0x8d, 0x7b, 0xfb, 0x5b, 0x25, 0x07, 0xda, 0x61, 0x7d, 0xf1, 0x71, 0x72, 0xdb, 0x81, \ + 0x54, 0x11, 0x71, 0xf4, 0xd3, 0x21, 0x5f, 0x31, 0x71, 0x21, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, \ + 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, \ + 0x78, 0xdf, 0xe0, 0x23, 0x06, 0x68, 0x79, 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, 0xb9, 0xd6, 0x97, \ + 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ + 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, \ + 0x53, 0x20, 0x89, 0xda, 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, 0x60, 0x4c, 0xc1, 0xa1, 0xa0, \ + 0x37, 0xef, 0x05, 0xf1, 0x19, 0x65, 0x6e, 0x10, 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, \ + 0x5b, 0x0f, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, \ + 0x56, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, \ + 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0xf1, \ + 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_response 1666u +#define TYPE_MAP_CDR_SZ_DurableSupport_response 1710u const dds_topic_descriptor_t DurableSupport_response_desc = { .m_size = sizeof (DurableSupport_response), @@ -924,7 +943,7 @@ const dds_topic_descriptor_t DurableSupport_response_desc = .m_nkeys = 1u, .m_typename = "DurableSupport::response", .m_keys = DurableSupport_response_keys, - .m_nops = 18, + .m_nops = 19, .m_ops = DurableSupport_response_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_response, .sz = TYPE_INFO_CDR_SZ_DurableSupport_response }, From 353fad4ef612917ae3b9da392d77ddbd20fe9cc4 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 22 Mar 2024 14:02:16 +0100 Subject: [PATCH 198/207] Fix merge issues when rebasing on CycloneDDS master Signed-off-by: TheFixer --- docs/manual/config/config_file_reference.rst | 6 +++--- docs/manual/options.md | 2 +- etc/cyclonedds.rnc | 2 +- etc/cyclonedds.xsd | 2 +- src/core/ddsc/src/dds_participant.c | 13 +++++++++++-- src/core/ddsc/src/dds_reader.c | 8 +++++++- src/core/ddsc/src/dds_write.c | 8 +++++--- src/core/ddsi/defconfig.c | 2 +- src/durability/src/dds_durability.c | 12 +++++++----- 9 files changed, 37 insertions(+), 18 deletions(-) diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index fd0a2b1169..1f42273a2f 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -22,7 +22,7 @@ CycloneDDS configuration ******************* Attributes: :ref:`Id` -Children: :ref:`Compatibility`, :ref:`Discovery`, :ref:`Discovery`, :ref:`General`, :ref:`Internal|Unsupported`, :ref:`Partitioning`, :ref:`SSL`, :ref:`Security|DDSSecurity`, :ref:`SharedMemory`, :ref:`Sizing`, :ref:`TCP`, :ref:`Threads`, :ref:`Tracing` +Children: :ref:`Compatibility`, :ref:`Discovery`, :ref:`Durability`, :ref:`General`, :ref:`Internal|Unsupported`, :ref:`Partitioning`, :ref:`SSL`, :ref:`Security|DDSSecurity`, :ref:`SharedMemory`, :ref:`Sizing`, :ref:`TCP`, :ref:`Threads`, :ref:`Tracing` The General element specifying Domain related settings. @@ -398,7 +398,7 @@ The default value is: ```` //CycloneDDS/Domain/Durability ============================== -Children: `//CycloneDDS/Domain/Durability/Quorum`_ +Children: :ref:`Quorum` This element specifies settings related to durable data. @@ -2745,7 +2745,7 @@ The default value is: ``none`` .. generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] - generated from ddsi__cfgelems.h[0fe5caa90873f3af7436f0f201edeccaea9fedd4] + generated from ddsi__cfgelems.h[fb5382bc6dbb34bca275d20c3c4282f948318862] generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] diff --git a/docs/manual/options.md b/docs/manual/options.md index ea8dfe448d..288aad21ff 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -1927,7 +1927,7 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: `none` - + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index 1ed01cd022..b054f3c0cf 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -1332,7 +1332,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
    } # generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] # generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] -# generated from ddsi__cfgelems.h[0fe5caa90873f3af7436f0f201edeccaea9fedd4] +# generated from ddsi__cfgelems.h[fb5382bc6dbb34bca275d20c3c4282f948318862] # generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] # generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] # generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index 9c61abcc4a..32a19ea027 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -2001,7 +2001,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - + diff --git a/src/core/ddsc/src/dds_participant.c b/src/core/ddsc/src/dds_participant.c index dcdcf0f7db..c3e6d1cc5a 100644 --- a/src/core/ddsc/src/dds_participant.c +++ b/src/core/ddsc/src/dds_participant.c @@ -64,9 +64,16 @@ static dds_return_t dds_participant_delete (dds_entity *e) ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); #ifdef DDS_HAS_DURABILITY - dds_durability_fini(); + (void)dds_durability_fini(); #endif + /* todo It seems incorrect that dds_participant_delete() + * always returns DDS_RETCODE_OK, even if an error has + * occurred along the way (e.g., in ddsi_delete_participant()). + * I tried returning the actual return code, but that causes + * test cases to fail. For now I leave it as is, but this is + * something that should be fixed eventually (I think). + */ return DDS_RETCODE_OK; } @@ -182,7 +189,9 @@ static dds_entity_t create_participant_flags_guid (const dds_domainid_t domain, dds_entity_unpin_and_drop_ref (&dds_global.m_entity); #ifdef DDS_HAS_DURABILITY - dds_durability_init (domain, &dom->gv); + if (ret > 0) { + (void)dds_durability_init (domain, &dom->gv); + } #endif return ret; diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index 043f468ed1..b0a57d6d7a 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -704,7 +704,10 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe #ifdef DDS_HAS_DURABILITY dds_durability_kind_t dkind; - dds_qget_durability(rqos, &dkind); + if (!dds_qget_durability(rqos, &dkind)) { + rc = DDS_RETCODE_ERROR; + goto err_qget_durability; + } #endif /* Create reader and associated read cache (if not provided by caller) */ @@ -811,6 +814,9 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe err_rd_guid: dds_endpoint_remove_psmx_endpoints (&rd->m_endpoint); err_create_endpoint: +#ifdef DDS_HAS_DURABILITY +err_qget_durability: +#endif err_bad_qos: #ifdef DDS_HAS_SECURITY err_not_allowed: diff --git a/src/core/ddsc/src/dds_write.c b/src/core/ddsc/src/dds_write.c index 1b8e3d33fc..a9761aaf1f 100644 --- a/src/core/ddsc/src/dds_write.c +++ b/src/core/ddsc/src/dds_write.c @@ -52,7 +52,7 @@ dds_return_t dds_write (dds_entity_t writer, const void *data) * LH: This implementation may be suboptimal, because determining whether the * quorum is fulfilled, and the actual publication of the data is not done * within the same writer lock. So after the quorum has been established, - * and before the data is published, the quorum could have been dropped. + * and before the data is published, the quorum could have been dropped again. * Chances for this to happen are slim, but still ... */ if ((ret = dds_durability_wait_for_quorum(writer)) != DDS_RETCODE_OK) { return ret; @@ -790,13 +790,15 @@ dds_return_t dds_write_impl (dds_writer *wr, const void *data, dds_time_t timest return DDS_RETCODE_OK; #ifdef DDS_HAS_DURABILITY - /* check if the quorum of durable services for the writer is fulfilled - * + /* Check if the quorum of durable services for the writer is fulfilled + * If it is not met within the max_blocking_time, then DDS_RETCODE_PRECONDITION_NOT_MET + * is returned. * LH: * todo this currently is solution to handle the case when the quorum is not yet reached. * A better solution would be to use the max_blocking_time and use it to figure out * if the quorum is reached within this time frame. The headbang period would then be * used to check if the quorum is met. */ + struct ddsi_writer * const ddsi_wr = wr->m_wr; if ((ddsi_wr->xqos->durability.kind == DDS_DURABILITY_TRANSIENT) || (ddsi_wr->xqos->durability.kind == DDS_DURABILITY_PERSISTENT)) { if (!wr->quorum_reached) { return DDS_RETCODE_PRECONDITION_NOT_MET; diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index 3f541abdd8..c43ec9a58f 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -104,7 +104,7 @@ void ddsi_config_init_default (struct ddsi_config *cfg) } /* generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] */ /* generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] */ -/* generated from ddsi__cfgelems.h[0fe5caa90873f3af7436f0f201edeccaea9fedd4] */ +/* generated from ddsi__cfgelems.h[fb5382bc6dbb34bca275d20c3c4282f948318862] */ /* generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] */ /* generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] */ /* generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] */ diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 0345f60dab..696c1c4392 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -751,7 +751,7 @@ static bool dc_is_ds_endpoint (struct com_t *com, dds_builtintopic_endpoint_t *e /* Determine if the quorum for the writer is reached or not. * This function also does its job when the quorum threshold is 0, - * even though this case is likely to be prohibited because it + * even though this case should likely be prohibited because it * violates eventual consistency. After all, how can you provide * historical data if you allow that durable publishers start to * publish when there is no durable support? */ @@ -810,8 +810,9 @@ static void dc_check_quorum_reached (struct dc_t *dc, dds_entity_t writer, bool * that the quorum_reached property of the writer changes. * Because the call to dds_get_matched_subscriptions() requires * an preallocated list of reader handles and we don't know the - * size of the list beforehand, we dynamically extend the list - * until it is large enough to hold all handles of matching readers. */ + * size of the list beforehand, we initially bound the list to + * 256 and extend it dynamically until it is large enough to hold + * all handles of matching readers. */ do { nrds = nrds * 2; rd_ihs = ddsrt_malloc(nrds * sizeof(dds_instance_handle_t)); @@ -1751,7 +1752,6 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade DDS_ERROR("failed to get partitions from qos\n"); goto err_qget_partition; } - assert(plen > 0); /* for each partition create a proxy set if it does not exist yet * and request data for the proxy set (if not done so already) */ for (i=0; i < plen; i++) { @@ -2122,13 +2122,15 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); ddsrt_free(dc.cfg.ident); + ddsrt_atomic_dec32(&dc.refcount); + memset(&dc, 0, sizeof(struct dc_t)); return DDS_RETCODE_ERROR; } /* make sure that dc terminates when the last participant is destroyed */ dds_return_t dds_durability_fini (void) { - dds_return_t rc; + dds_return_t rc = DDS_RETCODE_OK; uint32_t refcount; /* The durable client is deinitialized when the last participant is about From f06a86b94e064bbbda5039659f596d58aee9248c Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 22 Mar 2024 14:04:04 +0100 Subject: [PATCH 199/207] Exclude test cases for transient and persistent profiles when there is no durable support yet Signed-off-by: TheFixer --- src/core/ddsc/tests/entity_status.c | 2 +- src/core/ddsc/tests/qosmatch.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/ddsc/tests/entity_status.c b/src/core/ddsc/tests/entity_status.c index 83611e56a7..9defb9c7b1 100644 --- a/src/core/ddsc/tests/entity_status.c +++ b/src/core/ddsc/tests/entity_status.c @@ -235,7 +235,7 @@ CU_Test(ddsc_entity, incompatible_qos, .init=init_entity_status, .fini=fini_enti dds_offered_incompatible_qos_status_t off_incompatible_qos; memset (&req_incompatible_qos, 0, sizeof (req_incompatible_qos)); memset (&off_incompatible_qos, 0, sizeof (off_incompatible_qos)); - dds_qset_durability (qos, DDS_DURABILITY_PERSISTENT); + dds_qset_durability (qos, DDS_DURABILITY_TRANSIENT_LOCAL); /* Create a reader with persistent durability */ reader2 = dds_create_reader(participant, top, qos, NULL); diff --git a/src/core/ddsc/tests/qosmatch.c b/src/core/ddsc/tests/qosmatch.c index 8a1448d1d7..e6329f5842 100644 --- a/src/core/ddsc/tests/qosmatch.c +++ b/src/core/ddsc/tests/qosmatch.c @@ -81,10 +81,12 @@ static void setqos (dds_qos_t *q, size_t i, bool isrd, bool create) } /* Cyclone's accepting unimplemented QoS settings is a bug, but it does allow - us to feed it all kinds of nonsense and see whether discovery manages it */ + us to feed it all kinds of nonsense and see whether discovery manages it. + As far as the durability qos setting is concerned, we restrict it to VOLATILE + and TRANSIENT-LOCAL for the moment while implementing the durable profiles */ /* this makes topic transient-local, keep-last 1 */ - dds_qset_durability (q, (dds_durability_kind_t) ((i + 1) % 4)); + dds_qset_durability (q, (dds_durability_kind_t) ((i + 1) % 2)); dds_qset_history (q, (dds_history_kind_t) ((i + 1) % 2), (int32_t) (i + 1)); dds_qset_resource_limits (q, (int32_t) i + 3, (int32_t) i + 2, (int32_t) i + 1); dds_qset_presentation (q, (dds_presentation_access_scope_kind_t) ((psi + 1) % 3), 1, 1); From 22d638bb987d8997c5a4ba33c7a138deb0a29876 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 29 Mar 2024 14:56:32 +0100 Subject: [PATCH 200/207] Don't set a quorum on writers created by a DS Signed-off-by: TheFixer --- src/durability/src/dds_durability.c | 136 +++++++++++++++++++--------- 1 file changed, 93 insertions(+), 43 deletions(-) diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 696c1c4392..1f7b95faaa 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -2243,65 +2243,115 @@ dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rh return rc; } +/* Returns TRUE if the entity is an application entity, false otherwise */ +static bool is_application_entity (struct dc_t *dc, dds_entity_t entity) +{ + dds_qos_t *pqos; + dds_entity_t participant; + dds_return_t rc; + char *ident = dc->cfg.ident; + void *userdata; + size_t size = 0; + bool result = true; + + /* by convention, if there is no ident every entity is considered a local entity */ + if (ident == NULL) { + return true; + } + pqos = dds_create_qos(); + /* get the entity's participant, and determine if ident is present in the userdata */ + if ((participant = dds_get_participant(entity)) < 0) { + DDS_ERROR("dds_get_participant failed [%s]\n", dds_strretcode(participant)); + goto err_get_participant; + } + if ((rc = dds_get_qos(participant, pqos)) < 0) { + DDS_ERROR("Failed to get participant qos [%s]\n", dds_strretcode(rc)); + goto err_get_participant_qos; + } + if (!dds_qget_userdata(pqos, &userdata, &size)) { + DDS_ERROR("Unable to retrieve the participant's user data"); + goto err_qget_userdata; + } + if ((size != strlen(ident)) || (userdata == NULL) || (strcmp(userdata, ident) != 0)) { + /* the user data of the participant of the entity does not contain the ident, + * so the entity is an application entity */ + result = true; + } else { + /* the entity resides on a DS */ + result = false; + } + dds_free(userdata); + dds_delete_qos(pqos); + return result; + +err_qget_userdata: +err_get_participant_qos: +err_get_participant: + dds_delete_qos(pqos); + return true; +} + +/* check if the writer is a durable application writer, and if so, we need to keep track of the quorum */ dds_return_t dds_durability_new_local_writer (dds_entity_t writer) { dds_durability_kind_t dkind; - dds_qos_t *qos; - dds_return_t rc = DDS_RETCODE_ERROR; + dds_qos_t *wqos; + dds_return_t rc ; dds_guid_t wguid; char id_str[37]; - /* check if the writer is a durable writer, and if so, we need to keep track of the quorum */ - assert(writer); - qos = dds_create_qos(); - if ((rc = dds_get_qos(writer, qos)) < 0) { - DDS_ERROR("failed to get qos from writer [%s]\n", dds_strretcode(rc)); + /* We only need to apply quorum checking for durable application writers. + * Writers created by a DS (if any) do not have to be subjected to + * quorum checking */ + if ((rc = dds_get_guid(writer, &wguid)) != DDS_RETCODE_OK) { + DDS_ERROR("failed to retrieve writer guid\n"); + goto err_get_guid; + } + wqos = dds_create_qos(); + if ((rc = dds_get_qos(writer, wqos)) < 0) { + DDS_ERROR("failed to get qos from writer \"%s\" [%s]\n", dc_stringify_id(wguid.v, id_str), dds_strretcode(rc)); goto err_get_qos; } - if (!dds_qget_durability(qos, &dkind)) { - DDS_ERROR("failed to retrieve durability qos"); + if (!dds_qget_durability(wqos, &dkind)) { + DDS_ERROR("failed to retrieve durability qos for writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); goto err_qget_durability; } - if ((dkind == DDS_DURABILITY_TRANSIENT) || (dkind == DDS_DURABILITY_PERSISTENT)) { - assert(dc.quorum_listener); - /* The writer is durable, so subjected to reaching a quorum before - * it can start publishing. We set a publication_matched listener on - * the writer. Each time a matching durable data container is discovered - * the listener will be triggered, causing relevant quora to be updated - * accordingly. - * - * Note that setting a publication_matched listener implies that we do NOT - * allow that user application can set a listener on durable writers. - * This is currently a limitation. */ - if ((rc = dds_get_guid(writer, &wguid)) != DDS_RETCODE_OK) { - DDS_ERROR("failed to retrieve writer guid"); - goto err_get_guid; - } - /* We now set a quorum listener on the durable writer. - * Each time a matching reader will appear, wewill get notified. - * Existing readers may already have matched before the listener takes effect, - * so these publication_match events may be missed. Luckily, we can request - * all matching readers using dds_get_matched_subscriptions(). - * - * Note: be aware that the same readers can be present in the list provided - * by dds_get_matched_subscriptions(), and can also be triggered by the listener. - * Avoid counting these readers twice! - */ - DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "durable writer \"%s\" subject to quorum checking\n", dc_stringify_id(wguid.v, id_str)); - if ((rc = dds_set_listener(writer, dc.quorum_listener)) < 0) { - DDS_ERROR("Unable to set the quorum listener on writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); - goto err_set_listener; - } - dc_check_quorum_reached(&dc, writer, true); + /* not a durable writer, no quorum checking required */ + if ((dkind != DDS_DURABILITY_TRANSIENT) && (dkind != DDS_DURABILITY_PERSISTENT)) { + goto skip; + } + /* not an application writer, no quorum checking required */ + if (!is_application_entity(&dc, writer)) { + goto skip; + } + assert(dc.quorum_listener); + /* The writer is a durable application writer, so subjected to reaching + * a quorum before it can start publishing. We set a publication_matched + * listener on the writer. Each time a matching durable data container is + * discovered the listener will be triggered, causing relevant quora to + * be updated accordingly. + * + * Note: + * - setting a publication_matched listener implies that we do NOT + * allow that user applications can set a listener on durable writers. + * This is currently a limitation. + * - be aware that the same readers can be present in the list provided + * by dds_get_matched_subscriptions(), and can also be triggered by the listener. + * Avoid counting these readers twice! */ + if ((rc = dds_set_listener(writer, dc.quorum_listener)) < 0) { + DDS_ERROR("Unable to set the quorum listener on writer \"%s\"\n", dc_stringify_id(wguid.v, id_str)); + goto err_set_listener; } - dds_delete_qos(qos); + dc_check_quorum_reached(&dc, writer, true); +skip: + dds_delete_qos(wqos); return DDS_RETCODE_OK; err_set_listener: -err_get_guid: err_qget_durability: err_get_qos: - dds_delete_qos(qos); + dds_delete_qos(wqos); +err_get_guid: return rc; } From d1af80e34033d8c3ba6a04b5baea5cb51c6aa15e Mon Sep 17 00:00:00 2001 From: TheFixer Date: Fri, 29 Mar 2024 15:00:28 +0100 Subject: [PATCH 201/207] Don't run security tests when durability is enabled (they don't go well together) Signed-off-by: TheFixer --- src/security/core/CMakeLists.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/security/core/CMakeLists.txt b/src/security/core/CMakeLists.txt index 418fb3eb45..81bb2f5eb8 100644 --- a/src/security/core/CMakeLists.txt +++ b/src/security/core/CMakeLists.txt @@ -45,8 +45,16 @@ target_include_directories(security_core "$>" ) -if(BUILD_TESTING) - add_subdirectory(tests) +# Security and durable support are a problematic combination. +# Currently, the topics required for durable support are not +# part of the security configuration in the tests. This causes +# security test cases to fail when durable support is enabled. +# Until this is solved we only run security tests when +# durable support is NOT enabed. +if(NOT ENABLE_DURABILITY) + if(BUILD_TESTING) + add_subdirectory(tests) + endif() endif() install( From bc4e598746430150e02c285ee881ab34ec51f101 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 2 Apr 2024 15:50:28 +0200 Subject: [PATCH 202/207] Add reader guid to dc_request Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 1 + src/durability/src/dds_durability.c | 16 +-- src/durability/src/durablesupport.c | 114 ++++++++++-------- 3 files changed, 72 insertions(+), 59 deletions(-) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index 2f8adc59b7..0e5aaf84da 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -275,6 +275,7 @@ typedef uint64_t DurableSupport_delivery_id_t; typedef struct DurableSupport_request { DurableSupport_id_t client; + DurableSupport_id_t rguid; char * partition; char * tpname; char * type_id; diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 1f7b95faaa..869d4f29e0 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -146,6 +146,7 @@ static int dc_stringify_request (char *buf, size_t n, const DurableSupport_reque size_t i = 0; int l; char id_str[37]; + char rguid_str[37]; int64_t sec; uint32_t msec; @@ -159,7 +160,7 @@ static int dc_stringify_request (char *buf, size_t n, const DurableSupport_reque if (valid_data) { /* also print non-key fields */ if (request->timeout == DDS_INFINITY) { - if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"timeout\":\"never\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, request->type_id)) < 0) { + if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"rguid\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"timeout\":\"never\"}", dc_stringify_id(request->client, id_str), dc_stringify_id(request->rguid, rguid_str), request->partition, request->tpname, request->type_id)) < 0) { goto err; } } else { @@ -1200,7 +1201,7 @@ static void dc_com_free (struct com_t *com) #define MAX_TOPIC_NAME_SIZE 255 -static dds_return_t dc_com_request_write (struct com_t *com, const char *partition, const char *tpname, const char *type_id) +static dds_return_t dc_com_request_write (struct com_t *com, const dds_guid_t rguid, const char *partition, const char *tpname, const char *type_id) { /* note: we allow doing a request for volatile readers */ DurableSupport_request *request; @@ -1211,6 +1212,7 @@ static dds_return_t dc_com_request_write (struct com_t *com, const char *partiti request = DurableSupport_request__alloc(); memcpy(request->client, dc.cfg.id, 16); + memcpy(request->rguid, rguid.v, 16); request->partition = ddsrt_strdup(partition); request->tpname = ddsrt_strdup(tpname); request->type_id = ddsrt_strdup(type_id); @@ -1706,7 +1708,7 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade uint32_t plen, i; char **partitions; struct proxy_set_t *proxy_set = NULL; - dds_guid_t guid; + dds_guid_t rguid; char id_str[37]; dds_typeinfo_t *typeinfo; ddsi_typeid_t *tid = NULL; @@ -1722,11 +1724,11 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade } (void)ddsi_make_typeid_str(&tidstr, tid); /* get reader guid */ - if ((rc = dds_get_guid(reader, &guid)) < DDS_RETCODE_OK) { + if ((rc = dds_get_guid(reader, &rguid)) < DDS_RETCODE_OK) { DDS_ERROR("Unable to retrieve the guid of the reader [%s]\n", dds_strretcode(-rc)); goto err_get_guid; } - (void)dc_stringify_id(guid.v, id_str); + (void)dc_stringify_id(rguid.v, id_str); /* get topic name */ if ((topic = dds_get_topic(reader)) < 0) { DDS_ERROR("Unable to get topic from reader [%s]\n", dds_strretcode(-topic)); @@ -1761,9 +1763,9 @@ static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reade * We do this BEFORE we send the request, so that we are sure * that when we receive the response (possibly immediately after * sending the request) the reader and rhc are present */ - dc_register_reader_to_proxy_set(dc, proxy_set, guid, reader, rhc); + dc_register_reader_to_proxy_set(dc, proxy_set, rguid, reader, rhc); /* send a request for this proxy set */ - if ((rc = dc_com_request_write(dc->com, proxy_set->key.partition, proxy_set->key.tpname, proxy_set->key.type_id)) != DDS_RETCODE_OK) { + if ((rc = dc_com_request_write(dc->com, rguid, proxy_set->key.partition, proxy_set->key.tpname, proxy_set->key.type_id)) != DDS_RETCODE_OK) { DDS_ERROR("Failed to publish dc_request for proxy set %s.%s\n", proxy_set->key.partition, proxy_set->key.tpname); /* We failed to request data for this proxy set. * We could do several things now, e.g., 1) try again until we succeed, diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index 2395d59455..44413aaa4f 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -627,6 +627,7 @@ static const uint32_t DurableSupport_request_ops [] = /* request */ DDS_OP_DLC, DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, client), 16u, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, rguid), 16u, DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, partition), DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, type_id), @@ -636,42 +637,46 @@ static const uint32_t DurableSupport_request_ops [] = /* key: client */ DDS_OP_KOF | 1, 1u /* order: 0 */, - /* key: partition */ + /* key: rguid */ DDS_OP_KOF | 1, 4u /* order: 1 */, + + /* key: partition */ + DDS_OP_KOF | 1, 7u /* order: 2 */, /* key: tpname */ - DDS_OP_KOF | 1, 6u /* order: 2 */, + DDS_OP_KOF | 1, 9u /* order: 3 */, /* key: type_id */ - DDS_OP_KOF | 1, 8u /* order: 3 */ + DDS_OP_KOF | 1, 11u /* order: 4 */ }; -static const dds_key_descriptor_t DurableSupport_request_keys[4] = +static const dds_key_descriptor_t DurableSupport_request_keys[5] = { - { "client", 13, 0 }, - { "partition", 15, 1 }, - { "tpname", 17, 2 }, - { "type_id", 19, 3 } + { "client", 16, 0 }, + { "rguid", 18, 1 }, + { "partition", 20, 2 }, + { "tpname", 22, 3 }, + { "type_id", 24, 4 } }; /* Type Information: - [MINIMAL dd0d9462a253e8cce609462197f1] (#deps: 2) + [MINIMAL ab970ab07c061f95f865be523bb0] (#deps: 2) - [MINIMAL 43f53a2be35b432cc735e9431a89] - [MINIMAL 84ce9c3d894c1483f859c00d5927] - [COMPLETE 798973adc9bb497149ff155ebd9a] (#deps: 2) + [COMPLETE ca811b13ce9943d64d1fa75ace5f] (#deps: 2) - [COMPLETE aca4d5a256d39713924333e85c6d] - [COMPLETE 023df3bd21223779cd1936cef928] */ #define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ 0xc0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0xdd, 0x0d, 0x94, 0x62, 0xa2, 0x53, 0xe8, 0xcc, 0xe6, 0x09, 0x46, \ - 0x21, 0x97, 0xf1, 0x00, 0x85, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0xab, 0x97, 0x0a, 0xb0, 0x7c, 0x06, 0x1f, 0x95, 0xf8, 0x65, 0xbe, \ + 0x52, 0x3b, 0xb0, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, \ 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x79, 0x89, 0x73, 0xad, 0xc9, 0xbb, 0x49, 0x71, 0x49, 0xff, 0x15, \ - 0x5e, 0xbd, 0x9a, 0x00, 0xde, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0xca, 0x81, 0x1b, 0x13, 0xce, 0x99, 0x43, 0xd6, 0x4d, 0x1f, 0xa7, \ + 0x5a, 0xce, 0x5f, 0x00, 0x06, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ @@ -679,64 +684,68 @@ static const dds_key_descriptor_t DurableSupport_request_keys[4] = } #define TYPE_INFO_CDR_SZ_DurableSupport_request 196u #define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ - 0xeb, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0xdd, 0x0d, 0x94, 0x62, 0xa2, 0x53, 0xe8, \ - 0xcc, 0xe6, 0x09, 0x46, 0x21, 0x97, 0xf1, 0x00, 0x81, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x0b, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0xab, 0x97, 0x0a, 0xb0, 0x7c, 0x06, 0x1f, \ + 0x95, 0xf8, 0x65, 0xbe, 0x52, 0x3b, 0xb0, 0x00, 0xa1, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ - 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ - 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, \ - 0x19, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xaf, 0xc4, 0x1d, 0xc3, 0x00, 0x00, 0x00, \ + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ + 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ + 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, \ + 0x19, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ - 0x8d, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0x79, 0x89, 0x73, 0xad, 0xc9, 0xbb, 0x49, \ - 0x71, 0x49, 0xff, 0x15, 0x5e, 0xbd, 0x9a, 0x00, 0xda, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ + 0xb5, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0xca, 0x81, 0x1b, 0x13, 0xce, 0x99, 0x43, \ + 0xd6, 0x4d, 0x1f, 0xa7, 0x5a, 0xce, 0x5f, 0x00, 0x02, 0x01, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x00, 0xae, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ + 0x65, 0x73, 0x74, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, \ - 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, \ - 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, \ - 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x16, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, \ - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, \ - 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, \ - 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, \ - 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x75, 0x72, 0x61, \ - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0x79, 0x89, 0x73, \ - 0xad, 0xc9, 0xbb, 0x49, 0x71, 0x49, 0xff, 0x15, 0x5e, 0xbd, 0x9a, 0xf1, 0xdd, 0x0d, 0x94, 0x62, \ - 0xa2, 0x53, 0xe8, 0xcc, 0xe6, 0x09, 0x46, 0x21, 0x97, 0xf1, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, \ - 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, \ - 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, \ - 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ + 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x72, 0x67, 0x75, 0x69, 0x64, 0x00, 0x00, 0x00, \ + 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, \ + 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, \ + 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, \ + 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, \ + 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xac, \ + 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ + 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ + 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ + 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, \ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0xf2, 0xca, 0x81, 0x1b, 0x13, 0xce, 0x99, 0x43, 0xd6, 0x4d, 0x1f, 0xa7, \ + 0x5a, 0xce, 0x5f, 0xf1, 0xab, 0x97, 0x0a, 0xb0, 0x7c, 0x06, 0x1f, 0x95, 0xf8, 0x65, 0xbe, 0x52, \ + 0x3b, 0xb0, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ + 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, \ + 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_request 742u +#define TYPE_MAP_CDR_SZ_DurableSupport_request 814u const dds_topic_descriptor_t DurableSupport_request_desc = { .m_size = sizeof (DurableSupport_request), .m_align = dds_alignof (DurableSupport_request), .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 4u, + .m_nkeys = 5u, .m_typename = "DurableSupport::request", .m_keys = DurableSupport_request_keys, - .m_nops = 7, + .m_nops = 8, .m_ops = DurableSupport_request_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request }, @@ -949,3 +958,4 @@ const dds_topic_descriptor_t DurableSupport_response_desc = .type_information = { .data = TYPE_INFO_CDR_DurableSupport_response, .sz = TYPE_INFO_CDR_SZ_DurableSupport_response }, .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_response, .sz = TYPE_MAP_CDR_SZ_DurableSupport_response } }; + From f02341700aca89e407c2e18a76900a29535f1c1f Mon Sep 17 00:00:00 2001 From: TheFixer Date: Thu, 4 Apr 2024 22:39:19 +0200 Subject: [PATCH 203/207] First attempt to add CM interface to the idl Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 13 ++++ src/durability/src/durablesupport.c | 77 +++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index 0e5aaf84da..fc42a5a26f 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -257,6 +257,19 @@ extern const dds_topic_descriptor_t DurableSupport_bead_desc; #define DurableSupport_bead_free(d,o) \ dds_sample_free ((d), &DurableSupport_bead_desc, (o)) +typedef struct DurableSupport_control +{ + DurableSupport_id_t id; +} DurableSupport_control; + +extern const dds_topic_descriptor_t DurableSupport_control_desc; + +#define DurableSupport_control__alloc() \ +((DurableSupport_control*) dds_alloc (sizeof (DurableSupport_control))); + +#define DurableSupport_control_free(d,o) \ +dds_sample_free ((d), &DurableSupport_control_desc, (o)) + typedef int64_t DurableSupport_duration_t; #define DurableSupport_duration_t__alloc() \ diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index 44413aaa4f..63a895fcf0 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -622,6 +622,83 @@ const dds_topic_descriptor_t DurableSupport_bead_desc = .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_bead, .sz = TYPE_MAP_CDR_SZ_DurableSupport_bead } }; +static const uint32_t DurableSupport_control_ops [] = +{ + /* control */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_control, id), 16u, + DDS_OP_RTS, + + /* key: id */ + DDS_OP_KOF | 1, 1u /* order: 0 */ +}; + +static const dds_key_descriptor_t DurableSupport_control_keys[1] = +{ + { "id", 5, 0 } +}; + +/* Type Information: + [MINIMAL cb0d133f4534082d16d026f85046] (#deps: 1) + - [MINIMAL 43f53a2be35b432cc735e9431a89] + [COMPLETE 59d57c820de779413f0c29ca47e1] (#deps: 1) + - [COMPLETE aca4d5a256d39713924333e85c6d] +*/ +#define TYPE_INFO_CDR_DurableSupport_control (const unsigned char []){ \ + 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0xcb, 0x0d, 0x13, 0x3f, 0x45, 0x34, 0x08, 0x2d, 0x16, 0xd0, 0x26, \ + 0xf8, 0x50, 0x46, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ + 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x59, 0xd5, 0x7c, \ + 0x82, 0x0d, 0xe7, 0x79, 0x41, 0x3f, 0x0c, 0x29, 0xca, 0x47, 0xe1, 0x00, 0x59, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ + 0x40, 0x00, 0x00, 0x00\ +} +#define TYPE_INFO_CDR_SZ_DurableSupport_control 148u +#define TYPE_MAP_CDR_DurableSupport_control (const unsigned char []){ \ + 0x76, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0xcb, 0x0d, 0x13, 0x3f, 0x45, 0x34, 0x08, \ + 0x2d, 0x16, 0xd0, 0x26, 0xf8, 0x50, 0x46, 0x00, 0x31, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0xf1, 0x43, 0xf5, \ + 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ + 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0xf2, 0x59, 0xd5, 0x7c, 0x82, 0x0d, 0xe7, 0x79, 0x41, 0x3f, 0x0c, 0x29, \ + 0xca, 0x47, 0xe1, 0x00, 0x55, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x00, \ + 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, \ + 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x3c, 0x00, 0x00, 0x00, \ + 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0xf2, 0x59, 0xd5, 0x7c, 0x82, 0x0d, 0xe7, 0x79, 0x41, 0x3f, 0x0c, 0x29, \ + 0xca, 0x47, 0xe1, 0xf1, 0xcb, 0x0d, 0x13, 0x3f, 0x45, 0x34, 0x08, 0x2d, 0x16, 0xd0, 0x26, 0xf8, \ + 0x50, 0x46, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ +} +#define TYPE_MAP_CDR_SZ_DurableSupport_control 384u +const dds_topic_descriptor_t DurableSupport_control_desc = +{ + .m_size = sizeof (DurableSupport_control), + .m_align = dds_alignof (DurableSupport_control), + .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 1u, + .m_typename = "DurableSupport::control", + .m_keys = DurableSupport_control_keys, + .m_nops = 3, + .m_ops = DurableSupport_control_ops, + .m_meta = "", + .type_information = { .data = TYPE_INFO_CDR_DurableSupport_control, .sz = TYPE_INFO_CDR_SZ_DurableSupport_control }, + .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_control, .sz = TYPE_MAP_CDR_SZ_DurableSupport_control } +}; + static const uint32_t DurableSupport_request_ops [] = { /* request */ From c2899a999fa48b933de685506b7fcbc02d352ec2 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 7 May 2024 23:03:29 +0200 Subject: [PATCH 204/207] Refactor delivery requests: a delivery request is now done for a reader iso for a set Signed-off-by: TheFixer --- .../include/dds/durability/durablesupport.h | 25 +- src/durability/src/dds_durability.c | 1100 +++++++++-------- src/durability/src/durablesupport.c | 355 +++--- 3 files changed, 810 insertions(+), 670 deletions(-) diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h index fc42a5a26f..0750233696 100644 --- a/src/durability/include/dds/durability/durablesupport.h +++ b/src/durability/include/dds/durability/durablesupport.h @@ -285,10 +285,15 @@ typedef uint64_t DurableSupport_delivery_id_t; #define DurableSupport_delivery_id_t__alloc() \ ((DurableSupport_delivery_id_t*) dds_alloc (sizeof (DurableSupport_delivery_id_t))); +typedef struct DurableSupport_request_key +{ + DurableSupport_id_t rguid; +} DurableSupport_request_key; + typedef struct DurableSupport_request { + struct DurableSupport_request_key key; DurableSupport_id_t client; - DurableSupport_id_t rguid; char * partition; char * tpname; char * type_id; @@ -305,9 +310,27 @@ dds_sample_free ((d), &DurableSupport_request_desc, (o)) #define DurableSupport_RESPONSETYPE_SET 1 #define DurableSupport_RESPONSETYPE_DATA 2 +#ifndef DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED +#define DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED +typedef struct dds_sequence_DurableSupport_id_t +{ + uint32_t _maximum; + uint32_t _length; + DurableSupport_id_t *_buffer; + bool _release; +} dds_sequence_DurableSupport_id_t; + +#define dds_sequence_DurableSupport_id_t__alloc() \ +((dds_sequence_DurableSupport_id_t*) dds_alloc (sizeof (dds_sequence_DurableSupport_id_t))); + +#define dds_sequence_DurableSupport_id_t_allocbuf(l) \ +((DurableSupport_id_t *) dds_alloc ((l) * sizeof (DurableSupport_id_t))) +#endif /* DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED */ + typedef struct DurableSupport_response_set_t { DurableSupport_delivery_id_t delivery_id; + dds_sequence_DurableSupport_id_t guids; char * partition; char * tpname; char * type_id; diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index 869d4f29e0..e21e7c0239 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -141,14 +141,40 @@ static int dc_blob_image (dds_sequence_octet blob, char *buf, size_t n) return -1; } -static int dc_stringify_request (char *buf, size_t n, const DurableSupport_request *request, bool valid_data) +static int dc_stringify_request_key (char *buf, size_t n, const DurableSupport_request_key *key) { size_t i = 0; int l; - char id_str[37]; char rguid_str[37]; + + if (buf == NULL) { + goto err; + } + if (key == NULL) { + buf[0] = '\0'; + return 0; + } + if ((l = snprintf(buf+i, n-i, "\"key\":{\"rguid\":\"%s\"}", dc_stringify_id(key->rguid, rguid_str))) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_request_key failed"); + return -1; +} + +static int dc_stringify_request (char *buf, size_t n, const DurableSupport_request *request, bool valid_data) +{ + size_t i = 0; + int l; int64_t sec; uint32_t msec; + char id_str[37]; if (buf == NULL) { goto err; @@ -157,33 +183,138 @@ static int dc_stringify_request (char *buf, size_t n, const DurableSupport_reque buf[0] = '\0'; return 0; } + buf[i++] = '{'; + if ((l = dc_stringify_request_key(buf+i, n-i, &request->key)) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + /* print non-key fields for valid data */ if (valid_data) { - /* also print non-key fields */ + if ((l = snprintf(buf+i, n-i, ", \"client\":\"%s\"", dc_stringify_id(request->client, id_str))) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } if (request->timeout == DDS_INFINITY) { - if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"rguid\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"timeout\":\"never\"}", dc_stringify_id(request->client, id_str), dc_stringify_id(request->rguid, rguid_str), request->partition, request->tpname, request->type_id)) < 0) { + if ((l = snprintf(buf+i, n-i, ", \"timeout\":\"never\"")) < 0) { goto err; } } else { sec = (int64_t)(request->timeout / DDS_NSECS_IN_SEC); msec = (uint32_t)((request->timeout % DDS_NSECS_IN_SEC) / DDS_NSECS_IN_MSEC); - if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"timeout\":%" PRId64 ".%03" PRIu32 "}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, request->type_id, sec, msec)) < 0) { + if ((l = snprintf(buf+i, n-i, ", \"timeout\":%" PRId64 ".%03" PRIu32, sec, msec)) < 0) { goto err; } } - } else { - /* only print key fields */ - if ((l = snprintf(buf+i, n-i, "{\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\"}", dc_stringify_id(request->client, id_str), request->partition, request->tpname, request->type_id)) < 0) { + i += (size_t)l; + if (i >= n) { + goto trunc; + } + } + if (i < n) { + buf[i++] = '}'; + } + if (i < n) { + buf[i] = '\0'; + } +trunc: + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_request failed"); + return -1; +} + +static int dc_stringify_response_set (char *buf, size_t n, const DurableSupport_response_set_t *response_set) +{ + size_t i = 0, j; + int l; + char id_str[37]; + bool first = true; + + if (buf == NULL) { + goto err; + } + if (response_set == NULL) { + buf[0] = '\0'; + return 0; + } + if ((l = snprintf(buf+i, n-i, "{\"delivery_id\":%" PRIu64 ", \"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"flags\":\"0x%04" PRIx32 "\", \"guids\":[", response_set->delivery_id, response_set->partition, response_set->tpname, response_set->type_id, response_set->flags)) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + for(j=0; j < response_set->guids._length; j++) { + if ((l = snprintf(buf+i, n-i, "%s\"%s\"", (first) ? "" : ",", dc_stringify_id(response_set->guids._buffer[j], id_str))) < 0) { goto err; } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + first = false; + } + if (i < n) { + buf[i++] = ']'; + } + if (i < n) { + buf[i++] = '}'; + } +trunc: + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_response_set failed"); + return -1; +} + +static int dc_stringify_response_data (char *buf, size_t n, const DurableSupport_response_data_t *response_data) +{ + size_t i = 0; + int l; + char blob_str[64]; + + if (buf == NULL) { + goto err; + } + if (response_data == NULL) { + buf[0] = '\0'; + return 0; + } + if (dc_blob_image(response_data->blob, blob_str, sizeof(blob_str)) < 0) { + goto err; + } + if ((l = snprintf(buf+i, n-i, "{\"blob\":\"%s\"", blob_str)) < 0) { + goto err; } i += (size_t)l; + if (i >= n) { + goto trunc; + } + if (i < n) { + buf[i++] = '}'; + } +trunc: if (i >= n) { /* truncated */ buf[n-1] = '\0'; } return (int)i; err: - DDS_ERROR("dc_stringify_request failed"); + DDS_ERROR("dc_stringify_response_data failed"); return -1; } @@ -192,7 +323,6 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp size_t i = 0; int l; char id_str[37]; - char blob_str[64]; if (buf == NULL) { goto err; @@ -201,7 +331,7 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp buf[0] = '\0'; return 0; } - if ((l = snprintf(buf+i, n-i, "{\"id\":\"%s\", \"type\":\"%s\", \"content\":{", dc_stringify_id(response->id, id_str), dc_responsetype_image(response->body._d))) < 0) { + if ((l = snprintf(buf+i, n-i, "{\"id\":\"%s\", \"type\":\"%s\", \"content\":", dc_stringify_id(response->id, id_str), dc_responsetype_image(response->body._d))) < 0) { goto err; } i += (size_t)l; @@ -210,16 +340,13 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp } switch (response->body._d) { case DurableSupport_RESPONSETYPE_SET : - if ((l = snprintf(buf+i, n-i, "\"delivery_id\":%" PRIu64 ",\"partition\":\"%s\", \"tpname\":\"%s\", \"type_id\":\"%s\", \"flags\":\"0x%04" PRIx32 "\"", response->body._u.set.delivery_id, response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.type_id, response->body._u.set.flags)) < 0) { + if ((l = dc_stringify_response_set(buf+i, n-i, &response->body._u.set)) < 0) { goto err; } i += (size_t)l; break; case DurableSupport_RESPONSETYPE_DATA : - if (dc_blob_image(response->body._u.data.blob, blob_str, sizeof(blob_str)) < 0) { - goto err; - } - if ((l = snprintf(buf+i, n-i, "\"blob\":\"%s\"", blob_str)) < 0) { + if ((l = dc_stringify_response_data(buf+i, n-i, &response->body._u.data)) < 0) { goto err; } i += (size_t)l; @@ -230,9 +357,6 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp if (i < n) { buf[i++] = '}'; } - if (i < n) { - buf[i++] = '}'; - } trunc: if (i >= n) { /* truncated */ @@ -240,7 +364,7 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp } return (int)i; err: - DDS_ERROR("dc_stringify_response failed, type: %" PRIu16 ", buf: %s\n", response->body._d, !buf ? "NULL" : buf); + DDS_ERROR("dc_stringify_response failed"); return -1; } @@ -269,146 +393,225 @@ static void cleanup_server (void *n) static const ddsrt_avl_ctreedef_t server_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct server_t, node), offsetof (struct server_t, id), cmp_server, 0); -struct proxy_set_reader_key_t { - dds_guid_t guid; /* guid of the reader */ +struct delivery_reader_key_t { + dds_guid_t rguid; +}; + +struct delivery_reader_t { + ddsrt_avl_node_t node; /* represents a node in the tree of delivery reader */ + struct delivery_reader_key_t key; /* key of a delivery reader */ }; -static int cmp_proxy_set_reader (const void *a, const void *b) +static int cmp_delivery_reader (const void *a, const void *b) { - struct proxy_set_reader_key_t *k1 = (struct proxy_set_reader_key_t *)a; - struct proxy_set_reader_key_t *k2 = (struct proxy_set_reader_key_t *)b; + struct delivery_reader_key_t *k1 = (struct delivery_reader_key_t *)a; + struct delivery_reader_key_t *k2 = (struct delivery_reader_key_t *)b; - return memcmp(k1->guid.v, k2->guid.v, 16); + return memcmp(k1->rguid.v, k2->rguid.v, 16); } -struct proxy_set_reader_t { - ddsrt_avl_node_t node; - struct proxy_set_reader_key_t key; - dds_entity_t reader; - struct dds_rhc *rhc; -}; - -static void cleanup_proxy_set_reader (void *n) +static void cleanup_delivery_reader (void *n) { - struct proxy_set_reader_t *proxy_set_reader = (struct proxy_set_reader_t *)n; - - ddsrt_free(proxy_set_reader); + struct delivery_reader_t *rd = (struct delivery_reader_t *)n; + ddsrt_free(rd); } -static const ddsrt_avl_ctreedef_t proxy_set_reader_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct proxy_set_reader_t, node), offsetof (struct proxy_set_reader_t, key), cmp_proxy_set_reader, 0); +static const ddsrt_avl_ctreedef_t delivery_readers_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct delivery_reader_t, node), offsetof (struct delivery_reader_t, key), cmp_delivery_reader, 0); -struct proxy_set_key_t { - char *partition; /* partition name */ - char *tpname; /* topic name */ - char *type_id; /* type id */ +struct delivery_request_key_t { + dds_guid_t guid; /* the guid of the reader that requested historical data */ }; -struct proxy_set_t { - ddsrt_avl_node_t node; /* represents a node in the tree of pending requests */ - struct proxy_set_key_t key; /* key of a proxy set */ - ddsrt_avl_ctree_t readers; /* the tree of readers and their rhc that have an interest in this proxy set */ - uint64_t seq; /* the sequence number of the outstanding request for this proxy set, 0 if no outstanding request */ +/* This represents a request for historical data from a client to a ds. + * Such delivery request will lead to the publication of a transient-local + * autodisposed request topic to a DS. A delivery requests is keyed by the + * guid of the reader guid that request the historical data. + * Delivery requests carry an expiration time. When the expiration time + * expires, the delivery request will be disposed and is not available + * any more for late joining ds's. + * + * LH: to check: is it really necessary to allow expiration of requests? + * If a request is transient-local, autodisposed then there is no need + * to expire a request. Only if you want to request data from a different + * ds we should dispose the current requests, create another request reader + * that connects to another ds, and republish the requests. */ + +struct delivery_request_t { + ddsrt_avl_node_t node; /* represents a node in the tree of delivery requests */ + ddsrt_fibheap_node_t fhnode; /* represents a node in the priority queue */ + struct delivery_request_key_t key; /* key of the delivery request; represents the reader that requested historical data */ + dds_entity_t reader; /* the reader entity that requested historical data */ + dds_time_t exp_time; /* delivery request expiration time */ }; -static int cmp_proxy_set (const void *a, const void *b) +static int dc_stringify_delivery_request_key (char *buf, size_t n, const struct delivery_request_key_t *key) { - struct proxy_set_key_t *k1 = (struct proxy_set_key_t *)a; - struct proxy_set_key_t *k2 = (struct proxy_set_key_t *)b; - int cmp; + size_t i = 0; + int l; + char guid_str[37]; - /* compare partition */ - if ((cmp = strcmp(k1->partition, k2->partition)) < 0) { - return -1; - } else if (cmp > 0) { - return 1; + if (buf == NULL) { + goto err; } - /* compare topic */ - if ((cmp = strcmp(k1->tpname, k2->tpname)) < 0) { - return -1; - } else if (cmp > 0) { - return 1; + if (key == NULL) { + buf[0] = '\0'; + return 0; } - /* compare type id */ - if ((cmp = strcmp(k1->type_id, k2->type_id)) < 0) { - return -1; - } else if (cmp > 0) { - return 1; + if ((l = snprintf(buf+i, n-i, "\"key\":{\"guid\":\"%s\"}", dc_stringify_id(key->guid.v, guid_str))) < 0) { + goto err; } - return 0; + i += (size_t)l; + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_delivery_request_key failed"); + return -1; } -static void cleanup_proxy_set (void *n) +static int dc_stringify_delivery_request (char *buf, size_t n, const struct delivery_request_t *dr) { - struct proxy_set_t *proxy_set = (struct proxy_set_t *)n; + size_t i = 0; + int l; + int64_t sec; + uint32_t msec; - ddsrt_avl_cfree(&proxy_set_reader_td, &proxy_set->readers, cleanup_proxy_set_reader); - ddsrt_free(proxy_set->key.partition); - ddsrt_free(proxy_set->key.tpname); - ddsrt_free(proxy_set->key.type_id); - ddsrt_free(proxy_set); + if (buf == NULL) { + goto err; + } + if (dr == NULL) { + buf[0] = '\0'; + return 0; + } + buf[i++] = '{'; + if ((l = dc_stringify_delivery_request_key(buf+i, n-i, &dr->key)) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + if ((l = snprintf(buf+i, n-i, ", \", reader\":%" PRId32, dr->reader)) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + if (dr->exp_time == DDS_INFINITY) { + if ((l = snprintf(buf+i, n-i, ", \"exp_time\":\"never\"")) < 0) { + goto err; + } + } else { + sec = (int64_t)(dr->exp_time / DDS_NSECS_IN_SEC); + msec = (uint32_t)((dr->exp_time % DDS_NSECS_IN_SEC) / DDS_NSECS_IN_MSEC); + if ((l = snprintf(buf+i, n-i, ", \"exp_time\":%" PRId64 ".%03" PRIu32, sec, msec)) < 0) { + goto err; + } + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + buf[i++]='}'; + if (i < n) { + buf[i] = '\0'; + } +trunc: + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_delivery_request failed"); + return -1; } -static const ddsrt_avl_ctreedef_t proxy_set_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct proxy_set_t, node), offsetof (struct proxy_set_t, key), cmp_proxy_set, 0); - -struct pending_request_key_t { - uint64_t seq; /* the sequence number of the request */ -}; - -/* This represents a request for data for a proxy set. - * Such request will lead to the publication of a transient-local - * autodisposed request topic to a DS. Requests are keyed by a monotonically - * increasing sequence number. - * Requests can expire when no answer is received within the specified - * expiration time. In this case the request will be disposed to prevent - * that a DS reacts to an already expired request. - * - * LH: to check: is it really necessary to allow expiration of requests? - * If a request is transient-local, autodisposed then there is no need - * to expire a request. Only if you want to request data from a different - * ds we should dispose the current requests, create another request reader - * that connects to another ds, and republish the requests. */ -struct pending_request_t { - ddsrt_avl_node_t node; /* represents a node in the tree of pending requests */ - ddsrt_fibheap_node_t fhnode; /* represents a node in the priority queue */ - struct pending_request_key_t key; /* sequence number of the request */ - struct proxy_set_t *proxy_set; /* the proxy set associated with the request */ - dds_time_t exp_time; /* request expiration time */ -}; - -static int cmp_pending_request (const void *a, const void *b) +static int cmp_delivery_request (const void *a, const void *b) { - struct pending_request_key_t *k1 = (struct pending_request_key_t *)a; - struct pending_request_key_t *k2 = (struct pending_request_key_t *)b; + struct delivery_request_key_t *k1 = (struct delivery_request_key_t *)a; + struct delivery_request_key_t *k2 = (struct delivery_request_key_t *)b; - return (k1->seq < k2->seq) ? -1 : ((k1->seq > k2->seq) ? 1 : 0); + return memcmp(k1->guid.v, k2->guid.v, 16); } -static void cleanup_pending_request (void *n) +static void cleanup_delivery_request (void *n) { - struct pending_request_t *pr = (struct pending_request_t *)n; - ddsrt_free(pr); + struct delivery_request_t *dr = (struct delivery_request_t *)n; + ddsrt_free(dr); } static int cmp_exp_time (const void *a, const void *b) { - struct pending_request_t *pr1 = (struct pending_request_t *)a; - struct pending_request_t *pr2 = (struct pending_request_t *)b; + struct delivery_request_t *dr1 = (struct delivery_request_t *)a; + struct delivery_request_t *dr2 = (struct delivery_request_t *)b; - return (pr1->exp_time < pr2->exp_time) ? -1 : ((pr1->exp_time > pr2->exp_time) ? 1 : 0); + return (dr1->exp_time < dr2->exp_time) ? -1 : ((dr1->exp_time > dr2->exp_time) ? 1 : 0); } -static const ddsrt_avl_ctreedef_t pending_requests_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct pending_request_t, node), offsetof (struct pending_request_t, key), cmp_pending_request, 0); +static const ddsrt_avl_ctreedef_t delivery_requests_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct delivery_request_t, node), offsetof (struct delivery_request_t, key), cmp_delivery_request, 0); -static const ddsrt_fibheap_def_t pending_requests_fd = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct pending_request_t, fhnode), cmp_exp_time); +static const ddsrt_fibheap_def_t delivery_requests_fd = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct delivery_request_t, fhnode), cmp_exp_time); struct delivery_ctx_t { ddsrt_avl_node_t node; - DurableSupport_id_t id; /* id of the ds; key of the delivery context */ + DurableSupport_id_t id; /* id of the ds that delivers the data; key of the delivery context */ uint64_t delivery_id; /* the id of the delivery by this ds; this is a monotonic increased sequence number */ - struct proxy_set_t *proxy_set; /* current proxy_set for which responses are being received, NULL if not known */ + ddsrt_avl_ctree_t readers; /* tree of reader guids for which this delivery is intended */ }; +static int dc_stringify_delivery_ctx (char *buf, size_t n, const struct delivery_ctx_t *delivery_ctx) +{ + size_t i = 0; + int l; + char id_str[37]; + struct delivery_reader_t *delivery_reader; + ddsrt_avl_citer_t it; + bool first = true; + + if (buf == NULL) { + goto err; + } + if (delivery_ctx == NULL) { + buf[0] = '\0'; + return 0; + } + if ((l = snprintf(buf+i, n-i, "{\"id\":\"%s\", \"readers\":[", dc_stringify_id(delivery_ctx->id, id_str))) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + for (delivery_reader = ddsrt_avl_citer_first (&delivery_readers_td, &delivery_ctx->readers, &it); delivery_reader; delivery_reader = ddsrt_avl_citer_next (&it)) { + if ((l = snprintf(buf+i, n-i, "%s%s", (first) ? "" : ",", dc_stringify_id(delivery_reader->key.rguid.v, id_str))) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + goto trunc; + } + first = false; + } + if ((l = snprintf(buf+i, n-i, "]}")) < 0) { + goto err; + } + i += (size_t)l; +trunc: + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_delivery_ctx failed"); + return -1; +} + static int delivery_ctx_cmp (const void *a, const void *b) { return memcmp(a, b, 16); @@ -416,7 +619,8 @@ static int delivery_ctx_cmp (const void *a, const void *b) static void cleanup_delivery_ctx (void *n) { - struct delivery_ctx *delivery_ctx = (struct delivery_ctx *)n; + struct delivery_ctx_t *delivery_ctx = (struct delivery_ctx_t *)n; + ddsrt_avl_cfree(&delivery_readers_td, &delivery_ctx->readers, cleanup_delivery_reader); ddsrt_free(delivery_ctx); } @@ -464,7 +668,7 @@ struct com_t { dds_entity_t rd_participant; /* participant reader */ dds_entity_t rd_subinfo; /* DCPSSubscription reader */ dds_entity_t rc_subinfo; /* DCPSSubscription read condition */ - dds_entity_t pending_request_guard; /* trigger expiration of pending request */ + dds_entity_t delivery_request_guard; /* trigger expiration of delivery request */ dds_listener_t *status_listener; /* listener on status topic */ dds_entity_t ws; }; @@ -500,13 +704,12 @@ struct dc_t { dds_listener_t *subinfo_listener; /* listener to detect remote containers */ dds_listener_t *quorum_listener; /* listener to check if a quorum is reached */ dds_listener_t *request_listener; /* listener to check if request reader is available */ - ddsrt_avl_ctree_t pending_requests; /* tree containing pending requests */ - ddsrt_fibheap_t pending_requests_fh; /* priority queue for pending requests, prioritized by expiry time */ - ddsrt_mutex_t pending_request_mutex; /* pending request queue mutex */ - ddsrt_cond_t pending_request_cond; /* pending request condition */ + ddsrt_avl_ctree_t delivery_requests; /* tree containing delivery requests */ + ddsrt_fibheap_t delivery_requests_fh; /* priority queue for delivery requests, prioritized by expiry time */ + ddsrt_mutex_t delivery_request_mutex; /* delivery request queue mutex */ + ddsrt_cond_t delivery_request_cond; /* delivery request condition */ dds_instance_handle_t selected_request_reader_ih; /* instance handle to matched request reader, DDS_HANDLE_NIL if not available */ ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on a ds that match with my request writer */ - ddsrt_avl_ctree_t proxy_sets; /* tree containing the sets for which data has to be provided by a ds */ uint32_t nr_of_matched_dc_requests; /* indicates the number of matched dc_request readers for the dc_request writer of this client */ struct delivery_ctx_t *delivery_ctx; /* reference to current delivery context, NULL if none */ ddsrt_avl_ctree_t delivery_ctxs; /* table of delivery contexts, keyed by ds id */ @@ -1073,13 +1276,13 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc subinfo read condition [%s]\n", dds_strretcode(-com->rc_subinfo)); goto err_rc_subinfo; } - /* create pending reuqest guard condition */ - if ((com->pending_request_guard = dds_create_guardcondition(com->participant)) < 0) { - DDS_ERROR("failed to create guard condition [%s]\n", dds_strretcode(-com->pending_request_guard)); - goto err_create_pending_request_guard_condition; + /* create delivery request guard condition */ + if ((com->delivery_request_guard = dds_create_guardcondition(com->participant)) < 0) { + DDS_ERROR("failed to create delivery guard condition [%s]\n", dds_strretcode(-com->delivery_request_guard)); + goto err_create_delivery_request_guard_condition; } - if ((ret = dds_set_guardcondition(com->pending_request_guard, false)) < 0) { - DDS_ERROR("failed to initialize guard condition [%s]\n", dds_strretcode(-ret)); + if ((ret = dds_set_guardcondition(com->delivery_request_guard, false)) < 0) { + DDS_ERROR("failed to initialize delivery guard condition [%s]\n", dds_strretcode(-ret)); goto err_set_guard_condition; } /* create waitset and attach read conditions */ @@ -1087,9 +1290,9 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, DDS_ERROR("failed to create dc waitset [%s]\n", dds_strretcode(-com->ws)); goto err_waitset; } - if ((ret = dds_waitset_attach (com->ws, com->pending_request_guard, com->pending_request_guard)) < 0) { - DDS_ERROR("failed to attach pending request guard condition to waitset [%s]\n", dds_strretcode(-ret)); - goto err_attach_pending_request_guard; + if ((ret = dds_waitset_attach (com->ws, com->delivery_request_guard, com->delivery_request_guard)) < 0) { + DDS_ERROR("failed to attach delivery request guard condition to waitset [%s]\n", dds_strretcode(-ret)); + goto err_attach_delivery_request_guard; } if ((ret = dds_waitset_attach (com->ws, com->rc_status, com->rd_status)) < 0) { DDS_ERROR("failed to attach dc status reader to waitset [%s]\n", dds_strretcode(-ret)); @@ -1123,12 +1326,12 @@ static struct com_t *dc_com_new (struct dc_t *dc, const dds_domainid_t domainid, err_attach_rd_response: dds_waitset_detach(com->ws, com->rc_status); err_attach_rd_status: - dds_waitset_detach(com->ws, com->pending_request_guard); -err_attach_pending_request_guard: + dds_waitset_detach(com->ws, com->delivery_request_guard); +err_attach_delivery_request_guard: dds_delete(com->ws); err_waitset: - dds_delete(com->pending_request_guard); -err_create_pending_request_guard_condition: + dds_delete(com->delivery_request_guard); +err_create_delivery_request_guard_condition: err_set_guard_condition: dds_delete(com->rc_subinfo); err_rc_subinfo: @@ -1201,7 +1404,7 @@ static void dc_com_free (struct com_t *com) #define MAX_TOPIC_NAME_SIZE 255 -static dds_return_t dc_com_request_write (struct com_t *com, const dds_guid_t rguid, const char *partition, const char *tpname, const char *type_id) +static dds_return_t dc_com_request_write (struct com_t *com, const dds_guid_t rguid) { /* note: we allow doing a request for volatile readers */ DurableSupport_request *request; @@ -1211,11 +1414,8 @@ static dds_return_t dc_com_request_write (struct com_t *com, const dds_guid_t rg size_t len; request = DurableSupport_request__alloc(); + memcpy(request->key.rguid, rguid.v, 16); memcpy(request->client, dc.cfg.id, 16); - memcpy(request->rguid, rguid.v, 16); - request->partition = ddsrt_strdup(partition); - request->tpname = ddsrt_strdup(tpname); - request->type_id = ddsrt_strdup(type_id); request->timeout = DDS_INFINITY; l = dc_stringify_request(str, sizeof(str), request, true); assert(l > 0); @@ -1304,42 +1504,6 @@ static int dc_process_status (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } -static struct proxy_set_t *dc_create_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, const char *type_id) -{ - struct proxy_set_t *proxy_set = NULL; - - assert(partition); - assert(tpname); - proxy_set = (struct proxy_set_t *)ddsrt_malloc(sizeof(struct proxy_set_t)); - proxy_set->key.partition = ddsrt_strdup(partition); - proxy_set->key.tpname = ddsrt_strdup(tpname); - proxy_set->key.type_id = ddsrt_strdup(type_id); - proxy_set->seq = 0; /* no pending request yet */ - ddsrt_avl_cinit(&proxy_set_reader_td, &proxy_set->readers); - ddsrt_avl_cinsert(&proxy_set_td, &dc->proxy_sets, proxy_set); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "proxy set '%s.%s<%s>' created\n", proxy_set->key.partition, proxy_set->key.tpname, proxy_set->key.type_id); - return proxy_set; -} - -static struct proxy_set_t *dc_get_proxy_set (struct dc_t *dc, const char *partition, const char *tpname, const char *type_id, bool autocreate) -{ - struct proxy_set_key_t key; - struct proxy_set_t *proxy_set; - - assert(partition); - assert(tpname); - key.partition = ddsrt_strdup(partition); - key.tpname = ddsrt_strdup(tpname); - key.type_id = ddsrt_strdup(type_id); - if (((proxy_set = ddsrt_avl_clookup (&proxy_set_td, &dc->proxy_sets, &key)) == NULL) && autocreate) { - proxy_set = dc_create_proxy_set(dc, partition, tpname, type_id); - } - ddsrt_free(key.partition); - ddsrt_free(key.tpname); - ddsrt_free(key.type_id); - return proxy_set; -} - /* lookup the delivery context for the ds identified by id * if not found and autocreate=true, then create the delivery context */ static struct delivery_ctx_t *dc_get_delivery_ctx (struct dc_t *dc, DurableSupport_id_t id, bool autocreate) @@ -1351,88 +1515,131 @@ static struct delivery_ctx_t *dc_get_delivery_ctx (struct dc_t *dc, DurableSuppo } else if (((delivery_ctx = ddsrt_avl_clookup (&delivery_ctx_td, &dc->delivery_ctxs, id)) == NULL) && autocreate) { delivery_ctx = ddsrt_malloc(sizeof(struct delivery_ctx_t)); memcpy(delivery_ctx->id,id,16); - delivery_ctx->delivery_id = 0; - delivery_ctx->proxy_set = NULL; + ddsrt_avl_cinit(&delivery_readers_td, &delivery_ctx->readers); ddsrt_avl_cinsert(&delivery_ctx_td, &dc->delivery_ctxs, delivery_ctx); } return delivery_ctx; } -/* Remove the current delivery */ -static void dc_remove_current_delivery (struct dc_t *dc) +/* Remove the delivery identified by id */ +static void dc_remove_delivery_ctx (struct dc_t *dc, DurableSupport_id_t id) { struct delivery_ctx_t *delivery_ctx; ddsrt_avl_dpath_t dpath; - if (dc->delivery_ctx) { - - if ((delivery_ctx = ddsrt_avl_clookup_dpath(&delivery_ctx_td, &dc->delivery_ctxs, dc->delivery_ctx->id, &dpath)) != NULL) { - assert(dc->delivery_ctx == delivery_ctx); - /* remove the delivery ctx from the tree */ - ddsrt_avl_cdelete_dpath(&delivery_ctx_td, &dc->delivery_ctxs, delivery_ctx, &dpath); - cleanup_delivery_ctx(delivery_ctx); + if ((delivery_ctx = ddsrt_avl_clookup_dpath(&delivery_ctx_td, &dc->delivery_ctxs, id, &dpath)) != NULL) { + ddsrt_avl_cdelete_dpath(&delivery_ctx_td, &dc->delivery_ctxs, delivery_ctx, &dpath); + if (delivery_ctx == dc->delivery_ctx) { + dc->delivery_ctx = NULL; } - /* reset the current delivery ctx */ - dc->delivery_ctx = NULL; + cleanup_delivery_ctx(delivery_ctx); } } -/* Abort the current delivery (i.e., dc->delivery_ctx) */ -static void dc_abort_current_delivery (struct dc_t *dc) +static struct delivery_reader_t *create_delivery_reader (dds_guid_t *guid) { - char id_str[37]; - - assert(dc->delivery_ctx); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "aborting delivery %" PRIu64 " from ds \"%s\"\n", - dc->delivery_ctx->delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str)); - /* todo: reschedule the proxy set */ + struct delivery_reader_t *delivery_reader; - /* remove the current delivery ctx */ - dc_remove_current_delivery(dc); + delivery_reader = ddsrt_malloc(sizeof(struct delivery_reader_t)); + memcpy(delivery_reader->key.rguid.v, guid->v, 16); + return delivery_reader; } -/* open the delivery context for the ds identified by id */ -static void dc_open_delivery (struct dc_t *dc, DurableSupport_response *response) +static struct delivery_reader_t *dc_get_reader_from_delivery_ctx (struct delivery_ctx_t *delivery_ctx, DurableSupport_id_t id, bool autocreate) { - char id_str[37]; - uint64_t delivery_id; + struct delivery_reader_t *delivery_reader; + ddsrt_avl_ipath_t path; + dds_guid_t key; - assert(response); - assert(response->body._u.set.flags & DC_FLAG_SET_BEGIN); - delivery_id = response->body._u.set.delivery_id; - /* now create the new delivery context */ - if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, true)) == NULL) { - DDS_ERROR("unable to create an delivery context for ds \"%s\" and delivery id %" PRIu64 "\n", dc_stringify_id(response->id, id_str), delivery_id); - abort(); - } - /* set the delivery_id and proxy set for this delivery context */ - dc->delivery_ctx->delivery_id = delivery_id; - if ((dc->delivery_ctx->proxy_set = dc_get_proxy_set(dc, response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.type_id, false)) == NULL) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "no proxy set for \"%s.%s<%s>\" found, ignore delivery\n", response->body._u.set.partition, response->body._u.set.tpname, response->body._u.set.type_id); - /* abort this delivery context */ - dc_abort_current_delivery(dc); - return; + memcpy(key.v, id, 16); + /* create a container for the topic */ + if (((delivery_reader = ddsrt_avl_clookup_ipath(&delivery_readers_td, &delivery_ctx->readers, &key, &path)) == NULL) && (autocreate)) { + delivery_reader = create_delivery_reader(&key); + ddsrt_avl_cinsert_ipath(&delivery_readers_td, &delivery_ctx->readers, delivery_reader, &path); } - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s<%s>\" opened\n", - delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str), dc->delivery_ctx->proxy_set->key.partition, dc->delivery_ctx->proxy_set->key.tpname, dc->delivery_ctx->proxy_set->key.type_id); + return delivery_reader; } /* close the current delivery context for the ds identified by id */ static void dc_close_delivery (struct dc_t *dc, DurableSupport_id_t id, DurableSupport_response_set_t *response_set) { char id_str[37]; + char str[1024]; - DC_UNUSED_ARG(response_set); - DC_UNUSED_ARG(id); assert(response_set); assert(response_set->flags & DC_FLAG_SET_END); - assert(memcmp(dc->delivery_ctx->id,id,16) == 0); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s\" closed\n", - dc->delivery_ctx->delivery_id, dc_stringify_id(dc->delivery_ctx->id, id_str), dc->delivery_ctx->proxy_set->key.partition, dc->delivery_ctx->proxy_set->key.tpname); - /* todo: mark the proxy set as complete */ + /* lookup the align context for this aligner */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, id, false)) == NULL) { + /* There exists a delivery context for the ds that produced the response. */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "unable to close delivery for ds \"%s\"\n", dc_stringify_id(id, id_str)); + return; + } + /* there exists a delivery context for the ds identified by id, close this delivery context */ + (void)dc_stringify_delivery_ctx(str, sizeof(str), dc->delivery_ctx); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "close delivery %s\n", str); + /* remove current delivery ctx */ + dc_remove_delivery_ctx(dc, id); +} + +/* Abort the current delivery context for the ds identified by id + * + * The current delivery is aborted when a new response set is received without the + * previous set being ended correctly. */ +static void dc_abort_delivery (struct dc_t *dc, DurableSupport_id_t id, DurableSupport_response_set_t *response_set) +{ + char id_str[37]; + char str[1024]; + DC_UNUSED_ARG(response_set); + /* lookup the align context for this aligner */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, id, false)) == NULL) { + /* There exists a delivery context for the ds that produced the response. */ + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "unable to abort delivery for unknown delivery from ds \"%s\"\n", dc_stringify_id(id, id_str)); + return; + } + assert(memcmp(dc->delivery_ctx->id,id,16) == 0); + (void)dc_stringify_delivery_ctx(str, sizeof(str), dc->delivery_ctx); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "abort delivery %s", str); /* remove current delivery ctx */ - dc_remove_current_delivery(dc); + dc_remove_delivery_ctx(dc, id); +} + +/* open the delivery context for the ds identified by id */ +static void dc_open_delivery (struct dc_t *dc, DurableSupport_id_t id, DurableSupport_response_set_t *response_set) +{ + char id_str[37]; + char str[1024]; + uint32_t i; + + assert(response_set); + assert(response_set->flags & DC_FLAG_SET_BEGIN); + /* lookup the align context for this aligner */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, id, false)) != NULL) { + /* There already exists a delivery context for the ds that produced the response. + * Implicitly abort it before opening a new one.*/ + dc_abort_delivery(dc, id, response_set); + } + /* Now create the new delivery context */ + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, id, true)) == NULL) { + DDS_ERROR("unable to create an delivery context for ds \"%s\"\n", dc_stringify_id(id, id_str)); + abort(); + } + assert(dc->delivery_ctx); + /* Collect the readers for which the response is intended in the delivery context. + * A response set usually carries a non-empty set of reader guids without duplicates. + * However, whenever a response set accidentally contains duplicate reader guids or + * no readers at all, we don't want this to cause any trouble, so we will handle + * these cases as well. + * In case a response contains duplicate reader guids, then we will administrate + * the reader only once. + * In case a response is published with an empty reader list, the readers in the + * delivery context will be empty. Any response data belonging to such set will simply + * not be delivered to any reader. */ + for (i=0; i < response_set->guids._length; i++) { + (void)dc_get_reader_from_delivery_ctx(dc->delivery_ctx, response_set->guids._buffer[i], true); + } + (void)dc_stringify_delivery_ctx(str, sizeof(str), dc->delivery_ctx); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "open delivery %s\n", str); } static void dc_process_set_response_begin(struct dc_t *dc, DurableSupport_response *response) @@ -1446,39 +1653,18 @@ static void dc_process_set_response_begin(struct dc_t *dc, DurableSupport_respon assert(memcmp(dc->delivery_ctx->id, response->id, 16) == 0); DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "current open delivery %" PRIu64 " has missed an end\n", dc->delivery_ctx->delivery_id); /* abort the currently open delivery */ - dc_abort_current_delivery(dc); + dc_abort_delivery(dc, dc->delivery_ctx->id, &response->body._u.set); } assert(dc->delivery_ctx == NULL); /* open the new delivery */ - dc_open_delivery(dc, response); + dc_open_delivery(dc, response->id, &response->body._u.set); } static void dc_process_set_response_end (struct dc_t *dc, DurableSupport_response *response) { - char id_str[37]; - - /* A response set end is received. Lookup the existing delivery context for this ds */ - if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, false)) != NULL) { - assert(memcmp(dc->delivery_ctx->id, response->id, 16) == 0); - /* verify that this response set end belongs the currently opened delivery. - * by comparing the delivery_id. If they do not match, then this response - * set end does not belong to the currently opened set. This means that - * delivery of the currently opened set has failed and needs to be aborted. */ - if (dc->delivery_ctx->delivery_id != response->body._u.set.delivery_id) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "current open delivery %" PRIu64 " does not belong to end delivery %" PRIu64 "\n", - dc->delivery_ctx->delivery_id, response->body._u.set.delivery_id); - /* abort the currently open delivery */ - dc_abort_current_delivery(dc); - } else { - /* the end belongs to the correct begin; we have received all data for the set - * and can properly close the delivery */ - dc_close_delivery(dc, response->id, &response->body._u.set); - } - } else { - /* an end was received without a begin; no need to abort */ - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "end delivery %" PRIu64 " from ds \"%s\" for set \"%s.%s\" received, but no corresponding open delivery found\n", - response->body._u.set.delivery_id, dc_stringify_id(response->id, id_str), response->body._u.set.partition, response->body._u.set.tpname); - } + assert(response); + assert(response->body._d == DurableSupport_RESPONSETYPE_SET); + dc_close_delivery(dc, response->id, &response->body._u.set); } static void dc_process_set_response_not_found(struct dc_t *dc, DurableSupport_response *response) @@ -1506,12 +1692,6 @@ static void dc_process_set_response (struct dc_t *dc, DurableSupport_response *r } } -#if 0 -int dc_deliver_blob () -{ -} -#endif - /* todo: this function is hared between ds and client */ static enum ddsi_serdata_kind get_serdata_kind (uint8_t kind) { @@ -1543,7 +1723,6 @@ static enum ddsi_serdata_kind get_serdata_kind (uint8_t kind) static void dc_process_data_response (struct dc_t *dc, DurableSupport_response *response) { - struct proxy_set_t *proxy_set = NULL; ddsrt_avl_citer_t it; const struct ddsi_sertype *sertype; struct ddsi_serdata *serdata; @@ -1556,24 +1735,22 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * dds_guid_t wguid; dds_return_t ret = DDS_RETCODE_OK; bool autodispose = 0; - struct proxy_set_reader_t *proxy_set_rd; char id_str[37]; + struct delivery_reader_t *delivery_reader; /* TODO: * A DS also has a response reader (by virtue of the CycloneDDS instance it runs). - * Currently, a DS therefore also receives responses that it sends itself. - * Because they is no proxy set the data is not injected, but I still like - * to have that a ds never receives responses. */ + * A DS therefore also receives responses that it sends to itself. + * Preferably we should prevent that the responses are end up at DSs. + * In any case, if responses do end up a DS, then the DS should ignore it. */ if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, false)) == NULL) { /* There is no delivery context for this data, which means that this node * did not request data for this set. If we do receive data, then we * can safely ignore it. */ return; } - if ((proxy_set = dc->delivery_ctx->proxy_set) == NULL) { - /* There is no proxy set for this data, which means that this node - * did not request data for this set. If we do receive data, then we - * can safely ignore it. */ + if (ddsrt_avl_cis_empty(&dc->delivery_ctx->readers)) { + /* There are no readers to deliver the data to. */ return; } /* A response_set begin has been received. Because data delivery is reliable, @@ -1595,16 +1772,30 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * serdata_size = response_size - serdata_offset; data_out.iov_len = serdata_size; data_out.iov_base = response->body._u.data.blob._buffer + serdata_offset; - /* now deliver the data to the local readers that have an interest in the data */ - for (proxy_set_rd = ddsrt_avl_citer_first (&proxy_set_reader_td, &proxy_set->readers, &it); proxy_set_rd; proxy_set_rd = ddsrt_avl_citer_next (&it)) { - dds_entity_t reader = proxy_set_rd->reader; + /* Now deliver the data to the local readers. */ + for (delivery_reader = ddsrt_avl_citer_first (&delivery_readers_td, &dc->delivery_ctx->readers, &it); delivery_reader; delivery_reader = ddsrt_avl_citer_next (&it)) { + /* take the guid and lookup the reader entity that requested the delivery */ + /* check if the reader still exists by lookup the entity */ + struct delivery_request_t *dr; + struct delivery_request_key_t key; + dds_entity_t reader; + + memcpy(key.guid.v, delivery_reader->key.rguid.v, 16); + if ((dr = ddsrt_avl_clookup(&delivery_requests_td, &dc->delivery_requests, &key)) == NULL) { + /* Unable to find a delivery request for this reader, so + * we cannot resolve the reader entity associated with the guid. + * Evidently, we cannot inject data into the rhc of a reader + * that we cannot resolve. */ + continue; + } + reader = dr->reader; /* in order to insert the data in the rhc of the reader we first * need to resolve the type of the reader */ if ((ret = dds_get_entity_sertype (reader, &sertype)) < 0) { - /* We failed to get the sertype. If it happens I do not consider - * this my problem, it is a problem in CycloneDDS. - * For now I silently ignore the data. After all, I cannot - * deliver the data to this reader! */ + /* We failed to get the sertype of the reader., so we cannot + * This could be because the reader does not exist any more, + * but frankly I don't about the reason. All that matters is + * that we cannot inject data into the rhc of this reader. */ continue; } /* get the serdata */ @@ -1619,7 +1810,7 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * serdata->timestamp.v = wt; memcpy(&serdata->writer_guid, &wguid, 16); if ((ret = dds_reader_store_historical_serdata(reader, wguid, autodispose, serdata)) != DDS_RETCODE_OK) { - DDS_ERROR("Failed to deliver historical data to reader \"%s\" [%s]\n", dc_stringify_id(proxy_set_rd->key.guid.v, id_str), dds_strretcode(ret)); + DDS_ERROR("Failed to deliver historical data to reader \"%s\" [%s]\n", dc_stringify_id(dr->key.guid.v, id_str), dds_strretcode(ret)); goto err_store_historical_serdata; } ddsi_serdata_to_ser_unref(serdata, &data_out); @@ -1680,120 +1871,78 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) #undef MAX_SAMPLES } -/* add the reader tree of readers for this proxy set */ -static void dc_register_reader_to_proxy_set (struct dc_t *dc, struct proxy_set_t *proxy_set, dds_guid_t guid, dds_entity_t reader, struct dds_rhc *rhc) +static void dc_delete_delivery_request (struct dc_t *dc, dds_guid_t rguid) { - struct proxy_set_reader_t *proxy_set_rd; - struct proxy_set_reader_key_t key; - char id_str[37]; + struct delivery_request_t *dr; + struct delivery_request_key_t key; + ddsrt_avl_dpath_t dpath; + char dr_str[512]; - key.guid = guid; - if ((proxy_set_rd = ddsrt_avl_clookup (&proxy_set_reader_td, &proxy_set->readers, &key)) == NULL) { - proxy_set_rd = (struct proxy_set_reader_t *)ddsrt_malloc(sizeof(struct proxy_set_reader_t)); - proxy_set_rd->key.guid = guid; - proxy_set_rd->reader = reader; - proxy_set_rd->rhc = rhc; - ddsrt_avl_cinsert(&proxy_set_reader_td, &proxy_set->readers, proxy_set_rd); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "reader \"%s\" added to proxy set '%s.%s'\n", dc_stringify_id(guid.v, id_str), proxy_set->key.partition, proxy_set->key.tpname); + memcpy(key.guid.v, rguid.v, 16); + if ((dr = ddsrt_avl_clookup_dpath (&delivery_requests_td, &dc->delivery_requests, &key, &dpath)) != NULL) { + ddsrt_avl_cdelete_dpath(&delivery_requests_td, &dc->delivery_requests, dr, &dpath); + (void)dc_stringify_delivery_request(dr_str, sizeof(dr_str), dr); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delete delivery request %s\n", dr_str); + cleanup_delivery_request(dr); } - assert(proxy_set_rd->rhc == rhc); } -static void dc_create_proxy_sets_for_reader (struct dc_t *dc, dds_entity_t reader, struct dds_rhc *rhc) +static struct delivery_request_t *dc_insert_delivery_request (struct dc_t *dc, dds_entity_t reader, dds_guid_t rguid) { - dds_entity_t topic; + struct delivery_request_t *dr; + struct delivery_request_key_t key; + ddsrt_avl_ipath_t ipath; + char dr_str[512]; dds_return_t rc; - char tpname[MAX_TOPIC_NAME_SIZE]; - dds_qos_t *rqos; - uint32_t plen, i; - char **partitions; - struct proxy_set_t *proxy_set = NULL; - dds_guid_t rguid; - char id_str[37]; - dds_typeinfo_t *typeinfo; - ddsi_typeid_t *tid = NULL; - struct ddsi_typeid_str tidstr = { 0 }; - if ((rc = dds_get_typeinfo(reader, &typeinfo)) != DDS_RETCODE_OK) { - DDS_ERROR("Unable to retrieve typeinfo [%s]\n", dds_strretcode(-rc)); - goto err_get_typeinfo; - } - if ((tid = ddsi_typeinfo_typeid(typeinfo, DDSI_TYPEID_KIND_COMPLETE)) == NULL) { - DDS_ERROR("Unable to retrieve typeid [%s]\n", dds_strretcode(-rc)); - goto err_typeid; + memcpy(key.guid.v, rguid.v, 16); + if ((dr = ddsrt_avl_clookup_ipath (&delivery_requests_td, &dc->delivery_requests, &key, &ipath)) == NULL) { + dr = ddsrt_malloc(sizeof(struct delivery_request_t)); + memcpy(dr->key.guid.v, rguid.v, 16); + dr->reader = reader; + dr->exp_time = DDS_NEVER; + (void)dc_stringify_delivery_request(dr_str, sizeof(dr_str), dr); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "create delivery request %s\n", dr_str); + ddsrt_avl_cinsert_ipath(&delivery_requests_td, &dc->delivery_requests, dr, &ipath); + ddsrt_fibheap_insert(&delivery_requests_fd, &dc->delivery_requests_fh, dr); + if (dr == ddsrt_fibheap_min(&delivery_requests_fd, &dc->delivery_requests_fh)) { + /* delivery request added to the front, trigger guard condition */ + if ((rc = dds_set_guardcondition(dc->com->delivery_request_guard, true)) < 0) { + DDS_ERROR("failed to set delivery request guard to true [%s]", dds_strretcode(rc)); + } + } } - (void)ddsi_make_typeid_str(&tidstr, tid); - /* get reader guid */ + return dr; +} + +static void dc_send_request_for_reader (struct dc_t *dc, dds_entity_t reader, struct dds_rhc *rhc) +{ + dds_return_t rc; + dds_guid_t rguid; + + (void)rhc; if ((rc = dds_get_guid(reader, &rguid)) < DDS_RETCODE_OK) { - DDS_ERROR("Unable to retrieve the guid of the reader [%s]\n", dds_strretcode(-rc)); + DDS_ERROR("Unable to retrieve the guid of the reader [%s]", dds_strretcode(-rc)); goto err_get_guid; } - (void)dc_stringify_id(rguid.v, id_str); - /* get topic name */ - if ((topic = dds_get_topic(reader)) < 0) { - DDS_ERROR("Unable to get topic from reader [%s]\n", dds_strretcode(-topic)); - goto err_get_topic; - } - if ((rc = dds_get_name(topic, tpname, sizeof(tpname))) < 0) { - DDS_ERROR("Failed to get topic name [%s]\n", dds_strretcode(-rc)); - goto err_get_name; - } else if (rc > MAX_TOPIC_NAME_SIZE) { - DDS_ERROR("Name for topic '%s...', name too long\n", tpname); - goto err_get_name_size; - } - /* get partitions of the reader */ - if ((rqos = dds_create_qos()) == NULL) { - DDS_ERROR("Failed to allocate reader qos\n"); - goto err_alloc_rqos; - } - if ((rc = dds_get_qos(reader, rqos)) < 0) { - DDS_ERROR("Failed to get topic qos [%s]\n", dds_strretcode(rc)); - goto err_get_qos; - } - if (!dds_qget_partition(rqos, &plen, &partitions)) { - DDS_ERROR("failed to get partitions from qos\n"); - goto err_qget_partition; - } - /* for each partition create a proxy set if it does not exist yet - * and request data for the proxy set (if not done so already) */ - for (i=0; i < plen; i++) { - proxy_set = dc_get_proxy_set(dc, partitions[i], tpname, tidstr.str, true); - assert(proxy_set); - /* Add the reader and rhc to this proxy set. - * We do this BEFORE we send the request, so that we are sure - * that when we receive the response (possibly immediately after - * sending the request) the reader and rhc are present */ - dc_register_reader_to_proxy_set(dc, proxy_set, rguid, reader, rhc); - /* send a request for this proxy set */ - if ((rc = dc_com_request_write(dc->com, rguid, proxy_set->key.partition, proxy_set->key.tpname, proxy_set->key.type_id)) != DDS_RETCODE_OK) { - DDS_ERROR("Failed to publish dc_request for proxy set %s.%s\n", proxy_set->key.partition, proxy_set->key.tpname); - /* We failed to request data for this proxy set. - * We could do several things now, e.g., 1) try again until we succeed, - * 2) notify the application that no historical data could be retrieved, - * or 3) commit suicide because we cannot guarantee eventual consistency. - * For now, I choose for the latter. After all, it is expected that sending - * a request should never fails. */ - abort(); - } + /* Administrate the outstanding request. + * This is used a.o. to correlate reader guids to actual readers. */ + dc_insert_delivery_request(dc, reader, rguid); + /* Publish the quest */ + if ((rc = dc_com_request_write(dc->com, rguid)) != DDS_RETCODE_OK) { + DDS_ERROR("Failed to publish dc_request [%s]", dds_strretcode(-rc)); + /* We failed to request data for this proxy set. + * We could do several things now, e.g., 1) try again until we succeed, + * 2) notify the application that no historical data could be retrieved, + * or 3) commit suicide because we cannot guarantee eventual consistency. + * For now, I choose for the latter. After all, it is expected that sending + * a request should never fail. */ + dc_delete_delivery_request(dc, rguid); + abort(); } - dc_free_partitions(plen, partitions); - dds_delete_qos(rqos); - dds_free_typeinfo(typeinfo); - ddsrt_free(tid); return; -err_qget_partition: -err_get_qos: - dds_delete_qos(rqos); -err_alloc_rqos: -err_get_name_size: -err_get_name: -err_get_topic: err_get_guid: - ddsrt_free(tid); -err_typeid: - dds_free_typeinfo(typeinfo); -err_get_typeinfo: return; } @@ -1828,30 +1977,28 @@ static void default_durable_writer_matched_cb (dds_entity_t writer, dds_publicat return; } -/* dispose the request for the proxy set */ -static void dc_dispose_reader_request (struct dc_t *dc, struct proxy_set_t *proxy_set) +/* dispose the delivery request */ +static void dc_dispose_delivery_request (struct dc_t *dc, struct delivery_request_t *dr) { dds_return_t rc; dds_instance_handle_t ih; DurableSupport_request request; + char id_str[37]; - /* create a dummy request containing the key fields to retrieve the instance handle */ - memcpy(request.client, dc->cfg.id, 16); - request.partition = ddsrt_strdup(proxy_set->key.partition); - request.tpname = ddsrt_strdup(proxy_set->key.tpname); + DC_UNUSED_ARG(dr); + /* create a dummy request containing the reader guid that */ + memcpy(request.key.rguid, dr->key.guid.v, 16); if ((ih = dds_lookup_instance(dc->com->wr_request, &request)) == DDS_HANDLE_NIL) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dc_request for proxy set %s.%s not found, unable to dispose\n", request.partition, request.tpname); - goto err_dispose_reader_request; + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "no delivery request for reader \"%s\" found, unable to dispose\n", dc_stringify_id(request.key.rguid, id_str)); + goto err_dispose_delivery_request; } if ((rc = dc_com_request_dispose(dc->com, ih)) != DDS_RETCODE_OK) { - DDS_ERROR("failed to dispose dc_request for proxy set %s.%s [%s]\n", request.partition, request.tpname, dds_strretcode(-rc)); - goto err_dispose_reader_request; + DDS_ERROR("failed to dispose delivery request for reader \"%s\" [%s]\n", dc_stringify_id(request.key.rguid, id_str), dds_strretcode(-rc)); + goto err_dispose_delivery_request; } /* LH: todo: use dc_stringify_request, but only print the keys */ - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dispose dc_request {\"client\":\"%s\", \"partition\":\"%s\", \"tpname\":\"%s\"}\n", dc->cfg.id_str, request.partition, request.tpname); -err_dispose_reader_request: - ddsrt_free(request.partition); - ddsrt_free(request.tpname); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dispose delivery request for reader \"%s\"\n", dc_stringify_id(request.key.rguid, id_str)); +err_dispose_delivery_request: return; } @@ -1913,7 +2060,7 @@ static void default_request_writer_matched_cb (dds_entity_t writer, dds_publicat if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { /* A dc_request reader on a data container has matched with the dc_request writer. * From now on it is allowed to publish requests. - * In case there are any pending requests, we can sent them now */ + * In case there are any delivery requests, we can sent them now */ dc_add_matched_request_reader(dc, ep, ih); } dds_builtintopic_free_endpoint(ep); @@ -1923,40 +2070,42 @@ static void default_request_writer_matched_cb (dds_entity_t writer, dds_publicat } } -/* handle expired pending request and determine the next timeout */ -static void dc_process_pending_request_guard (struct dc_t *dc, dds_time_t *timeout) +/* handle expired delivery request and determine the next timeout */ +static void dc_process_delivery_request_guard (struct dc_t *dc, dds_time_t *timeout) { dds_return_t ret; - struct pending_request_t *pr; + struct delivery_request_t *dr; dds_time_t now = dds_time(); + char dr_str[256]; - ddsrt_mutex_lock(&dc->pending_request_mutex); + ddsrt_mutex_lock(&dc->delivery_request_mutex); do { - pr = ddsrt_fibheap_min(&pending_requests_fd, &dc->pending_requests_fh); - if ((pr == NULL) || (now < pr->exp_time)) { - /* there is no pending request, or the first pending request is not yet expired */ + dr = ddsrt_fibheap_min(&delivery_requests_fd, &dc->delivery_requests_fh); + if ((dr == NULL) || (now < dr->exp_time)) { + /* there is no delivery request, or the first delivery request has not yet expired */ break; } - /* The head is expired. Remove the pending request from the priority queue + /* The head is expired. Remove the delivery request from the priority queue * and dispose it to prevent that a DS reacts to an expired request */ - if ((pr = ddsrt_fibheap_extract_min(&pending_requests_fd, &dc->pending_requests_fh)) != NULL) { - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "process pending request %" PRIu64 "\n", pr->key.seq); - dc_dispose_reader_request(dc, pr->proxy_set); - cleanup_pending_request(pr); + if ((dr = ddsrt_fibheap_extract_min(&delivery_requests_fd, &dc->delivery_requests_fh)) != NULL) { + (void)dc_stringify_delivery_request(dr_str, sizeof(dr_str), dr); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "process delivery request \"%s\"\n", dr_str); + dc_dispose_delivery_request(dc, dr); + dc_delete_delivery_request(dc, dr->key.guid); } } while (true); /* recalculate the remaining timeout */ - *timeout = (pr == NULL) ? DDS_NEVER : pr->exp_time; - if ((ret = dds_set_guardcondition(dc->com->pending_request_guard, false)) < 0) { - DDS_ERROR("failed to set pending request guard to false [%s]", dds_strretcode(ret)); + *timeout = (dr == NULL) ? DDS_NEVER : dr->exp_time; + if ((ret = dds_set_guardcondition(dc->com->delivery_request_guard, false)) < 0) { + DDS_ERROR("failed to set delivery request guard to false [%s]", dds_strretcode(ret)); } if (*timeout != DDS_NEVER) { dds_duration_t tnext = *timeout - now; int64_t sec = (int64_t)(tnext / DDS_NSECS_IN_SEC); uint32_t usec = (uint32_t)((tnext % DDS_NSECS_IN_SEC) / DDS_NSECS_IN_USEC); - DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "next pending request timeout at %" PRId64 ".%06" PRIu32 "s\n", sec, usec); + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "next delivery request timeout at %" PRId64 ".%06" PRIu32 "s\n", sec, usec); } - ddsrt_mutex_unlock(&dc->pending_request_mutex); + ddsrt_mutex_unlock(&dc->delivery_request_mutex); } static uint32_t recv_handler (void *a) @@ -1978,13 +2127,13 @@ static uint32_t recv_handler (void *a) dc_process_status(dc->com->rd_status, dc); } else if (wsresults[j] == dc->com->rd_response) { dc_process_response(dc->com->rd_response, dc); - } else if (wsresults[j] == dc->com->pending_request_guard) { - dc_process_pending_request_guard(dc, &timeout); + } else if (wsresults[j] == dc->com->delivery_request_guard) { + dc_process_delivery_request_guard(dc, &timeout); } } } else { /* timeout */ - dc_process_pending_request_guard(dc, &timeout); + dc_process_delivery_request_guard(dc, &timeout); } } DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "stop durable client thread\n"); @@ -2038,7 +2187,7 @@ static dds_return_t activate_request_listener (struct dc_t *dc) if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { /* A dc_request reader on a DS has matched with the dc_request writer. * From now on it is allowed to publish requests. - * In case there are any pending requests, we can sent them now */ + * In case there are any delivery requests, we can sent them now */ dc_add_matched_request_reader(dc, ep, rd_ihs[i]); } dds_builtintopic_free_endpoint(ep); @@ -2081,11 +2230,10 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom ddsrt_avl_cinit(&delivery_ctx_td, &dc.delivery_ctxs); ddsrt_avl_cinit(&server_td, &dc.servers); ddsrt_avl_cinit(&matched_request_readers_td, &dc.matched_request_readers); - ddsrt_avl_cinit(&pending_requests_td, &dc.pending_requests); - ddsrt_fibheap_init(&pending_requests_fd, &dc.pending_requests_fh); - ddsrt_avl_cinit(&proxy_set_td, &dc.proxy_sets); - ddsrt_mutex_init(&dc.pending_request_mutex); - ddsrt_cond_init(&dc.pending_request_cond); + ddsrt_avl_cinit(&delivery_requests_td, &dc.delivery_requests); + ddsrt_fibheap_init(&delivery_requests_fd, &dc.delivery_requests_fh); + ddsrt_mutex_init(&dc.delivery_request_mutex); + ddsrt_cond_init(&dc.delivery_request_cond); /* create the quorum listener */ if ((dc.quorum_listener = dds_create_listener(&dc)) == NULL) { DDS_ERROR("failed to create quorum listener\n"); @@ -2117,10 +2265,9 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom err_create_request_listener: dds_delete_listener(dc.quorum_listener); err_create_quorum_listener: - ddsrt_cond_destroy(&dc.pending_request_cond); - ddsrt_mutex_destroy(&dc.pending_request_mutex); - ddsrt_avl_cfree(&proxy_set_td, &dc.proxy_sets, cleanup_proxy_set); - ddsrt_avl_cfree(&pending_requests_td, &dc.pending_requests, cleanup_pending_request); + ddsrt_cond_destroy(&dc.delivery_request_cond); + ddsrt_mutex_destroy(&dc.delivery_request_mutex); + ddsrt_avl_cfree(&delivery_requests_td, &dc.delivery_requests, cleanup_delivery_request); ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); ddsrt_free(dc.cfg.ident); @@ -2159,11 +2306,10 @@ dds_return_t dds_durability_fini (void) dds_delete_listener(dc.quorum_listener); dc_com_free(dc.com); ddsrt_avl_cfree(&delivery_ctx_td, &dc.delivery_ctxs, cleanup_delivery_ctx); - ddsrt_cond_destroy(&dc.pending_request_cond); - ddsrt_mutex_destroy(&dc.pending_request_mutex); - ddsrt_avl_cfree(&proxy_set_td, &dc.proxy_sets, cleanup_proxy_set); + ddsrt_cond_destroy(&dc.delivery_request_cond); + ddsrt_mutex_destroy(&dc.delivery_request_mutex); ddsrt_avl_cfree(&matched_request_readers_td, &dc.matched_request_readers, cleanup_matched_request_reader); - ddsrt_avl_cfree(&pending_requests_td, &dc.pending_requests, cleanup_pending_request); + ddsrt_avl_cfree(&delivery_requests_td, &dc.delivery_requests, cleanup_delivery_request); ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); ddsrt_free(dc.cfg.ident); } @@ -2175,76 +2321,6 @@ bool dds_durability_is_terminating (void) return (ddsrt_atomic_ld32(&dc.termflag) > 0); } -dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc) -{ - dds_durability_kind_t dkind; - dds_qos_t *qos, *parqos; - dds_return_t rc = DDS_RETCODE_ERROR; - - /* check if the reader is a durable reader from a "real" user application, - * if so, send a request to obtain historical data */ - assert(reader); - qos = dds_create_qos(); - if ((rc = dds_get_qos(reader, qos)) < 0) { - DDS_ERROR("failed to get qos from reader [%s]\n", dds_strretcode(rc)); - goto err_get_qos; - } - if (!dds_qget_durability(qos, &dkind)) { - DDS_ERROR("failed to retrieve durability qos\n"); - goto err_qget_durability; - } - if ((dkind == DDS_DURABILITY_TRANSIENT) || (dkind == DDS_DURABILITY_PERSISTENT)) { - dds_entity_t par; - void *userdata; - size_t size = 0; - - /* Creation of a durable reader must only lead to the publication - * of a dc_request when the reader is a "real" application reader. - * If the reader belongs to a participant that carries user data - * containing the IDENT, then the reader is a data container. - * We don't need to generate dc_requests for data containers */ - if ((par = dds_get_participant(reader)) < 0) { - DDS_ERROR("Unable to retrieve the participant of the reader [%s]\n", dds_strretcode(rc)); - goto err_get_participant; - } - if ((parqos = dds_create_qos()) == NULL) { - DDS_ERROR("Failed to allocate qos\n"); - goto err_alloc_parqos; - } - if ((rc = dds_get_qos(par, parqos)) < 0) { - DDS_ERROR("Failed to get topic qos [%s]", dds_strretcode(rc)); - goto err_get_parqos; - } - if (!dds_qget_userdata(parqos, &userdata, &size)) { - DDS_ERROR("Unable to retrieve the participant's user data for reader\n"); - goto err_qget_userdata; - } - if ((size != strlen(dc.cfg.ident)) || (userdata == NULL) || (strcmp(userdata, dc.cfg.ident) != 0)) { - /* the user data of the participant for this durable reader does - * not contain the ident, so the endpoint is not from a remote DS. - * We can now publish a dc_request for this durable reader. The - * dc_request is published as a transient-local topic. This means - * that a late joining DS will receive the DS as long as the request - * is not yet disposed. */ - dc_create_proxy_sets_for_reader(&dc, reader, rhc); - } - dds_free(userdata); - dds_delete_qos(parqos); - } - dds_delete_qos(qos); - return rc; - -err_qget_userdata: -err_get_parqos: - dds_delete_qos(parqos); -err_alloc_parqos: -err_get_participant: -err_qget_durability: -err_get_qos: - dds_delete_qos(qos); - return rc; -} - /* Returns TRUE if the entity is an application entity, false otherwise */ static bool is_application_entity (struct dc_t *dc, dds_entity_t entity) { @@ -2293,6 +2369,44 @@ static bool is_application_entity (struct dc_t *dc, dds_entity_t entity) return true; } +dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc) +{ + dds_durability_kind_t dkind; + dds_qos_t *qos; + dds_return_t rc = DDS_RETCODE_ERROR; + + /* check if the reader is a durable reader from a "real" user application, + * if so, send a request to obtain historical data */ + assert(reader); + qos = dds_create_qos(); + if ((rc = dds_get_qos(reader, qos)) < 0) { + DDS_ERROR("failed to get qos from reader [%s]\n", dds_strretcode(rc)); + goto err_get_qos; + } + if (!dds_qget_durability(qos, &dkind)) { + DDS_ERROR("failed to retrieve durability qos\n"); + goto err_qget_durability; + } + if ((dkind == DDS_DURABILITY_TRANSIENT) || (dkind == DDS_DURABILITY_PERSISTENT)) { + if (is_application_entity(&dc, reader)) { + /* the user data of the participant for this durable reader does + * not contain the ident, so the endpoint is not from a remote DS. + * We can now publish a dc_request for this durable reader. The + * dc_request is published as a transient-local topic. This means + * that a late joining DS will receive the DS as long as the request + * is not yet disposed. */ + dc_send_request_for_reader(&dc, reader, rhc); + } + } + dds_delete_qos(qos); + return rc; + +err_qget_durability: +err_get_qos: + dds_delete_qos(qos); + return rc; +} + /* check if the writer is a durable application writer, and if so, we need to keep track of the quorum */ dds_return_t dds_durability_new_local_writer (dds_entity_t writer) { diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c index 63a895fcf0..6325ac0e3f 100644 --- a/src/durability/src/durablesupport.c +++ b/src/durability/src/durablesupport.c @@ -703,100 +703,94 @@ static const uint32_t DurableSupport_request_ops [] = { /* request */ DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, client), 16u, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, rguid), 16u, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, partition), - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, tpname), - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_request, type_id), + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_EXT, offsetof (DurableSupport_request, key), (3u << 16u) + 9u /* request_key */, + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, client), 16u, DDS_OP_ADR | DDS_OP_TYPE_8BY | DDS_OP_FLAG_SGN, offsetof (DurableSupport_request, timeout), DDS_OP_RTS, - - /* key: client */ - DDS_OP_KOF | 1, 1u /* order: 0 */, - - /* key: rguid */ - DDS_OP_KOF | 1, 4u /* order: 1 */, - /* key: partition */ - DDS_OP_KOF | 1, 7u /* order: 2 */, - - /* key: tpname */ - DDS_OP_KOF | 1, 9u /* order: 3 */, + /* request_key */ + DDS_OP_DLC, + DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_key, rguid), 16u, + DDS_OP_RTS, - /* key: type_id */ - DDS_OP_KOF | 1, 11u /* order: 4 */ + /* key: key.rguid */ + DDS_OP_KOF | 2, 1u /* order: 0 */, 1u /* order: 0 */ }; -static const dds_key_descriptor_t DurableSupport_request_keys[5] = +static const dds_key_descriptor_t DurableSupport_request_keys[1] = { - { "client", 16, 0 }, - { "rguid", 18, 1 }, - { "partition", 20, 2 }, - { "tpname", 22, 3 }, - { "type_id", 24, 4 } + { "key.rguid", 15, 0 } }; /* Type Information: - [MINIMAL ab970ab07c061f95f865be523bb0] (#deps: 2) + [MINIMAL 8b9080d97a1a0c3c5aa3da72955b] (#deps: 3) + - [MINIMAL a3976212b3d863bdaaf29cf722d7] - [MINIMAL 43f53a2be35b432cc735e9431a89] - [MINIMAL 84ce9c3d894c1483f859c00d5927] - [COMPLETE ca811b13ce9943d64d1fa75ace5f] (#deps: 2) + [COMPLETE ffa88f3ac66a3c1ea9fb2cc3dcec] (#deps: 3) + - [COMPLETE c4f510554fa6a62cae1437b6364b] - [COMPLETE aca4d5a256d39713924333e85c6d] - [COMPLETE 023df3bd21223779cd1936cef928] */ #define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ - 0xc0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0xab, 0x97, 0x0a, 0xb0, 0x7c, 0x06, 0x1f, 0x95, 0xf8, 0x65, 0xbe, \ - 0x52, 0x3b, 0xb0, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, \ - 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x58, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0xca, 0x81, 0x1b, 0x13, 0xce, 0x99, 0x43, 0xd6, 0x4d, 0x1f, 0xa7, \ - 0x5a, 0xce, 0x5f, 0x00, 0x06, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ + 0xf0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x8b, 0x90, 0x80, 0xd9, 0x7a, 0x1a, 0x0c, 0x3c, 0x5a, 0xa3, 0xda, \ + 0x72, 0x95, 0x5b, 0x00, 0x75, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xa3, 0x97, 0x62, 0x12, 0xb3, 0xd8, 0x63, \ + 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, 0x00, 0x35, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ + 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, \ + 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ + 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xff, 0xa8, 0x8f, \ + 0x3a, 0xc6, 0x6a, 0x3c, 0x1e, 0xa9, 0xfb, 0x2c, 0xc3, 0xdc, 0xec, 0x00, 0xb2, 0x00, 0x00, 0x00, \ + 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ + 0xf2, 0xc4, 0xf5, 0x10, 0x55, 0x4f, 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, 0x4b, 0x00, \ + 0x60, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ 0x39, 0x00, 0x00, 0x00\ } -#define TYPE_INFO_CDR_SZ_DurableSupport_request 196u +#define TYPE_INFO_CDR_SZ_DurableSupport_request 244u #define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ - 0x0b, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf1, 0xab, 0x97, 0x0a, 0xb0, 0x7c, 0x06, 0x1f, \ - 0x95, 0xf8, 0x65, 0xbe, 0x52, 0x3b, 0xb0, 0x00, 0xa1, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ + 0x1f, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf1, 0x8b, 0x90, 0x80, 0xd9, 0x7a, 0x1a, 0x0c, \ + 0x3c, 0x5a, 0xa3, 0xda, 0x72, 0x95, 0x5b, 0x00, 0x71, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0xa3, 0x97, 0x62, 0x12, 0xb3, \ + 0xd8, 0x63, 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, 0x3c, 0x6e, 0x0b, 0x8a, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xaf, 0xc4, 0x1d, 0xc3, 0x00, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ - 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ - 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, \ - 0x19, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ - 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ - 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ - 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, \ - 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, \ - 0xb5, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf2, 0xca, 0x81, 0x1b, 0x13, 0xce, 0x99, 0x43, \ - 0xd6, 0x4d, 0x1f, 0xa7, 0x5a, 0xce, 0x5f, 0x00, 0x02, 0x01, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, \ - 0x65, 0x73, 0x74, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, \ - 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x72, 0x67, 0x75, 0x69, 0x64, 0x00, 0x00, 0x00, \ - 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, \ - 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, \ - 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, \ + 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ + 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0xa3, 0x97, \ + 0x62, 0x12, 0xb3, 0xd8, 0x63, 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, 0x31, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, \ + 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xaf, 0xc4, 0x1d, \ + 0xc3, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ + 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x84, \ + 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x00, 0x00, \ + 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x05, 0x00, 0xd1, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf2, 0xff, 0xa8, 0x8f, \ + 0x3a, 0xc6, 0x6a, 0x3c, 0x1e, 0xa9, 0xfb, 0x2c, 0xc3, 0xdc, 0xec, 0x00, 0xae, 0x00, 0x00, 0x00, \ + 0xf2, 0x51, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x00, 0x82, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xc4, 0xf5, 0x10, 0x55, 0x4f, \ + 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, 0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, \ 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, \ - 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ + 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xc4, \ + 0xf5, 0x10, 0x55, 0x4f, 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, 0x4b, 0x00, 0x00, 0x00, \ + 0x5c, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x1c, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, \ + 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x72, 0x67, 0x75, 0x69, 0x64, 0x00, 0x00, 0x00, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ @@ -805,21 +799,23 @@ static const dds_key_descriptor_t DurableSupport_request_keys[5] = 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0xf2, 0xca, 0x81, 0x1b, 0x13, 0xce, 0x99, 0x43, 0xd6, 0x4d, 0x1f, 0xa7, \ - 0x5a, 0xce, 0x5f, 0xf1, 0xab, 0x97, 0x0a, 0xb0, 0x7c, 0x06, 0x1f, 0x95, 0xf8, 0x65, 0xbe, 0x52, \ - 0x3b, 0xb0, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ - 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, \ - 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0xf2, 0xff, 0xa8, 0x8f, 0x3a, 0xc6, 0x6a, 0x3c, 0x1e, 0xa9, 0xfb, 0x2c, \ + 0xc3, 0xdc, 0xec, 0xf1, 0x8b, 0x90, 0x80, 0xd9, 0x7a, 0x1a, 0x0c, 0x3c, 0x5a, 0xa3, 0xda, 0x72, \ + 0x95, 0x5b, 0xf2, 0xc4, 0xf5, 0x10, 0x55, 0x4f, 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, \ + 0x4b, 0xf1, 0xa3, 0x97, 0x62, 0x12, 0xb3, 0xd8, 0x63, 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, \ + 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, \ + 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, \ + 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, \ + 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_request 814u +#define TYPE_MAP_CDR_SZ_DurableSupport_request 892u const dds_topic_descriptor_t DurableSupport_request_desc = { .m_size = sizeof (DurableSupport_request), .m_align = dds_alignof (DurableSupport_request), - .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 5u, + .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, + .m_nkeys = 1u, .m_typename = "DurableSupport::request", .m_keys = DurableSupport_request_keys, .m_nops = 8, @@ -841,12 +837,15 @@ static const uint32_t DurableSupport_response_ops [] = DDS_OP_DLC, DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_response_content, _d), 2u, (12u << 16u) + 4u, DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 9 /* response_set_t */, 1, offsetof (DurableSupport_response_content, _u.set), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 17 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, + DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 25 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, DDS_OP_RTS, /* response_set_t */ DDS_OP_DLC, DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_response_set_t, delivery_id), + DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_ARR, offsetof (DurableSupport_response_set_t, guids), sizeof (DurableSupport_id_t), (8u << 16u) + 4u, + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, 0u, 16u, + DDS_OP_RTS, DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, partition), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, tpname), DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, type_id), @@ -864,135 +863,140 @@ static const uint32_t DurableSupport_response_ops [] = static const dds_key_descriptor_t DurableSupport_response_keys[1] = { - { "id", 38, 0 } + { "id", 46, 0 } }; /* Type Information: - [MINIMAL 7172db81541171f4d3215f317121] (#deps: 6) + [MINIMAL afe8255284083dabd3ddf2d54e74] (#deps: 6) - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL adf1bdbb30b9d6975e377ee51fa4] + - [MINIMAL 98ce0230d0ff9c4c40cabb2d52c3] - [MINIMAL 80455e796dd3437163cb532089da] - - [MINIMAL 19656e10c4f1e4cd8e04106c5b0f] + - [MINIMAL e78d987aa9597510bc0942813b1e] - [MINIMAL d8398b259af5a04792e296996c27] - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE eb98abe5dd8d7bfb5b2507da617d] (#deps: 6) + [COMPLETE 96afe9e7626475acdc5483ed4445] (#deps: 6) - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE 5c1f20e6410aad78dfe023066879] + - [COMPLETE 32546bec8365219448f85d5a510d] - [COMPLETE eec1bad6badde73f40ef199fedcc] - - [COMPLETE e4730a78f541604cc1a1a037ef05] + - [COMPLETE 5af9ae0c63928c6db71150e723db] - [COMPLETE 7b005a124ff7bda9c39eb4003556] - [COMPLETE 008875599776c39ce0c1fe897846] */ #define TYPE_INFO_CDR_DurableSupport_response (const unsigned char []){ \ 0x80, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x71, 0x72, 0xdb, 0x81, 0x54, 0x11, 0x71, 0xf4, 0xd3, 0x21, 0x5f, \ - 0x31, 0x71, 0x21, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf1, 0xaf, 0xe8, 0x25, 0x52, 0x84, 0x08, 0x3d, 0xab, 0xd3, 0xdd, 0xf2, \ + 0xd5, 0x4e, 0x74, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, 0xb9, 0xd6, 0x97, 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0x00, \ + 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, 0xff, 0x9c, 0x4c, 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0x00, \ 0x7c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x19, 0x65, 0x6e, 0x10, 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, 0x5b, 0x0f, 0x00, \ - 0x77, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ + 0xf1, 0xe7, 0x8d, 0x98, 0x7a, 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, 0x3b, 0x1e, 0x00, \ + 0x9b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0xeb, 0x98, 0xab, 0xe5, 0xdd, 0x8d, 0x7b, 0xfb, 0x5b, 0x25, 0x07, \ - 0xda, 0x61, 0x7d, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ + 0x14, 0x00, 0x00, 0x00, 0xf2, 0x96, 0xaf, 0xe9, 0xe7, 0x62, 0x64, 0x75, 0xac, 0xdc, 0x54, 0x83, \ + 0xed, 0x44, 0x45, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, 0x78, 0xdf, 0xe0, 0x23, 0x06, 0x68, 0x79, 0x00, \ + 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, 0x65, 0x21, 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0x00, \ 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, \ 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, 0x60, 0x4c, 0xc1, 0xa1, 0xa0, 0x37, 0xef, 0x05, 0x00, \ - 0xd8, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, \ + 0xf2, 0x5a, 0xf9, 0xae, 0x0c, 0x63, 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, 0xe7, 0x23, 0xdb, 0x00, \ + 0x04, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, \ 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ 0x57, 0x00, 0x00, 0x00\ } #define TYPE_INFO_CDR_SZ_DurableSupport_response 388u #define TYPE_MAP_CDR_DurableSupport_response (const unsigned char []){ \ - 0x30, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0x71, 0x72, 0xdb, 0x81, 0x54, 0x11, 0x71, \ - 0xf4, 0xd3, 0x21, 0x5f, 0x31, 0x71, 0x21, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ + 0x54, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0xaf, 0xe8, 0x25, 0x52, 0x84, 0x08, 0x3d, \ + 0xab, 0xd3, 0xdd, 0xf2, 0xd5, 0x4e, 0x74, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, \ - 0xb9, 0xd6, 0x97, 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ + 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, \ + 0xff, 0x9c, 0x4c, 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, \ - 0xb9, 0xd6, 0x97, 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, \ + 0xff, 0x9c, 0x4c, 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ 0x54, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x19, 0x65, 0x6e, 0x10, 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, 0x5b, \ - 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ + 0x01, 0x00, 0xf1, 0xe7, 0x8d, 0x98, 0x7a, 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, 0x3b, \ + 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ 0x02, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x19, 0x65, 0x6e, 0x10, \ - 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, 0x5b, 0x0f, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0xe7, 0x8d, 0x98, 0x7a, \ + 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, 0x3b, 0x1e, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, \ + 0x06, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x7c, 0x4b, 0x99, \ - 0xfe, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x7e, 0x75, 0xc0, 0xed, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x94, 0x75, 0x7c, 0xae, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, \ - 0x58, 0x68, 0xd6, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ - 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, \ - 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \ - 0xee, 0x26, 0x90, 0x8b, 0x9b, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0xeb, 0x98, 0xab, \ - 0xe5, 0xdd, 0x8d, 0x7b, 0xfb, 0x5b, 0x25, 0x07, 0xda, 0x61, 0x7d, 0x00, 0x83, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, 0x78, 0xdf, \ - 0xe0, 0x23, 0x06, 0x68, 0x79, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x64, 0x79, \ - 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, \ - 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x10, 0x02, 0x00, 0x00, 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, 0x78, 0xdf, 0xe0, 0x23, \ - 0x06, 0x68, 0x79, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, \ - 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, \ - 0x11, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, \ - 0xcc, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, 0x60, 0x4c, 0xc1, \ - 0xa1, 0xa0, 0x37, 0xef, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, \ - 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, \ - 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, \ - 0x60, 0x4c, 0xc1, 0xa1, 0xa0, 0x37, 0xef, 0x05, 0xd4, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ - 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0xfe, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, \ + 0x01, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, \ + 0x1a, 0x89, 0x0d, 0x36, 0x32, 0x3f, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, 0x0b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, \ + 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, \ + 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, \ + 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, \ + 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0xc7, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0xf2, 0x96, 0xaf, 0xe9, 0xe7, 0x62, 0x64, 0x75, 0xac, 0xdc, 0x54, 0x83, 0xed, 0x44, 0x45, 0x00, \ + 0x83, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, \ + 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ + 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, \ + 0x65, 0x21, 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ + 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ + 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ + 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, 0x65, 0x21, \ + 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, \ + 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, \ - 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x7b, \ - 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ + 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, \ + 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ + 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ + 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5a, 0xf9, 0xae, 0x0c, 0x63, \ + 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, 0xe7, 0x23, 0xdb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, \ + 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, \ + 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, \ + 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ + 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, \ + 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x5a, 0xf9, \ + 0xae, 0x0c, 0x63, 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, 0xe7, 0x23, 0xdb, 0x00, 0x01, 0x00, 0x00, \ + 0xf2, 0x51, 0x0a, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, \ + 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, \ + 0xcc, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, \ + 0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, \ + 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ + 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x67, 0x75, 0x69, 0x64, \ + 0x73, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ + 0x15, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, \ - 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, \ + 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, \ 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1005,22 +1009,22 @@ static const dds_key_descriptor_t DurableSupport_response_keys[1] = 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, \ 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, \ - 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0xeb, 0x98, 0xab, \ - 0xe5, 0xdd, 0x8d, 0x7b, 0xfb, 0x5b, 0x25, 0x07, 0xda, 0x61, 0x7d, 0xf1, 0x71, 0x72, 0xdb, 0x81, \ - 0x54, 0x11, 0x71, 0xf4, 0xd3, 0x21, 0x5f, 0x31, 0x71, 0x21, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ + 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0x96, 0xaf, 0xe9, \ + 0xe7, 0x62, 0x64, 0x75, 0xac, 0xdc, 0x54, 0x83, 0xed, 0x44, 0x45, 0xf1, 0xaf, 0xe8, 0x25, 0x52, \ + 0x84, 0x08, 0x3d, 0xab, 0xd3, 0xdd, 0xf2, 0xd5, 0x4e, 0x74, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, \ - 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x5c, 0x1f, 0x20, 0xe6, 0x41, 0x0a, 0xad, \ - 0x78, 0xdf, 0xe0, 0x23, 0x06, 0x68, 0x79, 0xf1, 0xad, 0xf1, 0xbd, 0xbb, 0x30, 0xb9, 0xd6, 0x97, \ - 0x5e, 0x37, 0x7e, 0xe5, 0x1f, 0xa4, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ + 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, 0x65, 0x21, \ + 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, 0xff, 0x9c, 0x4c, \ + 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, \ - 0x53, 0x20, 0x89, 0xda, 0xf2, 0xe4, 0x73, 0x0a, 0x78, 0xf5, 0x41, 0x60, 0x4c, 0xc1, 0xa1, 0xa0, \ - 0x37, 0xef, 0x05, 0xf1, 0x19, 0x65, 0x6e, 0x10, 0xc4, 0xf1, 0xe4, 0xcd, 0x8e, 0x04, 0x10, 0x6c, \ - 0x5b, 0x0f, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, \ + 0x53, 0x20, 0x89, 0xda, 0xf2, 0x5a, 0xf9, 0xae, 0x0c, 0x63, 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, \ + 0xe7, 0x23, 0xdb, 0xf1, 0xe7, 0x8d, 0x98, 0x7a, 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, \ + 0x3b, 0x1e, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, \ 0x56, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, \ 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0xf1, \ 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ } -#define TYPE_MAP_CDR_SZ_DurableSupport_response 1710u +#define TYPE_MAP_CDR_SZ_DurableSupport_response 1790u const dds_topic_descriptor_t DurableSupport_response_desc = { .m_size = sizeof (DurableSupport_response), @@ -1029,10 +1033,9 @@ const dds_topic_descriptor_t DurableSupport_response_desc = .m_nkeys = 1u, .m_typename = "DurableSupport::response", .m_keys = DurableSupport_response_keys, - .m_nops = 19, + .m_nops = 22, .m_ops = DurableSupport_response_ops, .m_meta = "", .type_information = { .data = TYPE_INFO_CDR_DurableSupport_response, .sz = TYPE_INFO_CDR_SZ_DurableSupport_response }, .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_response, .sz = TYPE_MAP_CDR_SZ_DurableSupport_response } }; - From c4e259ebe5dd22d6e540e2c2ce9770144630605f Mon Sep 17 00:00:00 2001 From: Michel van den Hoek Date: Wed, 15 May 2024 17:33:48 +0200 Subject: [PATCH 205/207] Resolve build-time circular dependencies by making the durability client a plugin. Signed-off-by: Michel van den Hoek --- src/CMakeLists.txt | 7 +- src/core/CMakeLists.txt | 7 +- src/core/ddsc/CMakeLists.txt | 1 + src/core/ddsc/src/dds__types.h | 2 + src/core/ddsc/src/dds_domain.c | 5 + src/core/ddsc/src/dds_durability.c | 70 ++ src/core/ddsc/src/dds_participant.c | 11 +- src/core/ddsc/src/dds_reader.c | 7 +- src/core/ddsc/src/dds_write.c | 12 +- src/core/ddsc/src/dds_writer.c | 12 +- src/core/xtests/symbol_export/CMakeLists.txt | 3 +- src/durability/CMakeLists.txt | 45 +- .../include/dds/durability/dds_durability.h | 42 - .../dds/durability/dds_durability_private.h | 27 + .../dds/durability/dds_durability_public.h | 41 + .../include/dds/durability/durablesupport.h | 390 ------ src/durability/src/dds_durability.c | 51 +- src/durability/src/durablesupport.c | 1041 ----------------- src/durability/src/durablesupport.idl | 71 ++ 19 files changed, 292 insertions(+), 1553 deletions(-) create mode 100644 src/core/ddsc/src/dds_durability.c delete mode 100644 src/durability/include/dds/durability/dds_durability.h create mode 100644 src/durability/include/dds/durability/dds_durability_private.h create mode 100644 src/durability/include/dds/durability/dds_durability_public.h delete mode 100644 src/durability/include/dds/durability/durablesupport.h delete mode 100644 src/durability/src/durablesupport.c create mode 100644 src/durability/src/durablesupport.idl diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3c74cc5d1b..5e4ac045f6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -119,10 +119,6 @@ if(ENABLE_ICEORYX) endif() endif() -if(ENABLE_DURABILITY) - message(STATUS "Building with Durable support") -endif() - if(BUILD_TESTING) add_subdirectory(ucunit) endif() @@ -135,7 +131,8 @@ add_subdirectory(security) if(ENABLE_ICEORYX) add_subdirectory(psmx_iox) endif() +add_subdirectory(core) if(ENABLE_DURABILITY) + message(STATUS "Building with Durable support") add_subdirectory(durability) endif() -add_subdirectory(core) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index d9ead68db4..31ef861efc 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -58,10 +58,6 @@ if(ENABLE_SECURITY) $>) endif() -if(ENABLE_DURABILITY) - target_link_libraries(ddsc PRIVATE "$") -endif() - include(cdr/CMakeLists.txt) include(ddsi/CMakeLists.txt) include(ddsc/CMakeLists.txt) @@ -93,7 +89,8 @@ target_compile_definitions( $>) target_include_directories( ddsc PUBLIC - $>) + $> + $) # SOVERSION should increase on incompatible ABI change set_target_properties(ddsc PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) diff --git a/src/core/ddsc/CMakeLists.txt b/src/core/ddsc/CMakeLists.txt index 9ac86c23e3..d39d24e9f7 100644 --- a/src/core/ddsc/CMakeLists.txt +++ b/src/core/ddsc/CMakeLists.txt @@ -46,6 +46,7 @@ prepend(srcs_ddsc "${CMAKE_CURRENT_LIST_DIR}/src/" dds_loaned_sample.c dds_heap_loan.c dds_psmx.c + dds_durability.c ) if(ENABLE_TYPELIB) diff --git a/src/core/ddsc/src/dds__types.h b/src/core/ddsc/src/dds__types.h index 9048246181..f42d7d53a5 100644 --- a/src/core/ddsc/src/dds__types.h +++ b/src/core/ddsc/src/dds__types.h @@ -24,6 +24,7 @@ #include "dds/ddsrt/avl.h" #include "dds/ddsi/ddsi_builtin_topic_if.h" #include "dds/ddsc/dds_psmx.h" +#include "dds/durability/dds_durability_public.h" #include "dds__handles.h" #include "dds__loaned_sample.h" @@ -306,6 +307,7 @@ typedef struct dds_domain { struct dds_serdatapool *serpool; struct dds_psmx_set psmx_instances; + dds_durability_t dc; // Durability client } dds_domain; typedef struct dds_subscriber { diff --git a/src/core/ddsc/src/dds_domain.c b/src/core/ddsc/src/dds_domain.c index d2612033d7..f0a7eec123 100644 --- a/src/core/ddsc/src/dds_domain.c +++ b/src/core/ddsc/src/dds_domain.c @@ -128,6 +128,9 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i if ((ret = dds_pubsub_message_exchange_init (&domain->gv, domain)) != DDS_RETCODE_OK) goto fail_psmx_init; + if ((ret = dds_durability_load (&domain->dc, &domain->gv)) != DDS_RETCODE_OK) + goto fail_durability_init; + struct ddsi_psmx_instance_locators psmx_locators; psmx_locators.length = domain->psmx_instances.length; psmx_locators.instances = dds_alloc (domain->psmx_instances.length * sizeof (*psmx_locators.instances)); @@ -207,6 +210,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i domain->psmx_instances.instances[i]->ops.deinit(domain->psmx_instances.instances[i]); domain->psmx_instances.instances[i] = NULL; } +fail_durability_init: fail_psmx_init: fail_ddsi_config: if (domain->cfgst) @@ -337,6 +341,7 @@ static dds_return_t dds_domain_free (dds_entity *vdomain) ddsi_fini (&domain->gv); + dds_durability_unload (&domain->dc); (void) dds_pubsub_message_exchange_fini (domain); dds_serdatapool_free (domain->serpool); diff --git a/src/core/ddsc/src/dds_durability.c b/src/core/ddsc/src/dds_durability.c new file mode 100644 index 0000000000..4b1f9a877e --- /dev/null +++ b/src/core/ddsc/src/dds_durability.c @@ -0,0 +1,70 @@ +/* + * Copyright(c) 2006 to 2019 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ + +#include "dds/durability/dds_durability_public.h" +#include "dds/ddsi/ddsi_log.h" +#include + +void dds_durability_fini (dds_durability_t* dc) +{ +#ifdef DDS_HAS_DURABILITY + /* + In the cleanup phase, the durability client's participant will always be the last remaining participant on the domain. + Thus if the domain is implicit, it will trigger deletion of the domain, which in turn unloads the durability plugin. + + So if the participant were to be deleted from inside the plugin, it would result in a fatal error when + the program tries to return (as it unwinds the call stack) to the plugin function that called `dds_delete()` on the participant. + + Therefore, in order to safely delete the participant of the durability client, + its handle needs to be smuggled out so it can be deleted by a function that isn't part of the plugin itself. + */ + assert(dc->_dds_durability_fini); + dds_entity_t pp = dc->_dds_durability_fini(); + if ( pp != 0 ) { + dds_delete(pp); + } +#endif +} + +dds_return_t dds_durability_load (dds_durability_t* dc, const struct ddsi_domaingv* gv) +{ + memset(dc, 0x0, sizeof(dds_durability_t)); +#ifdef DDS_HAS_DURABILITY + dds_return_t (*creator)(dds_durability_t* dc); + ddsrt_dynlib_t handle = NULL; + dds_return_t ret; + if ((ret = ddsrt_dlopen("durability", true, &handle)) != DDS_RETCODE_OK) { + char buf[256]; + ddsrt_dlerror(buf, sizeof(buf)); + GVERROR("dlopen: %s\n", buf); + return ret; + } + if ((ret = ddsrt_dlsym(handle, "dds_durability_creator", (void**)&creator)) != DDS_RETCODE_OK) { + char buf[256]; + ddsrt_dlerror(buf, sizeof(buf)); + GVERROR("dlsym: %s\n", buf); + (void)ddsrt_dlclose(handle); + return ret; + } + creator(dc); + dc->lib_handle = handle; +#endif + return DDS_RETCODE_OK; +} + +void dds_durability_unload (dds_durability_t* dc) +{ +#ifdef DDS_HAS_DURABILITY + assert(dc->lib_handle); + (void)ddsrt_dlclose(dc->lib_handle); +#endif +} diff --git a/src/core/ddsc/src/dds_participant.c b/src/core/ddsc/src/dds_participant.c index c3e6d1cc5a..0351a3c46d 100644 --- a/src/core/ddsc/src/dds_participant.c +++ b/src/core/ddsc/src/dds_participant.c @@ -28,10 +28,6 @@ #include "dds__builtin.h" #include "dds__qos.h" -#ifdef DDS_HAS_DURABILITY -#include "dds/durability/dds_durability.h" -#endif - DECL_ENTITY_LOCK_UNLOCK (dds_participant) #define DDS_PARTICIPANT_STATUS_MASK (0u) @@ -63,9 +59,7 @@ static dds_return_t dds_participant_delete (dds_entity *e) DDS_CERROR (&e->m_domain->gv.logconfig, "dds_participant_delete: internal error %"PRId32"\n", ret); ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); -#ifdef DDS_HAS_DURABILITY - (void)dds_durability_fini(); -#endif + dds_durability_fini(&e->m_domain->dc); /* todo It seems incorrect that dds_participant_delete() * always returns DDS_RETCODE_OK, even if an error has @@ -189,8 +183,9 @@ static dds_entity_t create_participant_flags_guid (const dds_domainid_t domain, dds_entity_unpin_and_drop_ref (&dds_global.m_entity); #ifdef DDS_HAS_DURABILITY + assert(dom->dc.dds_durability_init); if (ret > 0) { - (void)dds_durability_init (domain, &dom->gv); + (void)dom->dc.dds_durability_init (domain, &dom->gv); } #endif diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index b0a57d6d7a..be27126a57 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -52,10 +52,6 @@ #include "dds/ddsi/ddsi_tkmap.h" #endif -#ifdef DDS_HAS_DURABILITY -#include "dds/durability/dds_durability.h" -#endif - DECL_ENTITY_LOCK_UNLOCK (dds_reader) #define DDS_READER_STATUS_MASK \ @@ -803,8 +799,9 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe dds_subscriber_unlock (sub); #ifdef DDS_HAS_DURABILITY + assert(rd->m_entity.m_domain->dc.dds_durability_new_local_reader); if (dkind >= DDS_DURABILITY_TRANSIENT) { - dds_durability_new_local_reader(reader, rhc); + rd->m_entity.m_domain->dc.dds_durability_new_local_reader(reader, rhc); } #endif diff --git a/src/core/ddsc/src/dds_write.c b/src/core/ddsc/src/dds_write.c index a9761aaf1f..6de46f5a51 100644 --- a/src/core/ddsc/src/dds_write.c +++ b/src/core/ddsc/src/dds_write.c @@ -31,10 +31,6 @@ #include "dds__loaned_sample.h" #include "dds__psmx.h" -#ifdef DDS_HAS_DURABILITY -#include "dds/durability/dds_durability.h" -#endif - struct ddsi_serdata_plain { struct ddsi_serdata p; }; struct ddsi_serdata_any { struct ddsi_serdata a; }; @@ -47,6 +43,11 @@ dds_return_t dds_write (dds_entity_t writer, const void *data) return DDS_RETCODE_BAD_PARAMETER; #ifdef DDS_HAS_DURABILITY + if ((ret = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK) + return ret; + dds_durability_t* dc = &wr->m_entity.m_domain->dc; + dds_writer_unlock (wr); + /* determine if the quorum of durable services for the writer is fulfilled. * * LH: This implementation may be suboptimal, because determining whether the @@ -54,7 +55,8 @@ dds_return_t dds_write (dds_entity_t writer, const void *data) * within the same writer lock. So after the quorum has been established, * and before the data is published, the quorum could have been dropped again. * Chances for this to happen are slim, but still ... */ - if ((ret = dds_durability_wait_for_quorum(writer)) != DDS_RETCODE_OK) { + assert(dc->dds_durability_wait_for_quorum); + if ((ret = dc->dds_durability_wait_for_quorum(writer)) != DDS_RETCODE_OK) { return ret; } #endif diff --git a/src/core/ddsc/src/dds_writer.c b/src/core/ddsc/src/dds_writer.c index fcc2c9bf1b..db2afe5e89 100644 --- a/src/core/ddsc/src/dds_writer.c +++ b/src/core/ddsc/src/dds_writer.c @@ -39,10 +39,6 @@ #include "dds__statistics.h" #include "dds__psmx.h" -#ifdef DDS_HAS_DURABILITY -#include "dds/durability/dds_durability.h" -#endif - DECL_ENTITY_LOCK_UNLOCK (dds_writer) #define DDS_WRITER_STATUS_MASK \ @@ -428,13 +424,14 @@ static dds_entity_t dds_create_writer_int (dds_entity_t participant_or_publisher if ((rc = dds_endpoint_add_psmx_endpoint (&wr->m_endpoint, wqos, &tp->m_ktopic->psmx_topics, DDS_PSMX_ENDPOINT_TYPE_WRITER)) != DDS_RETCODE_OK) goto err_pipe_open; -#if DDS_HAS_DURABILITY +#ifdef DDS_HAS_DURABILITY /* quorum applies only to durable writers. * By default quorum reached for volatile and transient-local writers * For durable writer the quorum is initially reached when quorum threshold == 0 * (but we'll likely prohibit this case as an invalid configuration because * it may lead to eventual inconsistencies). */ - uint32_t quorum = dds_durability_get_quorum(); + assert(wr->m_entity.m_domain->dc.dds_durability_get_quorum); + uint32_t quorum = wr->m_entity.m_domain->dc.dds_durability_get_quorum(); wr->quorum_reached = true; if (wqos->durability.kind >= DDS_DURABILITY_TRANSIENT) { wr->quorum_reached = (quorum == 0); @@ -479,7 +476,8 @@ static dds_entity_t dds_create_writer_int (dds_entity_t participant_or_publisher dds_publisher_unlock (pub); #ifdef DDS_HAS_DURABILITY - dds_durability_new_local_writer(writer); + assert(wr->m_entity.m_domain->dc.dds_durability_new_local_writer); + wr->m_entity.m_domain->dc.dds_durability_new_local_writer(writer); #endif // start async thread if not already started and the latency budget is non zero diff --git a/src/core/xtests/symbol_export/CMakeLists.txt b/src/core/xtests/symbol_export/CMakeLists.txt index bccea7a021..5b8f423247 100644 --- a/src/core/xtests/symbol_export/CMakeLists.txt +++ b/src/core/xtests/symbol_export/CMakeLists.txt @@ -19,7 +19,8 @@ target_include_directories(symbol_export_test PRIVATE "$" "$" "$" - "$") + "$" + "$") if (ENABLE_SECURITY) target_link_libraries(symbol_export_test PRIVATE security_api) diff --git a/src/durability/CMakeLists.txt b/src/durability/CMakeLists.txt index 434c38867a..e2bb45caca 100644 --- a/src/durability/CMakeLists.txt +++ b/src/durability/CMakeLists.txt @@ -7,32 +7,25 @@ # http://www.eclipse.org/org/documents/edl-v10.php. # # SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause -# -set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}") -set(binary_dir "${CMAKE_CURRENT_BINARY_DIR}") - -add_library(durability INTERFACE) - -target_include_directories( - durability INTERFACE - "$" - "$" - "$") - -set(headers - "${source_dir}/include/dds/durability/dds_durability.h" - "${source_dir}/include/dds/durability/durablesupport.h") -set(sources - "${source_dir}/src/dds_durability.c" - "${source_dir}/src/durablesupport.c") - -target_sources(durability INTERFACE ${headers} ${sources}) +idlc_generate(TARGET dcidl FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/durablesupport.idl") +add_library(durability SHARED "${CMAKE_CURRENT_SOURCE_DIR}/src/dds_durability.c") +set_property(TARGET durability PROPERTY C_VISIBILITY_PRESET hidden) +target_include_directories(durability PRIVATE + "$" + "$" + "$" + "$" + "$" + "$" + "$" + "$" +) +target_link_libraries(durability PRIVATE dcidl) install( - DIRECTORY - "${source_dir}/include/" - "${binary_dir}/include/" - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" - COMPONENT dev - FILES_MATCHING PATTERN "*.h") \ No newline at end of file + TARGETS durability + EXPORT "${PROJECT_NAME}" + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) diff --git a/src/durability/include/dds/durability/dds_durability.h b/src/durability/include/dds/durability/dds_durability.h deleted file mode 100644 index 83e9033478..0000000000 --- a/src/durability/include/dds/durability/dds_durability.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright(c) 2006 to 2020 ZettaScale Technology and others -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License -// v. 1.0 which is available at -// http://www.eclipse.org/org/documents/edl-v10.php. -// -// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause - -#ifndef DDS_DURABILITY_H -#define DDS_DURABILITY_H - -#include "dds/ddsi/ddsi_domaingv.h" -#include "dds/ddsrt/retcode.h" -#include "ddsc/dds.h" -#include "dds__types.h" -#include "dds/ddsc/dds_rhc.h" - -#if defined (__cplusplus) -extern "C" { -#endif - -/* Integration functions for durability plugins */ -typedef int (*plugin_init)(const char *argument, void **context, struct ddsi_domaingv *gv); -typedef int (*plugin_finalize)(void *context); - -dds_return_t dds_durability_init (const dds_domainid_t domain, struct ddsi_domaingv *gv); -dds_return_t dds_durability_fini (void); -uint32_t dds_durability_get_quorum (void); -dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc); -dds_return_t dds_durability_new_local_writer (dds_entity_t writer); -dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer); - -bool dds_durability_is_terminating (void); - - -#if defined (__cplusplus) -} -#endif - -#endif /* DDS_DURABILITY_H */ diff --git a/src/durability/include/dds/durability/dds_durability_private.h b/src/durability/include/dds/durability/dds_durability_private.h new file mode 100644 index 0000000000..fbe5b4ba37 --- /dev/null +++ b/src/durability/include/dds/durability/dds_durability_private.h @@ -0,0 +1,27 @@ +// Copyright(c) 2006 to 2020 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#ifndef DDS_DURABILITY_PRIVATE_H +#define DDS_DURABILITY_PRIVATE_H + +#include "dds/export.h" +#include "dds/durability/dds_durability_public.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +DDS_EXPORT void dds_durability_creator(dds_durability_t* ds); + +#if defined (__cplusplus) +} +#endif + +#endif /* DDS_DURABILITY_PRIVATE_H */ diff --git a/src/durability/include/dds/durability/dds_durability_public.h b/src/durability/include/dds/durability/dds_durability_public.h new file mode 100644 index 0000000000..e990cba38b --- /dev/null +++ b/src/durability/include/dds/durability/dds_durability_public.h @@ -0,0 +1,41 @@ +// Copyright(c) 2006 to 2020 ZettaScale Technology and others +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License +// v. 1.0 which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +#ifndef DDS_DURABILITY_PUBLIC_H +#define DDS_DURABILITY_PUBLIC_H + +#include "dds/ddsrt/dynlib.h" +#include "dds/ddsi/ddsi_domaingv.h" +#include "ddsc/dds.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +typedef struct dds_durability{ + ddsrt_dynlib_t lib_handle; + dds_return_t (*dds_durability_init) (const dds_domainid_t domain, struct ddsi_domaingv *gv); + dds_entity_t (*_dds_durability_fini) (void); + uint32_t (*dds_durability_get_quorum) (void); + dds_return_t (*dds_durability_new_local_reader) (dds_entity_t reader, struct dds_rhc *rhc); + dds_return_t (*dds_durability_new_local_writer) (dds_entity_t writer); + dds_return_t (*dds_durability_wait_for_quorum) (dds_entity_t writer); + bool (*dds_durability_is_terminating) (void); +}dds_durability_t; + +void dds_durability_fini (dds_durability_t* dc); +dds_return_t dds_durability_load (dds_durability_t* dc, const struct ddsi_domaingv* gv); +void dds_durability_unload (dds_durability_t* dc); + +#if defined (__cplusplus) +} +#endif + +#endif /* DDS_DURABILITY_PUBLIC_H */ diff --git a/src/durability/include/dds/durability/durablesupport.h b/src/durability/include/dds/durability/durablesupport.h deleted file mode 100644 index 0750233696..0000000000 --- a/src/durability/include/dds/durability/durablesupport.h +++ /dev/null @@ -1,390 +0,0 @@ -/**************************************************************** - - IMPORTANT: - - The file contains the definitions for the client durability related topics. - This file is partially copied from the output generated by durabledupport.idl - because we cannot generate code from an idl file due to cyclic dependencies - in idlc_generate(). - -*****************************************************************/ -#ifndef DURABLE_SUPPORT_H -#define DURABLE_SUPPORT_H - -#include "dds/ddsc/dds_public_impl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef uint8_t DurableSupport_id_t[16]; - -#define DurableSupport_id_t__alloc() \ -((DurableSupport_id_t*) dds_alloc (sizeof (DurableSupport_id_t))); - -typedef uint64_t DurableSupport_session_id_t; - -#define DurableSupport_session_id_t__alloc() \ -((DurableSupport_session_id_t*) dds_alloc (sizeof (DurableSupport_session_id_t))); - -typedef uint16_t DurableSupport_session_kind_t; - -#define DurableSupport_session_kind_t__alloc() \ -((DurableSupport_session_kind_t*) dds_alloc (sizeof (DurableSupport_session_kind_t))); - -typedef uint16_t DurableSupport_beadtype_t; - -#define DurableSupport_beadtype_t__alloc() \ -((DurableSupport_beadtype_t*) dds_alloc (sizeof (DurableSupport_beadtype_t))); - -typedef struct DurableSupport_status -{ - DurableSupport_id_t id; - char * hostname; - char * name; -} DurableSupport_status; - -extern const dds_topic_descriptor_t DurableSupport_status_desc; - -#define DurableSupport_status__alloc() \ -((DurableSupport_status*) dds_alloc (sizeof (DurableSupport_status))); - -#define DurableSupport_status_free(d,o) \ -dds_sample_free ((d), &DurableSupport_status_desc, (o)) - -typedef struct DurableSupport_range -{ - uint64_t lb; - uint64_t ub; -} DurableSupport_range; - -#ifndef DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED -#define DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED -typedef struct dds_sequence_DurableSupport_range -{ - uint32_t _maximum; - uint32_t _length; - struct DurableSupport_range *_buffer; - bool _release; -} dds_sequence_DurableSupport_range; - -#define dds_sequence_DurableSupport_range__alloc() \ -((dds_sequence_DurableSupport_range*) dds_alloc (sizeof (dds_sequence_DurableSupport_range))); - -#define dds_sequence_DurableSupport_range_allocbuf(l) \ -((struct DurableSupport_range *) dds_alloc ((l) * sizeof (struct DurableSupport_range))) -#endif /* DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED */ - -typedef struct DurableSupport_writer -{ - DurableSupport_id_t id; - uint32_t flags; - dds_sequence_DurableSupport_range ranges; -} DurableSupport_writer; - -#ifndef DDS_SEQUENCE_DURABLESUPPORT_WRITER_DEFINED -#define DDS_SEQUENCE_DURABLESUPPORT_WRITER_DEFINED -typedef struct dds_sequence_DurableSupport_writer -{ - uint32_t _maximum; - uint32_t _length; - struct DurableSupport_writer *_buffer; - bool _release; -} dds_sequence_DurableSupport_writer; - -#define dds_sequence_DurableSupport_writer__alloc() \ -((dds_sequence_DurableSupport_writer*) dds_alloc (sizeof (dds_sequence_DurableSupport_writer))); - -#define dds_sequence_DurableSupport_writer_allocbuf(l) \ -((struct DurableSupport_writer *) dds_alloc ((l) * sizeof (struct DurableSupport_writer))) -#endif /* DDS_SEQUENCE_DURABLESUPPORT_WRITER_DEFINED */ - -typedef struct DurableSupport_set -{ - char * partition; - char * tpname; - char * type_id; - uint32_t flags; - dds_sequence_DurableSupport_writer writers; -} DurableSupport_set; - -#ifndef DDS_SEQUENCE_DURABLESUPPORT_SET_DEFINED -#define DDS_SEQUENCE_DURABLESUPPORT_SET_DEFINED -typedef struct dds_sequence_DurableSupport_set -{ - uint32_t _maximum; - uint32_t _length; - struct DurableSupport_set *_buffer; - bool _release; -} dds_sequence_DurableSupport_set; - -#define dds_sequence_DurableSupport_set__alloc() \ -((dds_sequence_DurableSupport_set*) dds_alloc (sizeof (dds_sequence_DurableSupport_set))); - -#define dds_sequence_DurableSupport_set_allocbuf(l) \ -((struct DurableSupport_set *) dds_alloc ((l) * sizeof (struct DurableSupport_set))) -#endif /* DDS_SEQUENCE_DURABLESUPPORT_SET_DEFINED */ - -typedef struct DurableSupport_state -{ - DurableSupport_id_t id; - char * name; - dds_sequence_DurableSupport_set sets; -} DurableSupport_state; - -extern const dds_topic_descriptor_t DurableSupport_state_desc; - -#define DurableSupport_state__alloc() \ -((DurableSupport_state*) dds_alloc (sizeof (DurableSupport_state))); - -#define DurableSupport_state_free(d,o) \ -dds_sample_free ((d), &DurableSupport_state_desc, (o)) - -#define DurableSupport_BEADTYPE_SESSION 1 -#define DurableSupport_BEADTYPE_SET 2 -#define DurableSupport_BEADTYPE_WRITER 3 -#define DurableSupport_BEADTYPE_DATA 4 -#define DurableSupport_SESSION_KIND_START 1 -#define DurableSupport_SESSION_KIND_END 2 -#define DurableSupport_SESSION_KIND_ABORT 3 -typedef struct DurableSupport_session_t -{ - DurableSupport_session_kind_t kind; - DurableSupport_session_id_t session_id; -} DurableSupport_session_t; - -#ifndef DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED -#define DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED -typedef struct dds_sequence_DurableSupport_id_t -{ - uint32_t _maximum; - uint32_t _length; - DurableSupport_id_t *_buffer; - bool _release; -} dds_sequence_DurableSupport_id_t; - -#define dds_sequence_DurableSupport_id_t__alloc() \ -((dds_sequence_DurableSupport_id_t*) dds_alloc (sizeof (dds_sequence_DurableSupport_id_t))); - -#define dds_sequence_DurableSupport_id_t_allocbuf(l) \ -((DurableSupport_id_t *) dds_alloc ((l) * sizeof (DurableSupport_id_t))) -#endif /* DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED */ - -typedef struct DurableSupport_set_t -{ - char * partition; - char * tpname; - char * type_id; - uint32_t flags; - dds_sequence_DurableSupport_id_t addressees; -} DurableSupport_set_t; - -typedef struct DurableSupport_writer_properties_t -{ - bool autodispose; -} DurableSupport_writer_properties_t; - -#ifndef DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED -#define DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED -typedef struct dds_sequence_DurableSupport_range -{ - uint32_t _maximum; - uint32_t _length; - struct DurableSupport_range *_buffer; - bool _release; -} dds_sequence_DurableSupport_range; - -#define dds_sequence_DurableSupport_range__alloc() \ -((dds_sequence_DurableSupport_range*) dds_alloc (sizeof (dds_sequence_DurableSupport_range))); - -#define dds_sequence_DurableSupport_range_allocbuf(l) \ -((struct DurableSupport_range *) dds_alloc ((l) * sizeof (struct DurableSupport_range))) -#endif /* DDS_SEQUENCE_DURABLESUPPORT_RANGE_DEFINED */ - -typedef struct DurableSupport_writer_t -{ - DurableSupport_id_t id; - struct DurableSupport_writer_properties_t properties; - uint32_t flags; - dds_sequence_DurableSupport_range ranges; -} DurableSupport_writer_t; - -#ifndef DDS_SEQUENCE_OCTET_DEFINED -#define DDS_SEQUENCE_OCTET_DEFINED -typedef struct dds_sequence_octet -{ - uint32_t _maximum; - uint32_t _length; - uint8_t *_buffer; - bool _release; -} dds_sequence_octet; - -#define dds_sequence_octet__alloc() \ -((dds_sequence_octet*) dds_alloc (sizeof (dds_sequence_octet))); - -#define dds_sequence_octet_allocbuf(l) \ -((uint8_t *) dds_alloc ((l) * sizeof (uint8_t))) -#endif /* DDS_SEQUENCE_OCTET_DEFINED */ - -typedef struct DurableSupport_data_t -{ - dds_sequence_octet blob; -} DurableSupport_data_t; - -typedef struct DurableSupport_content -{ - DurableSupport_beadtype_t _d; - union - { - struct DurableSupport_session_t session; - struct DurableSupport_set_t set; - struct DurableSupport_writer_t writer; - struct DurableSupport_data_t data; - } _u; -} DurableSupport_content; - -typedef struct DurableSupport_bead -{ - DurableSupport_id_t id; - struct DurableSupport_content body; -} DurableSupport_bead; - -extern const dds_topic_descriptor_t DurableSupport_bead_desc; - -#define DurableSupport_bead__alloc() \ -((DurableSupport_bead*) dds_alloc (sizeof (DurableSupport_bead))); - -#define DurableSupport_bead_free(d,o) \ -dds_sample_free ((d), &DurableSupport_bead_desc, (o)) - -typedef struct DurableSupport_control -{ - DurableSupport_id_t id; -} DurableSupport_control; - -extern const dds_topic_descriptor_t DurableSupport_control_desc; - -#define DurableSupport_control__alloc() \ -((DurableSupport_control*) dds_alloc (sizeof (DurableSupport_control))); - -#define DurableSupport_control_free(d,o) \ -dds_sample_free ((d), &DurableSupport_control_desc, (o)) - -typedef int64_t DurableSupport_duration_t; - -#define DurableSupport_duration_t__alloc() \ -((DurableSupport_duration_t*) dds_alloc (sizeof (DurableSupport_duration_t))); - -typedef uint16_t DurableSupport_responsetype_t; - -#define DurableSupport_responsetype_t__alloc() \ -((DurableSupport_responsetype_t*) dds_alloc (sizeof (DurableSupport_responsetype_t))); - -typedef uint64_t DurableSupport_delivery_id_t; - -#define DurableSupport_delivery_id_t__alloc() \ -((DurableSupport_delivery_id_t*) dds_alloc (sizeof (DurableSupport_delivery_id_t))); - -typedef struct DurableSupport_request_key -{ - DurableSupport_id_t rguid; -} DurableSupport_request_key; - -typedef struct DurableSupport_request -{ - struct DurableSupport_request_key key; - DurableSupport_id_t client; - char * partition; - char * tpname; - char * type_id; - DurableSupport_duration_t timeout; -} DurableSupport_request; - -extern const dds_topic_descriptor_t DurableSupport_request_desc; - -#define DurableSupport_request__alloc() \ -((DurableSupport_request*) dds_alloc (sizeof (DurableSupport_request))); - -#define DurableSupport_request_free(d,o) \ -dds_sample_free ((d), &DurableSupport_request_desc, (o)) - -#define DurableSupport_RESPONSETYPE_SET 1 -#define DurableSupport_RESPONSETYPE_DATA 2 -#ifndef DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED -#define DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED -typedef struct dds_sequence_DurableSupport_id_t -{ - uint32_t _maximum; - uint32_t _length; - DurableSupport_id_t *_buffer; - bool _release; -} dds_sequence_DurableSupport_id_t; - -#define dds_sequence_DurableSupport_id_t__alloc() \ -((dds_sequence_DurableSupport_id_t*) dds_alloc (sizeof (dds_sequence_DurableSupport_id_t))); - -#define dds_sequence_DurableSupport_id_t_allocbuf(l) \ -((DurableSupport_id_t *) dds_alloc ((l) * sizeof (DurableSupport_id_t))) -#endif /* DDS_SEQUENCE_DURABLESUPPORT_ID_T_DEFINED */ - -typedef struct DurableSupport_response_set_t -{ - DurableSupport_delivery_id_t delivery_id; - dds_sequence_DurableSupport_id_t guids; - char * partition; - char * tpname; - char * type_id; - uint32_t flags; -} DurableSupport_response_set_t; - -#ifndef DDS_SEQUENCE_OCTET_DEFINED -#define DDS_SEQUENCE_OCTET_DEFINED -typedef struct dds_sequence_octet -{ - uint32_t _maximum; - uint32_t _length; - uint8_t *_buffer; - bool _release; -} dds_sequence_octet; - -#define dds_sequence_octet__alloc() \ -((dds_sequence_octet*) dds_alloc (sizeof (dds_sequence_octet))); - -#define dds_sequence_octet_allocbuf(l) \ -((uint8_t *) dds_alloc ((l) * sizeof (uint8_t))) -#endif /* DDS_SEQUENCE_OCTET_DEFINED */ - -typedef struct DurableSupport_response_data_t -{ - dds_sequence_octet blob; -} DurableSupport_response_data_t; - -typedef struct DurableSupport_response_content -{ - DurableSupport_responsetype_t _d; - union - { - struct DurableSupport_response_set_t set; - struct DurableSupport_response_data_t data; - } _u; -} DurableSupport_response_content; - -typedef struct DurableSupport_response -{ - DurableSupport_id_t id; - struct DurableSupport_response_content body; -} DurableSupport_response; - -extern const dds_topic_descriptor_t DurableSupport_response_desc; - -#define DurableSupport_response__alloc() \ -((DurableSupport_response*) dds_alloc (sizeof (DurableSupport_response))); - -#define DurableSupport_response_free(d,o) \ -dds_sample_free ((d), &DurableSupport_response_desc, (o)) - -#ifdef __cplusplus -} -#endif - -#endif /* DURABLE_SUPPORT_H */ diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index e21e7c0239..e6eaa4feec 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -9,21 +9,21 @@ * * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ +#include "durablesupport.h" +#include "dds/durability/dds_durability_private.h" #include "dds/ddsi/ddsi_domaingv.h" -#include "dds/durability/dds_durability.h" -#include "dds/durability/durablesupport.h" #include "dds/ddsrt/atomics.h" #include "dds/ddsrt/string.h" #include "dds/ddsrt/heap.h" #include "dds/ddsrt/threads.h" #include "dds/ddsrt/log.h" #include "ddsc/dds.h" -#include -#include "dds__writer.h" +#include "../src/dds__writer.h" #include "dds/ddsi/ddsi_endpoint.h" #include "dds/ddsrt/avl.h" #include "dds/ddsi/ddsi_serdata.h" #include "dds/ddsi/ddsi_typelib.h" +#include #define DEFAULT_QOURUM 1 #define DEFAULT_IDENT "durable_support" @@ -1392,11 +1392,15 @@ err_response_subscriber : return NULL; } -static void dc_com_free (struct com_t *com) +static void dc_com_free (struct com_t *com, dds_entity_t* pp_out) { assert(com); DDS_CLOG(DDS_LC_DUR, &dc.gv->logconfig, "destroying dc infrastructure\n"); - dds_delete(com->participant); + if ( pp_out == NULL ){ + dds_delete(com->participant); + } else { + *pp_out = com->participant; + } ddsrt_free(com); dc.com = NULL; return; @@ -2204,7 +2208,7 @@ static dds_return_t activate_request_listener (struct dc_t *dc) return DDS_RETCODE_ERROR; } -dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_domaingv *gv) +static dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_domaingv *gv) { dds_return_t rc; @@ -2259,7 +2263,7 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom return DDS_RETCODE_OK; err_recv_thread: - dc_com_free(dc.com); + dc_com_free(dc.com, NULL); err_com_new: dds_delete_listener(dc.request_listener); err_create_request_listener: @@ -2277,9 +2281,9 @@ dds_return_t dds_durability_init (const dds_domainid_t domainid, struct ddsi_dom } /* make sure that dc terminates when the last participant is destroyed */ -dds_return_t dds_durability_fini (void) +static dds_entity_t _dds_durability_fini (void) { - dds_return_t rc = DDS_RETCODE_OK; + dds_entity_t pp_out = 0; uint32_t refcount; /* The durable client is deinitialized when the last participant is about @@ -2289,12 +2293,13 @@ dds_return_t dds_durability_fini (void) refcount = ddsrt_atomic_dec32_nv(&dc.refcount); if (refcount != 2) { /* skip */ - return DDS_RETCODE_OK; + return pp_out; } if (dc.com) { /* indicate the the durable client is terminating */ ddsrt_atomic_st32 (&dc.termflag, 1); /* force the dc thread to terminate */ + dds_return_t rc; if ((rc = dds_waitset_set_trigger(dc.com->ws, true)) < 0) { DDS_ERROR("failed to trigger dc recv thread [%s]", dds_strretcode(rc)); } @@ -2304,7 +2309,7 @@ dds_return_t dds_durability_fini (void) } dds_delete_listener(dc.request_listener); dds_delete_listener(dc.quorum_listener); - dc_com_free(dc.com); + dc_com_free(dc.com, &pp_out); // Participant must be deleted outside the plugin. ddsrt_avl_cfree(&delivery_ctx_td, &dc.delivery_ctxs, cleanup_delivery_ctx); ddsrt_cond_destroy(&dc.delivery_request_cond); ddsrt_mutex_destroy(&dc.delivery_request_mutex); @@ -2313,10 +2318,10 @@ dds_return_t dds_durability_fini (void) ddsrt_avl_cfree(&server_td, &dc.servers, cleanup_server); ddsrt_free(dc.cfg.ident); } - return DDS_RETCODE_OK; + return pp_out; } -bool dds_durability_is_terminating (void) +static bool dds_durability_is_terminating (void) { return (ddsrt_atomic_ld32(&dc.termflag) > 0); } @@ -2369,7 +2374,7 @@ static bool is_application_entity (struct dc_t *dc, dds_entity_t entity) return true; } -dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc) +static dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rhc *rhc) { dds_durability_kind_t dkind; dds_qos_t *qos; @@ -2408,7 +2413,7 @@ dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct dds_rh } /* check if the writer is a durable application writer, and if so, we need to keep track of the quorum */ -dds_return_t dds_durability_new_local_writer (dds_entity_t writer) +static dds_return_t dds_durability_new_local_writer (dds_entity_t writer) { dds_durability_kind_t dkind; dds_qos_t *wqos; @@ -2508,7 +2513,7 @@ static dds_return_t dds_durability_get_quorum_reached (dds_entity_t writer, bool * DDS_RETCODE_OK if quorum is reached * DDS_PRECONDITION_NOT_MET otherwise */ -dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) +static dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) { dds_return_t ret = DDS_RETCODE_ERROR; ddsrt_mtime_t tnow = ddsrt_time_monotonic (); @@ -2548,8 +2553,18 @@ dds_return_t dds_durability_wait_for_quorum (dds_entity_t writer) } /* get the configured quorum */ -uint32_t dds_durability_get_quorum (void) +static uint32_t dds_durability_get_quorum (void) { return dc.cfg.quorum; } +void dds_durability_creator(dds_durability_t* ds) +{ + ds->dds_durability_init = dds_durability_init; + ds->_dds_durability_fini = _dds_durability_fini; + ds->dds_durability_get_quorum = dds_durability_get_quorum; + ds->dds_durability_new_local_reader = dds_durability_new_local_reader; + ds->dds_durability_new_local_writer = dds_durability_new_local_writer; + ds->dds_durability_wait_for_quorum = dds_durability_wait_for_quorum; + ds->dds_durability_is_terminating = dds_durability_is_terminating; +} diff --git a/src/durability/src/durablesupport.c b/src/durability/src/durablesupport.c deleted file mode 100644 index 6325ac0e3f..0000000000 --- a/src/durability/src/durablesupport.c +++ /dev/null @@ -1,1041 +0,0 @@ -/**************************************************************** - - Generated by Eclipse Cyclone DDS IDL to C Translator - File name: /home/lex/Repositories/TheFixer/durable_support/build/src/durablesupport.c - Source: /home/lex/Repositories/TheFixer/durable_support/src/durablesupport.idl - Cyclone DDS: V0.11.0 - -*****************************************************************/ -#include "../include/dds/durability/durablesupport.h" - -static const uint32_t DurableSupport_status_ops [] = -{ - /* status */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_status, id), 16u, - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_status, hostname), - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_status, name), - DDS_OP_RTS, - - /* key: id */ - DDS_OP_KOF | 1, 1u /* order: 0 */ -}; - -static const dds_key_descriptor_t DurableSupport_status_keys[1] = -{ - { "id", 9, 0 } -}; - -/* Type Information: - [MINIMAL 1609a972dd9ffc746226aaae0ce7] (#deps: 1) - - [MINIMAL 43f53a2be35b432cc735e9431a89] - [COMPLETE 3ae8d3b6272f54c8257bf018eda8] (#deps: 1) - - [COMPLETE aca4d5a256d39713924333e85c6d] -*/ -#define TYPE_INFO_CDR_DurableSupport_status (const unsigned char []){ \ - 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x16, 0x09, 0xa9, 0x72, 0xdd, 0x9f, 0xfc, 0x74, 0x62, 0x26, 0xaa, \ - 0xae, 0x0c, 0xe7, 0x00, 0x58, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x3a, 0xe8, 0xd3, \ - 0xb6, 0x27, 0x2f, 0x54, 0xc8, 0x25, 0x7b, 0xf0, 0x18, 0xed, 0xa8, 0x00, 0x8f, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x40, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_status 148u -#define TYPE_MAP_CDR_DurableSupport_status (const unsigned char []){ \ - 0x9a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0x16, 0x09, 0xa9, 0x72, 0xdd, 0x9f, 0xfc, \ - 0x74, 0x62, 0x26, 0xaa, 0xae, 0x0c, 0xe7, 0x00, 0x54, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x08, 0x97, 0xac, 0xf4, \ - 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0xb0, 0x68, 0x93, 0x1c, \ - 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ - 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ - 0xf4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf2, 0x3a, 0xe8, 0xd3, 0xb6, 0x27, 0x2f, 0x54, \ - 0xc8, 0x25, 0x7b, 0xf0, 0x18, 0xed, 0xa8, 0x00, 0x8b, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x74, 0x61, 0x74, \ - 0x75, 0x73, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x09, 0x00, 0x00, 0x00, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, \ - 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ - 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0xf2, 0x3a, 0xe8, 0xd3, 0xb6, 0x27, 0x2f, 0x54, 0xc8, 0x25, 0x7b, 0xf0, 0x18, 0xed, 0xa8, 0xf1, \ - 0x16, 0x09, 0xa9, 0x72, 0xdd, 0x9f, 0xfc, 0x74, 0x62, 0x26, 0xaa, 0xae, 0x0c, 0xe7, 0xf2, 0xac, \ - 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_status 476u -const dds_topic_descriptor_t DurableSupport_status_desc = -{ - .m_size = sizeof (DurableSupport_status), - .m_align = dds_alignof (DurableSupport_status), - .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 1u, - .m_typename = "DurableSupport::status", - .m_keys = DurableSupport_status_keys, - .m_nops = 5, - .m_ops = DurableSupport_status_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_status, .sz = TYPE_INFO_CDR_SZ_DurableSupport_status }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_status, .sz = TYPE_MAP_CDR_SZ_DurableSupport_status } -}; - -static const uint32_t DurableSupport_state_ops [] = -{ - /* state */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_state, id), 16u, - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_state, name), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_state, sets), sizeof (DurableSupport_set), (4u << 16u) + 5u /* set */, - DDS_OP_RTS, - - /* set */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, partition), - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, tpname), - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_STR, offsetof (DurableSupport_set, type_id), - DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_set, flags), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_set, writers), sizeof (DurableSupport_writer), (4u << 16u) + 5u /* writer */, - DDS_OP_RTS, - - /* writer */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_writer, id), 16u, - DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_writer, flags), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_writer, ranges), sizeof (DurableSupport_range), (4u << 16u) + 5u /* range */, - DDS_OP_RTS, - - /* range */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, lb), - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, ub), - DDS_OP_RTS, - - /* key: id */ - DDS_OP_KOF | 1, 1u /* order: 0 */ -}; - -static const dds_key_descriptor_t DurableSupport_state_keys[1] = -{ - { "id", 42, 0 } -}; - -/* Type Information: - [MINIMAL 9546da84e880713f59c93561b8d8] (#deps: 4) - - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 0edda7680861b44f54f71e189994] - - [MINIMAL 7b73d4df4f265b2da8c52f3c3a8e] - - [MINIMAL ef038b7b19448c9ce27fa1c268cd] - [COMPLETE 174aa20548235aee4aff5111d8a2] (#deps: 4) - - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE 0b9ecead7e5e9db531d5a4ef26b1] - - [COMPLETE 3be64a4fbc92a7b2f612cbd52a3a] - - [COMPLETE d8d43c2295c185a21b9591a7126c] -*/ -#define TYPE_INFO_CDR_DurableSupport_state (const unsigned char []){ \ - 0x20, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x95, 0x46, 0xda, 0x84, 0xe8, 0x80, 0x71, 0x3f, 0x59, 0xc9, 0x35, \ - 0x61, 0xb8, 0xd8, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, 0x94, 0x00, \ - 0x7a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, \ - 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, \ - 0x37, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x88, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x4a, 0xa2, 0x05, 0x48, 0x23, 0x5a, 0xee, 0x4a, 0xff, 0x51, \ - 0x11, 0xd8, 0xa2, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ - 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x0b, 0x9e, 0xce, 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0x00, \ - 0xca, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, \ - 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, \ - 0x61, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_state 292u -#define TYPE_MAP_CDR_DurableSupport_state (const unsigned char []){ \ - 0xff, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf1, 0x95, 0x46, 0xda, 0x84, 0xe8, 0x80, 0x71, \ - 0x3f, 0x59, 0xc9, 0x35, 0x61, 0xb8, 0xd8, 0x00, 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0xb0, 0x68, 0x93, 0x1c, \ - 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ - 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, 0x94, 0x17, 0x8d, \ - 0x51, 0x02, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, \ - 0x89, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x10, 0x02, 0xf1, 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, \ - 0x94, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x0c, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, 0x0b, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0x7b, 0x73, 0xd4, 0xdf, \ - 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0xbf, 0x63, 0x9b, 0x5f, 0xf1, 0x7b, \ - 0x73, 0xd4, 0xdf, 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0x00, 0x00, 0x00, \ - 0x66, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x56, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, \ - 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, \ - 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x8d, 0x81, 0x02, 0xfb, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, \ - 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x26, \ - 0x40, 0x3e, 0xc6, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x1c, \ - 0x78, 0xb4, 0x86, 0x00, 0x01, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x4a, 0xa2, \ - 0x05, 0x48, 0x23, 0x5a, 0xee, 0x4a, 0xff, 0x51, 0x11, 0xd8, 0xa2, 0x00, 0x9b, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x02, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x73, 0x74, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x70, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, \ - 0x27, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, \ - 0x0b, 0x9e, 0xce, 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, \ - 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x0b, 0x9e, 0xce, \ - 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0x00, 0xc6, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x73, 0x65, 0x74, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x70, 0x00, \ - 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, \ - 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, \ - 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x77, 0x72, 0x69, 0x74, \ - 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x3b, 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, 0xf6, \ - 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, \ - 0x65, 0x72, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, \ - 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, \ - 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, \ - 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x5d, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x61, 0x6e, 0x67, \ - 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6c, 0x62, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0xf2, 0x17, 0x4a, 0xa2, 0x05, 0x48, 0x23, 0x5a, 0xee, 0x4a, 0xff, 0x51, \ - 0x11, 0xd8, 0xa2, 0xf1, 0x95, 0x46, 0xda, 0x84, 0xe8, 0x80, 0x71, 0x3f, 0x59, 0xc9, 0x35, 0x61, \ - 0xb8, 0xd8, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ - 0xf2, 0x0b, 0x9e, 0xce, 0xad, 0x7e, 0x5e, 0x9d, 0xb5, 0x31, 0xd5, 0xa4, 0xef, 0x26, 0xb1, 0xf1, \ - 0x0e, 0xdd, 0xa7, 0x68, 0x08, 0x61, 0xb4, 0x4f, 0x54, 0xf7, 0x1e, 0x18, 0x99, 0x94, 0xf2, 0x3b, \ - 0xe6, 0x4a, 0x4f, 0xbc, 0x92, 0xa7, 0xb2, 0xf6, 0x12, 0xcb, 0xd5, 0x2a, 0x3a, 0xf1, 0x7b, 0x73, \ - 0xd4, 0xdf, 0x4f, 0x26, 0x5b, 0x2d, 0xa8, 0xc5, 0x2f, 0x3c, 0x3a, 0x8e, 0xf2, 0xd8, 0xd4, 0x3c, \ - 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, 0xef, 0x03, 0x8b, 0x7b, \ - 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_state 1450u -const dds_topic_descriptor_t DurableSupport_state_desc = -{ - .m_size = sizeof (DurableSupport_state), - .m_align = dds_alignof (DurableSupport_state), - .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 1u, - .m_typename = "DurableSupport::state", - .m_keys = DurableSupport_state_keys, - .m_nops = 21, - .m_ops = DurableSupport_state_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_state, .sz = TYPE_INFO_CDR_SZ_DurableSupport_state }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_state, .sz = TYPE_MAP_CDR_SZ_DurableSupport_state } -}; - -static const uint32_t DurableSupport_bead_ops [] = -{ - /* bead */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_bead, id), 16u, - DDS_OP_ADR | DDS_OP_TYPE_EXT, offsetof (DurableSupport_bead, body), (3u << 16u) + 4u /* content */, - DDS_OP_RTS, - - /* content */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_content, _d), 4u, (20u << 16u) + 4u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 17 /* session_t */, 1, offsetof (DurableSupport_content, _u.session), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 19 /* set_t */, 2, offsetof (DurableSupport_content, _u.set), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 33 /* writer_t */, 3, offsetof (DurableSupport_content, _u.writer), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 53 /* data_t */, 4, offsetof (DurableSupport_content, _u.data), 0u, - DDS_OP_RTS, - - /* session_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_2BY, offsetof (DurableSupport_session_t, kind), - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_session_t, session_id), - DDS_OP_RTS, - - /* set_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, partition), - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, tpname), - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_set_t, type_id), - DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_set_t, flags), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_ARR, offsetof (DurableSupport_set_t, addressees), sizeof (DurableSupport_id_t), (8u << 16u) + 4u, - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, 0u, 16u, - DDS_OP_RTS, - DDS_OP_RTS, - - /* writer_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_writer_t, id), 16u, - DDS_OP_ADR | DDS_OP_TYPE_EXT, offsetof (DurableSupport_writer_t, properties), (3u << 16u) + 10u /* writer_properties_t */, - DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_writer_t, flags), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_STU, offsetof (DurableSupport_writer_t, ranges), sizeof (DurableSupport_range), (4u << 16u) + 9u /* range */, - DDS_OP_RTS, - - /* writer_properties_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_BLN, offsetof (DurableSupport_writer_properties_t, autodispose), - DDS_OP_RTS, - - /* range */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, lb), - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_range, ub), - DDS_OP_RTS, - - /* data_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_data_t, blob), - DDS_OP_RTS, - - /* key: id */ - DDS_OP_KOF | 1, 1u /* order: 0 */ -}; - -static const dds_key_descriptor_t DurableSupport_bead_keys[1] = -{ - { "id", 82, 0 } -}; - -/* Type Information: - [MINIMAL 333a527587be11928ad9cbfa1803] (#deps: 10) - - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL e4bc4a05081322db5581a91d817f] - - [MINIMAL 80455e796dd3437163cb532089da] - - [MINIMAL 7fe2256248fb0dc7c6a9b6c616fb] - - [MINIMAL d8398b259af5a04792e296996c27] - - [MINIMAL 5068289639b114fecda3f2c2ebd6] - - [MINIMAL 889fb89d6714387ca74c9aa42719] - - [MINIMAL 7d1dfbcf78261b30f20d1dadb067] - - [MINIMAL ef038b7b19448c9ce27fa1c268cd] - - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE a10b59cc2ac5234a0ab0c89deed6] (#deps: 11) - - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE ad3badfa4313f0bde4a077931856] - - [COMPLETE 105e7fa73d9700c1960716873c88] - - [COMPLETE 5de973c540260a829429a905efcd] - - [COMPLETE 838f13c80cfd7a0061fb91f88e49] - - [COMPLETE 9c5d42ec81585355d169823828eb] - - [COMPLETE e2beee99b860e5aa4c372c3b5655] - - [COMPLETE e6c4e5bb805c08c1d9e923e071ea] - - [COMPLETE 7a239210b1658deca81e1474b300] - - [COMPLETE d8d43c2295c185a21b9591a7126c] - - [COMPLETE a092964f6f76e3d643846ba36f9b] -*/ -#define TYPE_INFO_CDR_DurableSupport_bead (const unsigned char []){ \ - 0x58, 0x02, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x18, 0x01, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x33, 0x3a, 0x52, 0x75, 0x87, 0xbe, 0x11, 0x92, 0x8a, 0xd9, 0xcb, \ - 0xfa, 0x18, 0x03, 0x00, 0x55, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, \ - 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xe4, 0xbc, 0x4a, 0x05, 0x08, 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0x00, \ - 0xcc, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ - 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0x00, \ - 0x55, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ - 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, 0xb1, 0x14, 0xfe, 0xcd, 0xa3, 0xf2, 0xc2, 0xeb, 0xd6, 0x00, \ - 0x7a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, \ - 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, 0x19, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, 0x1d, 0xad, 0xb0, 0x67, 0x00, \ - 0x27, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, \ - 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x37, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ - 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x30, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa1, 0x0b, 0x59, 0xcc, 0x2a, 0xc5, 0x23, 0x4a, 0x0a, 0xb0, 0xc8, \ - 0x9d, 0xee, 0xd6, 0x00, 0x83, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, \ - 0x0b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ - 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, 0x13, 0xf0, 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0x00, \ - 0x13, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, \ - 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, 0x39, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, \ - 0x8d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, \ - 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, \ - 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, 0xe5, \ - 0xaa, 0x4c, 0x37, 0x2c, 0x3b, 0x56, 0x55, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0x00, \ - 0xd5, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, \ - 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, \ - 0x61, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, \ - 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x00, 0x4f, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_bead 604u -#define TYPE_MAP_CDR_DurableSupport_bead (const unsigned char []){ \ - 0x28, 0x04, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xf1, 0x33, 0x3a, 0x52, 0x75, 0x87, 0xbe, 0x11, \ - 0x92, 0x8a, 0xd9, 0xcb, 0xfa, 0x18, 0x03, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xe4, 0xbc, 0x4a, 0x05, 0x08, \ - 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ - 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0xe4, 0xbc, 0x4a, 0x05, 0x08, \ - 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, \ - 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ - 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ - 0xa4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x7f, 0xe2, 0x25, 0x62, 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, \ - 0xfb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0xd6, 0xf4, 0x0c, \ - 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, \ - 0xb1, 0x14, 0xfe, 0xcd, 0xa3, 0xf2, 0xc2, 0xeb, 0xd6, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xa8, 0x2f, 0xee, 0xe3, \ - 0x24, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ - 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ - 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0x7f, 0xe2, 0x25, 0x62, \ - 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x80, \ - 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xd9, 0x39, 0xaa, \ - 0xf7, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ - 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x7f, 0xc8, 0xef, \ - 0x54, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, \ - 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x06, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, \ - 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, 0xb1, 0x14, 0xfe, \ - 0xcd, 0xa3, 0xf2, 0xc2, 0xeb, 0xd6, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, \ - 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, \ - 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, \ - 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, \ - 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x73, 0xed, \ - 0xc9, 0x6c, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, 0x27, \ - 0x19, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, \ - 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, \ - 0x0d, 0x1d, 0xad, 0xb0, 0x67, 0x74, 0x69, 0x3d, 0x2f, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0x00, 0x1e, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, 0x01, 0x00, 0x00, 0xf1, 0xef, 0x03, 0x8b, 0x7b, \ - 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x8d, 0x81, 0x02, 0xfb, 0xf1, 0x7d, \ - 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, 0x1d, 0xad, 0xb0, 0x67, 0x00, 0x00, 0x00, \ - 0x23, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x01, 0x1c, 0x63, 0x57, 0x19, 0xf1, 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, \ - 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x26, 0x40, 0x3e, 0xc6, 0x00, \ - 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x1c, 0x78, 0xb4, 0x86, 0xf1, \ - 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, \ - 0x28, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0x8b, 0x06, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0xf2, 0xa1, 0x0b, 0x59, 0xcc, 0x2a, 0xc5, 0x23, 0x4a, 0x0a, 0xb0, 0xc8, \ - 0x9d, 0xee, 0xd6, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x62, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, \ - 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, \ - 0x13, 0xf0, 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ - 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, 0x13, 0xf0, \ - 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0x00, 0x0f, 0x01, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, \ - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x63, 0x6f, 0x6e, 0x74, \ - 0x65, 0x6e, 0x74, 0x00, 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, 0x3d, \ - 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5d, \ - 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, \ - 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, 0xe5, 0xaa, 0x4c, 0x37, 0x2c, 0x3b, 0x56, \ - 0x55, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, \ - 0xea, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xa0, 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, \ - 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, 0x10, 0x5e, 0x7f, 0xa7, \ - 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x62, 0x65, 0x61, 0x64, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x5d, 0xe9, 0x73, 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, \ - 0xa9, 0x05, 0xef, 0xcd, 0x89, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x22, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, \ - 0x74, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, \ - 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6b, 0x69, 0x6e, 0x64, \ - 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x9c, \ - 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x00, 0x00, 0x00, \ - 0x0b, 0x00, 0x00, 0x00, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x00, 0x00, \ - 0x00, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, \ - 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, \ - 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x9c, 0x5d, \ - 0x42, 0xec, 0x81, 0x58, 0x53, 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0x39, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, \ - 0xe5, 0xaa, 0x4c, 0x37, 0x2c, 0x3b, 0x56, 0x55, 0xcd, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x73, 0x65, 0x74, 0x5f, \ - 0x74, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, \ - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, \ - 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ - 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x72, \ - 0x65, 0x73, 0x73, 0x65, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, \ - 0x08, 0xc1, 0xd9, 0xe9, 0x23, 0xe0, 0x71, 0xea, 0xd1, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, \ - 0x65, 0x72, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, \ - 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, \ - 0x65, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ - 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, \ - 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, \ - 0x07, 0x00, 0x00, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x00, 0x00, 0xf2, 0x7a, 0x23, \ - 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, 0x00, 0x5a, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, \ - 0x73, 0x5f, 0x74, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x61, 0x75, 0x74, 0x6f, \ - 0x64, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x00, 0x00, 0x00, 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, \ - 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x6c, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x75, 0x62, 0x00, 0x00, 0x00, 0xf2, 0xa0, 0x92, \ - 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0x4b, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \ - 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x01, 0x00, 0x00, \ - 0x0c, 0x00, 0x00, 0x00, 0xf2, 0xa1, 0x0b, 0x59, 0xcc, 0x2a, 0xc5, 0x23, 0x4a, 0x0a, 0xb0, 0xc8, \ - 0x9d, 0xee, 0xd6, 0xf1, 0x33, 0x3a, 0x52, 0x75, 0x87, 0xbe, 0x11, 0x92, 0x8a, 0xd9, 0xcb, 0xfa, \ - 0x18, 0x03, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ - 0xf2, 0xad, 0x3b, 0xad, 0xfa, 0x43, 0x13, 0xf0, 0xbd, 0xe4, 0xa0, 0x77, 0x93, 0x18, 0x56, 0xf1, \ - 0xe4, 0xbc, 0x4a, 0x05, 0x08, 0x13, 0x22, 0xdb, 0x55, 0x81, 0xa9, 0x1d, 0x81, 0x7f, 0xf2, 0x10, \ - 0x5e, 0x7f, 0xa7, 0x3d, 0x97, 0x00, 0xc1, 0x96, 0x07, 0x16, 0x87, 0x3c, 0x88, 0xf1, 0x80, 0x45, \ - 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x5d, 0xe9, 0x73, \ - 0xc5, 0x40, 0x26, 0x0a, 0x82, 0x94, 0x29, 0xa9, 0x05, 0xef, 0xcd, 0xf1, 0x7f, 0xe2, 0x25, 0x62, \ - 0x48, 0xfb, 0x0d, 0xc7, 0xc6, 0xa9, 0xb6, 0xc6, 0x16, 0xfb, 0xf2, 0x83, 0x8f, 0x13, 0xc8, 0x0c, \ - 0xfd, 0x7a, 0x00, 0x61, 0xfb, 0x91, 0xf8, 0x8e, 0x49, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, \ - 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0xf2, 0x9c, 0x5d, 0x42, 0xec, 0x81, 0x58, 0x53, \ - 0x55, 0xd1, 0x69, 0x82, 0x38, 0x28, 0xeb, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, \ - 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0xf2, 0xe2, 0xbe, 0xee, 0x99, 0xb8, 0x60, 0xe5, 0xaa, 0x4c, \ - 0x37, 0x2c, 0x3b, 0x56, 0x55, 0xf1, 0x50, 0x68, 0x28, 0x96, 0x39, 0xb1, 0x14, 0xfe, 0xcd, 0xa3, \ - 0xf2, 0xc2, 0xeb, 0xd6, 0xf2, 0xe6, 0xc4, 0xe5, 0xbb, 0x80, 0x5c, 0x08, 0xc1, 0xd9, 0xe9, 0x23, \ - 0xe0, 0x71, 0xea, 0xf1, 0x88, 0x9f, 0xb8, 0x9d, 0x67, 0x14, 0x38, 0x7c, 0xa7, 0x4c, 0x9a, 0xa4, \ - 0x27, 0x19, 0xf2, 0x7a, 0x23, 0x92, 0x10, 0xb1, 0x65, 0x8d, 0xec, 0xa8, 0x1e, 0x14, 0x74, 0xb3, \ - 0x00, 0xf1, 0x7d, 0x1d, 0xfb, 0xcf, 0x78, 0x26, 0x1b, 0x30, 0xf2, 0x0d, 0x1d, 0xad, 0xb0, 0x67, \ - 0xf2, 0xd8, 0xd4, 0x3c, 0x22, 0x95, 0xc1, 0x85, 0xa2, 0x1b, 0x95, 0x91, 0xa7, 0x12, 0x6c, 0xf1, \ - 0xef, 0x03, 0x8b, 0x7b, 0x19, 0x44, 0x8c, 0x9c, 0xe2, 0x7f, 0xa1, 0xc2, 0x68, 0xcd, 0xf2, 0xa0, \ - 0x92, 0x96, 0x4f, 0x6f, 0x76, 0xe3, 0xd6, 0x43, 0x84, 0x6b, 0xa3, 0x6f, 0x9b, 0xf1, 0xa5, 0x80, \ - 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_bead 3116u -const dds_topic_descriptor_t DurableSupport_bead_desc = -{ - .m_size = sizeof (DurableSupport_bead), - .m_align = dds_alignof (DurableSupport_bead), - .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 1u, - .m_typename = "DurableSupport::bead", - .m_keys = DurableSupport_bead_keys, - .m_nops = 40, - .m_ops = DurableSupport_bead_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_bead, .sz = TYPE_INFO_CDR_SZ_DurableSupport_bead }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_bead, .sz = TYPE_MAP_CDR_SZ_DurableSupport_bead } -}; - -static const uint32_t DurableSupport_control_ops [] = -{ - /* control */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_control, id), 16u, - DDS_OP_RTS, - - /* key: id */ - DDS_OP_KOF | 1, 1u /* order: 0 */ -}; - -static const dds_key_descriptor_t DurableSupport_control_keys[1] = -{ - { "id", 5, 0 } -}; - -/* Type Information: - [MINIMAL cb0d133f4534082d16d026f85046] (#deps: 1) - - [MINIMAL 43f53a2be35b432cc735e9431a89] - [COMPLETE 59d57c820de779413f0c29ca47e1] (#deps: 1) - - [COMPLETE aca4d5a256d39713924333e85c6d] -*/ -#define TYPE_INFO_CDR_DurableSupport_control (const unsigned char []){ \ - 0x90, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0xcb, 0x0d, 0x13, 0x3f, 0x45, 0x34, 0x08, 0x2d, 0x16, 0xd0, 0x26, \ - 0xf8, 0x50, 0x46, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x59, 0xd5, 0x7c, \ - 0x82, 0x0d, 0xe7, 0x79, 0x41, 0x3f, 0x0c, 0x29, 0xca, 0x47, 0xe1, 0x00, 0x59, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x40, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_control 148u -#define TYPE_MAP_CDR_DurableSupport_control (const unsigned char []){ \ - 0x76, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0xcb, 0x0d, 0x13, 0x3f, 0x45, 0x34, 0x08, \ - 0x2d, 0x16, 0xd0, 0x26, 0xf8, 0x50, 0x46, 0x00, 0x31, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ - 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0xf2, 0x59, 0xd5, 0x7c, 0x82, 0x0d, 0xe7, 0x79, 0x41, 0x3f, 0x0c, 0x29, \ - 0xca, 0x47, 0xe1, 0x00, 0x55, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, \ - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x00, \ - 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, \ - 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x3c, 0x00, 0x00, 0x00, \ - 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0xf2, 0x59, 0xd5, 0x7c, 0x82, 0x0d, 0xe7, 0x79, 0x41, 0x3f, 0x0c, 0x29, \ - 0xca, 0x47, 0xe1, 0xf1, 0xcb, 0x0d, 0x13, 0x3f, 0x45, 0x34, 0x08, 0x2d, 0x16, 0xd0, 0x26, 0xf8, \ - 0x50, 0x46, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_control 384u -const dds_topic_descriptor_t DurableSupport_control_desc = -{ - .m_size = sizeof (DurableSupport_control), - .m_align = dds_alignof (DurableSupport_control), - .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 1u, - .m_typename = "DurableSupport::control", - .m_keys = DurableSupport_control_keys, - .m_nops = 3, - .m_ops = DurableSupport_control_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_control, .sz = TYPE_INFO_CDR_SZ_DurableSupport_control }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_control, .sz = TYPE_MAP_CDR_SZ_DurableSupport_control } -}; - -static const uint32_t DurableSupport_request_ops [] = -{ - /* request */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_EXT, offsetof (DurableSupport_request, key), (3u << 16u) + 9u /* request_key */, - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request, client), 16u, - DDS_OP_ADR | DDS_OP_TYPE_8BY | DDS_OP_FLAG_SGN, offsetof (DurableSupport_request, timeout), - DDS_OP_RTS, - - /* request_key */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_request_key, rguid), 16u, - DDS_OP_RTS, - - /* key: key.rguid */ - DDS_OP_KOF | 2, 1u /* order: 0 */, 1u /* order: 0 */ -}; - -static const dds_key_descriptor_t DurableSupport_request_keys[1] = -{ - { "key.rguid", 15, 0 } -}; - -/* Type Information: - [MINIMAL 8b9080d97a1a0c3c5aa3da72955b] (#deps: 3) - - [MINIMAL a3976212b3d863bdaaf29cf722d7] - - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 84ce9c3d894c1483f859c00d5927] - [COMPLETE ffa88f3ac66a3c1ea9fb2cc3dcec] (#deps: 3) - - [COMPLETE c4f510554fa6a62cae1437b6364b] - - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE 023df3bd21223779cd1936cef928] -*/ -#define TYPE_INFO_CDR_DurableSupport_request (const unsigned char []){ \ - 0xf0, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x8b, 0x90, 0x80, 0xd9, 0x7a, 0x1a, 0x0c, 0x3c, 0x5a, 0xa3, 0xda, \ - 0x72, 0x95, 0x5b, 0x00, 0x75, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xa3, 0x97, 0x62, 0x12, 0xb3, 0xd8, 0x63, \ - 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, 0x00, 0x35, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, \ - 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, \ - 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xff, 0xa8, 0x8f, \ - 0x3a, 0xc6, 0x6a, 0x3c, 0x1e, 0xa9, 0xfb, 0x2c, 0xc3, 0xdc, 0xec, 0x00, 0xb2, 0x00, 0x00, 0x00, \ - 0x03, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0xc4, 0xf5, 0x10, 0x55, 0x4f, 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, 0x4b, 0x00, \ - 0x60, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ - 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ - 0x39, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_request 244u -#define TYPE_MAP_CDR_DurableSupport_request (const unsigned char []){ \ - 0x1f, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf1, 0x8b, 0x90, 0x80, 0xd9, 0x7a, 0x1a, 0x0c, \ - 0x3c, 0x5a, 0xa3, 0xda, 0x72, 0x95, 0x5b, 0x00, 0x71, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0xa3, 0x97, 0x62, 0x12, 0xb3, \ - 0xd8, 0x63, 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, 0x3c, 0x6e, 0x0b, 0x8a, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x62, 0x60, 0x8e, 0x08, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x84, 0xce, 0x9c, 0x3d, 0x89, \ - 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x90, 0x27, 0x2d, 0xda, 0xf1, 0xa3, 0x97, \ - 0x62, 0x12, 0xb3, 0xd8, 0x63, 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, 0x31, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x43, \ - 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xaf, 0xc4, 0x1d, \ - 0xc3, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, \ - 0x1a, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x84, \ - 0xce, 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27, 0x00, 0x00, 0x00, \ - 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x05, 0x00, 0xd1, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf2, 0xff, 0xa8, 0x8f, \ - 0x3a, 0xc6, 0x6a, 0x3c, 0x1e, 0xa9, 0xfb, 0x2c, 0xc3, 0xdc, 0xec, 0x00, 0xae, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x00, 0x82, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf2, 0xc4, 0xf5, 0x10, 0x55, 0x4f, \ - 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, 0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x02, \ - 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, 0x00, 0x00, \ - 0x08, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0xf2, 0xc4, \ - 0xf5, 0x10, 0x55, 0x4f, 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, 0x4b, 0x00, 0x00, 0x00, \ - 0x5c, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x0a, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x1c, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x00, \ - 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x72, 0x67, 0x75, 0x69, 0x64, 0x00, 0x00, 0x00, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, \ - 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, \ - 0xf2, 0x02, 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0x00, \ - 0x35, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x1b, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x00, 0x00, \ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0xf2, 0xff, 0xa8, 0x8f, 0x3a, 0xc6, 0x6a, 0x3c, 0x1e, 0xa9, 0xfb, 0x2c, \ - 0xc3, 0xdc, 0xec, 0xf1, 0x8b, 0x90, 0x80, 0xd9, 0x7a, 0x1a, 0x0c, 0x3c, 0x5a, 0xa3, 0xda, 0x72, \ - 0x95, 0x5b, 0xf2, 0xc4, 0xf5, 0x10, 0x55, 0x4f, 0xa6, 0xa6, 0x2c, 0xae, 0x14, 0x37, 0xb6, 0x36, \ - 0x4b, 0xf1, 0xa3, 0x97, 0x62, 0x12, 0xb3, 0xd8, 0x63, 0xbd, 0xaa, 0xf2, 0x9c, 0xf7, 0x22, 0xd7, \ - 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, \ - 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x02, \ - 0x3d, 0xf3, 0xbd, 0x21, 0x22, 0x37, 0x79, 0xcd, 0x19, 0x36, 0xce, 0xf9, 0x28, 0xf1, 0x84, 0xce, \ - 0x9c, 0x3d, 0x89, 0x4c, 0x14, 0x83, 0xf8, 0x59, 0xc0, 0x0d, 0x59, 0x27\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_request 892u -const dds_topic_descriptor_t DurableSupport_request_desc = -{ - .m_size = sizeof (DurableSupport_request), - .m_align = dds_alignof (DurableSupport_request), - .m_flagset = DDS_TOPIC_FIXED_SIZE | DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 1u, - .m_typename = "DurableSupport::request", - .m_keys = DurableSupport_request_keys, - .m_nops = 8, - .m_ops = DurableSupport_request_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_request, .sz = TYPE_INFO_CDR_SZ_DurableSupport_request }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_request, .sz = TYPE_MAP_CDR_SZ_DurableSupport_request } -}; - -static const uint32_t DurableSupport_response_ops [] = -{ - /* response */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_response, id), 16u, - DDS_OP_ADR | DDS_OP_TYPE_EXT, offsetof (DurableSupport_response, body), (3u << 16u) + 4u /* response_content */, - DDS_OP_RTS, - - /* response_content */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_FLAG_MU | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_2BY, offsetof (DurableSupport_response_content, _d), 2u, (12u << 16u) + 4u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 9 /* response_set_t */, 1, offsetof (DurableSupport_response_content, _u.set), 0u, - DDS_OP_JEQ4 | DDS_OP_TYPE_STU | 25 /* response_data_t */, 2, offsetof (DurableSupport_response_content, _u.data), 0u, - DDS_OP_RTS, - - /* response_set_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_8BY, offsetof (DurableSupport_response_set_t, delivery_id), - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_ARR, offsetof (DurableSupport_response_set_t, guids), sizeof (DurableSupport_id_t), (8u << 16u) + 4u, - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, 0u, 16u, - DDS_OP_RTS, - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, partition), - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, tpname), - DDS_OP_ADR | DDS_OP_TYPE_STR, offsetof (DurableSupport_response_set_t, type_id), - DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (DurableSupport_response_set_t, flags), - DDS_OP_RTS, - - /* response_data_t */ - DDS_OP_DLC, - DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (DurableSupport_response_data_t, blob), - DDS_OP_RTS, - - /* key: id */ - DDS_OP_KOF | 1, 1u /* order: 0 */ -}; - -static const dds_key_descriptor_t DurableSupport_response_keys[1] = -{ - { "id", 46, 0 } -}; - -/* Type Information: - [MINIMAL afe8255284083dabd3ddf2d54e74] (#deps: 6) - - [MINIMAL 43f53a2be35b432cc735e9431a89] - - [MINIMAL 98ce0230d0ff9c4c40cabb2d52c3] - - [MINIMAL 80455e796dd3437163cb532089da] - - [MINIMAL e78d987aa9597510bc0942813b1e] - - [MINIMAL d8398b259af5a04792e296996c27] - - [MINIMAL a580b28d8a19d4a49d2794aae844] - [COMPLETE 96afe9e7626475acdc5483ed4445] (#deps: 6) - - [COMPLETE aca4d5a256d39713924333e85c6d] - - [COMPLETE 32546bec8365219448f85d5a510d] - - [COMPLETE eec1bad6badde73f40ef199fedcc] - - [COMPLETE 5af9ae0c63928c6db71150e723db] - - [COMPLETE 7b005a124ff7bda9c39eb4003556] - - [COMPLETE 008875599776c39ce0c1fe897846] -*/ -#define TYPE_INFO_CDR_DurableSupport_response (const unsigned char []){ \ - 0x80, 0x01, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf1, 0xaf, 0xe8, 0x25, 0x52, 0x84, 0x08, 0x3d, 0xab, 0xd3, 0xdd, 0xf2, \ - 0xd5, 0x4e, 0x74, 0x00, 0x55, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, \ - 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, 0xff, 0x9c, 0x4c, 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0x00, \ - 0x7c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ - 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xe7, 0x8d, 0x98, 0x7a, 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, 0x3b, 0x1e, 0x00, \ - 0x9b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, \ - 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, \ - 0x2c, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0xb8, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, \ - 0x14, 0x00, 0x00, 0x00, 0xf2, 0x96, 0xaf, 0xe9, 0xe7, 0x62, 0x64, 0x75, 0xac, 0xdc, 0x54, 0x83, \ - 0xed, 0x44, 0x45, 0x00, 0x87, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, \ - 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x40, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, 0x65, 0x21, 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0x00, \ - 0xb7, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, \ - 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x5a, 0xf9, 0xae, 0x0c, 0x63, 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, 0xe7, 0x23, 0xdb, 0x00, \ - 0x04, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, \ - 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, \ - 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, \ - 0x57, 0x00, 0x00, 0x00\ -} -#define TYPE_INFO_CDR_SZ_DurableSupport_response 388u -#define TYPE_MAP_CDR_DurableSupport_response (const unsigned char []){ \ - 0x54, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf1, 0xaf, 0xe8, 0x25, 0x52, 0x84, 0x08, 0x3d, \ - 0xab, 0xd3, 0xdd, 0xf2, 0xd5, 0x4e, 0x74, 0x00, 0x51, 0x00, 0x00, 0x00, 0xf1, 0x51, 0x02, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, \ - 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xb8, 0x0b, 0xb7, 0x74, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, \ - 0xff, 0x9c, 0x4c, 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0x84, 0x1a, 0x2d, 0x68, 0xf1, 0x43, 0xf5, \ - 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0x1a, 0x00, 0x00, 0x00, \ - 0xf1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, \ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, \ - 0xff, 0x9c, 0x4c, 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, \ - 0xf1, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf1, 0x80, \ - 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x00, 0x00, \ - 0x54, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf1, 0xe7, 0x8d, 0x98, 0x7a, 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, 0x3b, \ - 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xcd, 0xae, 0xee, 0xba, \ - 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, 0x8a, \ - 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x8d, 0x77, 0x7f, 0x38, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, \ - 0x71, 0x63, 0xcb, 0x53, 0x20, 0x89, 0xda, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf1, 0xe7, 0x8d, 0x98, 0x7a, \ - 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, 0x3b, 0x1e, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, \ - 0x06, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf1, 0xd8, \ - 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x7c, 0x4b, 0x99, \ - 0xfe, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf1, \ - 0x01, 0x00, 0x00, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, \ - 0x1a, 0x89, 0x0d, 0x36, 0x32, 0x3f, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x70, 0x00, 0x70, 0x13, 0xba, 0x9b, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x70, 0x00, 0x7e, 0x75, 0xc0, 0xed, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x70, 0x00, 0x94, 0x75, 0x7c, 0xae, 0x0b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x07, 0x4e, 0x58, 0x68, 0xd6, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, \ - 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0xa5, 0x80, 0xb2, 0x8d, \ - 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, \ - 0xf1, 0x51, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, \ - 0x01, 0x00, 0x00, 0x02, 0xee, 0x26, 0x90, 0x8b, 0xc7, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0xf2, 0x96, 0xaf, 0xe9, 0xe7, 0x62, 0x64, 0x75, 0xac, 0xdc, 0x54, 0x83, 0xed, 0x44, 0x45, 0x00, \ - 0x83, 0x00, 0x00, 0x00, 0xf2, 0x51, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x19, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, \ - 0x53, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x31, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, \ - 0x6d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, \ - 0x65, 0x21, 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x62, 0x6f, 0x64, 0x79, 0x00, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ - 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, \ - 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x69, 0x64, 0x5f, 0x74, \ - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, 0x65, 0x21, \ - 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xf2, 0x52, 0x0a, 0x00, \ - 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, \ - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, \ - 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, \ - 0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ - 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, \ - 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x5a, 0xf9, 0xae, 0x0c, 0x63, \ - 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, 0xe7, 0x23, 0xdb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, \ - 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0xf2, \ - 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, 0xef, 0x19, 0x9f, 0xed, 0xcc, 0x00, 0x00, \ - 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, \ - 0x5f, 0x74, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xf2, 0x5a, 0xf9, \ - 0xae, 0x0c, 0x63, 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, 0xe7, 0x23, 0xdb, 0x00, 0x01, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x00, 0x00, \ - 0xcc, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, \ - 0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, \ - 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf2, 0x01, 0x00, 0x00, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, 0xd3, 0x97, 0x13, \ - 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x67, 0x75, 0x69, 0x64, \ - 0x73, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, \ - 0x0a, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, \ - 0x15, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x00, \ - 0x74, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, \ - 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, \ - 0x5f, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, 0x00, \ - 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, 0x56, 0x00, \ - 0x39, 0x00, 0x00, 0x00, 0xf2, 0x30, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x1e, 0x00, 0x00, 0x00, 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, \ - 0x72, 0x74, 0x3a, 0x3a, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x5f, \ - 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xf2, 0x00, 0x88, \ - 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0x53, 0x00, 0x00, 0x00, \ - 0xf2, 0x51, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, \ - 0x44, 0x75, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x3a, \ - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x00, \ - 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x6f, 0x62, \ - 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf2, 0x96, 0xaf, 0xe9, \ - 0xe7, 0x62, 0x64, 0x75, 0xac, 0xdc, 0x54, 0x83, 0xed, 0x44, 0x45, 0xf1, 0xaf, 0xe8, 0x25, 0x52, \ - 0x84, 0x08, 0x3d, 0xab, 0xd3, 0xdd, 0xf2, 0xd5, 0x4e, 0x74, 0xf2, 0xac, 0xa4, 0xd5, 0xa2, 0x56, \ - 0xd3, 0x97, 0x13, 0x92, 0x43, 0x33, 0xe8, 0x5c, 0x6d, 0xf1, 0x43, 0xf5, 0x3a, 0x2b, 0xe3, 0x5b, \ - 0x43, 0x2c, 0xc7, 0x35, 0xe9, 0x43, 0x1a, 0x89, 0xf2, 0x32, 0x54, 0x6b, 0xec, 0x83, 0x65, 0x21, \ - 0x94, 0x48, 0xf8, 0x5d, 0x5a, 0x51, 0x0d, 0xf1, 0x98, 0xce, 0x02, 0x30, 0xd0, 0xff, 0x9c, 0x4c, \ - 0x40, 0xca, 0xbb, 0x2d, 0x52, 0xc3, 0xf2, 0xee, 0xc1, 0xba, 0xd6, 0xba, 0xdd, 0xe7, 0x3f, 0x40, \ - 0xef, 0x19, 0x9f, 0xed, 0xcc, 0xf1, 0x80, 0x45, 0x5e, 0x79, 0x6d, 0xd3, 0x43, 0x71, 0x63, 0xcb, \ - 0x53, 0x20, 0x89, 0xda, 0xf2, 0x5a, 0xf9, 0xae, 0x0c, 0x63, 0x92, 0x8c, 0x6d, 0xb7, 0x11, 0x50, \ - 0xe7, 0x23, 0xdb, 0xf1, 0xe7, 0x8d, 0x98, 0x7a, 0xa9, 0x59, 0x75, 0x10, 0xbc, 0x09, 0x42, 0x81, \ - 0x3b, 0x1e, 0xf2, 0x7b, 0x00, 0x5a, 0x12, 0x4f, 0xf7, 0xbd, 0xa9, 0xc3, 0x9e, 0xb4, 0x00, 0x35, \ - 0x56, 0xf1, 0xd8, 0x39, 0x8b, 0x25, 0x9a, 0xf5, 0xa0, 0x47, 0x92, 0xe2, 0x96, 0x99, 0x6c, 0x27, \ - 0xf2, 0x00, 0x88, 0x75, 0x59, 0x97, 0x76, 0xc3, 0x9c, 0xe0, 0xc1, 0xfe, 0x89, 0x78, 0x46, 0xf1, \ - 0xa5, 0x80, 0xb2, 0x8d, 0x8a, 0x19, 0xd4, 0xa4, 0x9d, 0x27, 0x94, 0xaa, 0xe8, 0x44\ -} -#define TYPE_MAP_CDR_SZ_DurableSupport_response 1790u -const dds_topic_descriptor_t DurableSupport_response_desc = -{ - .m_size = sizeof (DurableSupport_response), - .m_align = dds_alignof (DurableSupport_response), - .m_flagset = DDS_TOPIC_XTYPES_METADATA, - .m_nkeys = 1u, - .m_typename = "DurableSupport::response", - .m_keys = DurableSupport_response_keys, - .m_nops = 22, - .m_ops = DurableSupport_response_ops, - .m_meta = "", - .type_information = { .data = TYPE_INFO_CDR_DurableSupport_response, .sz = TYPE_INFO_CDR_SZ_DurableSupport_response }, - .type_mapping = { .data = TYPE_MAP_CDR_DurableSupport_response, .sz = TYPE_MAP_CDR_SZ_DurableSupport_response } -}; diff --git a/src/durability/src/durablesupport.idl b/src/durability/src/durablesupport.idl new file mode 100644 index 0000000000..0e4d949512 --- /dev/null +++ b/src/durability/src/durablesupport.idl @@ -0,0 +1,71 @@ +module DurableSupport { + /******************** + * Generic + ********************/ + + /* generic typedef to identify ds services and writers; GUID compatible */ + typedef octet id_t[16]; + + @appendable + struct status { + @key id_t id; /* system wide unique service identifier */ + string hostname; /* name of the host where this ds is deployed */ + string name; /* human readable and user defined identification */ + }; + + /******************** + * Durable client + ********************/ + + /* duration */ + typedef long long duration_t; + + /* Type discriminator for responses */ + typedef unsigned short responsetype_t; + + /* delivery id to identify the delivery session */ + typedef unsigned long long delivery_id_t; + + @appendable @nested + struct request_key { + id_t rguid; /* the guid of the reader */ + }; + + @appendable + struct request { + @key request_key key; /* the key of the request topic */ + id_t client; /* the client expressing interest in historical data for this reader */ + duration_t timeout; /* optional maximum duration the client issuing the request expects to start receiving an answer. */ + }; + + /* List of supported response types */ + const responsetype_t RESPONSETYPE_SET = 1; + const responsetype_t RESPONSETYPE_DATA = 2; + + @appendable @nested + struct response_set_t { + delivery_id_t delivery_id; /* identification of the delivery; increases monotonically per set */ + sequence guids; /* the reader guids for which this set is intended */ + string partition; /* partition of this set */ + string tpname; /* topic name of this set */ + string type_id; /* type identification of this set */ + unsigned long flags; /* flags for this set */ + }; + + @appendable @nested + struct response_data_t { + sequence blob; + }; + + @appendable @nested + union response_content switch (responsetype_t) { + case RESPONSETYPE_SET : response_set_t set; + case RESPONSETYPE_DATA: response_data_t data; + }; + + @appendable + struct response { + @key id_t id; /* identification of the ds that produces this response */ + response_content body; + }; +}; From 6bd38164c2d66e733ad3044f994899e230030ba7 Mon Sep 17 00:00:00 2001 From: TheFixer Date: Mon, 22 Jul 2024 16:47:30 +0200 Subject: [PATCH 206/207] Implement wfhd Signed-off-by: TheFixer --- src/core/ddsc/src/dds__types.h | 4 + src/core/ddsc/src/dds_reader.c | 17 +- .../dds/durability/dds_durability_public.h | 5 +- src/durability/src/dds_durability.c | 203 ++++++++++++++---- src/durability/src/durablesupport.idl | 29 ++- 5 files changed, 210 insertions(+), 48 deletions(-) diff --git a/src/core/ddsc/src/dds__types.h b/src/core/ddsc/src/dds__types.h index f42d7d53a5..6186ec7cb1 100644 --- a/src/core/ddsc/src/dds__types.h +++ b/src/core/ddsc/src/dds__types.h @@ -397,6 +397,10 @@ typedef struct dds_reader { struct dds_loan_pool *m_loans; /* administration of outstanding loans */ struct dds_loan_pool *m_heap_loan_cache; + /* Mutex and condition variable for wfhd; only available for readers */ + ddsrt_mutex_t wfhd_mutex; + ddsrt_cond_t wfhd_cond; + /* Status metrics */ dds_sample_rejected_status_t m_sample_rejected_status; dds_liveliness_changed_status_t m_liveliness_changed_status; diff --git a/src/core/ddsc/src/dds_reader.c b/src/core/ddsc/src/dds_reader.c index be27126a57..0a792ee677 100644 --- a/src/core/ddsc/src/dds_reader.c +++ b/src/core/ddsc/src/dds_reader.c @@ -91,6 +91,11 @@ static dds_return_t dds_reader_delete (dds_entity *e) dds_rhc_free (rd->m_rhc); ddsi_thread_state_asleep (ddsi_lookup_thread_state ()); + // Destroy mutex and condition variable for wfhd + // LH: Not sure if this is the right spot to destroy + ddsrt_mutex_destroy(&rd->wfhd_mutex); + ddsrt_cond_destroy(&rd->wfhd_cond); + dds_loan_pool_free (rd->m_heap_loan_cache); dds_loan_pool_free (rd->m_loans); @@ -713,6 +718,10 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe // Ownership of rqos is transferred to reader entity own_rqos = false; + // Initialize mutex and condition variable for wfhd + ddsrt_mutex_init (&rd->wfhd_mutex); + ddsrt_cond_init (&rd->wfhd_cond); + // assume DATA_ON_READERS is materialized in the subscriber: // - changes to it won't be propagated to this reader until after it has been added to the subscriber's children // - data can arrive once `new_reader` is called, requiring raising DATA_ON_READERS if materialized @@ -963,7 +972,9 @@ dds_return_t dds_reader_wait_for_historical_data (dds_entity_t reader, dds_durat dds_reader *rd; dds_return_t ret; (void) max_wait; - if ((ret = dds_reader_lock (reader, &rd)) != DDS_RETCODE_OK) + bool call_wfhd = false; + + if ((ret = dds_reader_lock(reader, &rd)) != DDS_RETCODE_OK) return ret; switch (rd->m_entity.m_qos->durability.kind) { @@ -974,9 +985,13 @@ dds_return_t dds_reader_wait_for_historical_data (dds_entity_t reader, dds_durat break; case DDS_DURABILITY_TRANSIENT: case DDS_DURABILITY_PERSISTENT: + call_wfhd = true; break; } dds_reader_unlock(rd); + if (call_wfhd) { + ret = rd->m_entity.m_domain->dc.dds_durability_wait_for_historical_data(reader, max_wait); + } return ret; } diff --git a/src/durability/include/dds/durability/dds_durability_public.h b/src/durability/include/dds/durability/dds_durability_public.h index e990cba38b..97c2690973 100644 --- a/src/durability/include/dds/durability/dds_durability_public.h +++ b/src/durability/include/dds/durability/dds_durability_public.h @@ -19,7 +19,7 @@ extern "C" { #endif -typedef struct dds_durability{ +typedef struct dds_durability { ddsrt_dynlib_t lib_handle; dds_return_t (*dds_durability_init) (const dds_domainid_t domain, struct ddsi_domaingv *gv); dds_entity_t (*_dds_durability_fini) (void); @@ -27,8 +27,9 @@ typedef struct dds_durability{ dds_return_t (*dds_durability_new_local_reader) (dds_entity_t reader, struct dds_rhc *rhc); dds_return_t (*dds_durability_new_local_writer) (dds_entity_t writer); dds_return_t (*dds_durability_wait_for_quorum) (dds_entity_t writer); + dds_return_t (*dds_durability_wait_for_historical_data) (dds_entity_t reader, dds_duration_t max_wait); bool (*dds_durability_is_terminating) (void); -}dds_durability_t; +} dds_durability_t; void dds_durability_fini (dds_durability_t* dc); dds_return_t dds_durability_load (dds_durability_t* dc, const struct ddsi_domaingv* gv); diff --git a/src/durability/src/dds_durability.c b/src/durability/src/dds_durability.c index e6eaa4feec..cd70f8423e 100644 --- a/src/durability/src/dds_durability.c +++ b/src/durability/src/dds_durability.c @@ -17,12 +17,15 @@ #include "dds/ddsrt/heap.h" #include "dds/ddsrt/threads.h" #include "dds/ddsrt/log.h" +#include "dds/ddsrt/avl.h" #include "ddsc/dds.h" #include "../src/dds__writer.h" +#include "../src/dds__reader.h" #include "dds/ddsi/ddsi_endpoint.h" #include "dds/ddsrt/avl.h" #include "dds/ddsi/ddsi_serdata.h" #include "dds/ddsi/ddsi_typelib.h" +#include "dds/ddsi/ddsi_entity_index.h" #include #define DEFAULT_QOURUM 1 @@ -60,6 +63,8 @@ static char *dc_responsetype_image (DurableSupport_responsetype_t type) switch (type) { case DurableSupport_RESPONSETYPE_SET: return "set"; + case DurableSupport_RESPONSETYPE_READER: + return "reader"; case DurableSupport_RESPONSETYPE_DATA: return "data"; default: @@ -281,6 +286,33 @@ static int dc_stringify_response_set (char *buf, size_t n, const DurableSupport_ return -1; } +static int dc_stringify_response_reader (char *buf, size_t n, const DurableSupport_response_reader_t *response_reader) +{ + size_t i = 0; + int l; + char id_str[37]; + + if (buf == NULL) { + goto err; + } + if (response_reader == NULL) { + buf[0] = '\0'; + return 0; + } + if ((l = snprintf(buf+i, n-i, "{\"rguid\":\"%s\"}" , dc_stringify_id(response_reader->rguid, id_str))) < 0) { + goto err; + } + i += (size_t)l; + if (i >= n) { + /* truncated */ + buf[n-1] = '\0'; + } + return (int)i; +err: + DDS_ERROR("dc_stringify_response_reader failed"); + return -1; +} + static int dc_stringify_response_data (char *buf, size_t n, const DurableSupport_response_data_t *response_data) { size_t i = 0; @@ -345,6 +377,12 @@ static int dc_stringify_response (char *buf, size_t n, const DurableSupport_resp } i += (size_t)l; break; + case DurableSupport_RESPONSETYPE_READER : + if ((l = dc_stringify_response_reader(buf+i, n-i, &response->body._u.reader)) < 0) { + goto err; + } + i += (size_t)l; + break; case DurableSupport_RESPONSETYPE_DATA : if ((l = dc_stringify_response_data(buf+i, n-i, &response->body._u.data)) < 0) { goto err; @@ -398,7 +436,7 @@ struct delivery_reader_key_t { }; struct delivery_reader_t { - ddsrt_avl_node_t node; /* represents a node in the tree of delivery reader */ + ddsrt_avl_node_t node; /* represents a node in the tree of readers for which there is a delivery pending */ struct delivery_reader_key_t key; /* key of a delivery reader */ }; @@ -412,8 +450,8 @@ static int cmp_delivery_reader (const void *a, const void *b) static void cleanup_delivery_reader (void *n) { - struct delivery_reader_t *rd = (struct delivery_reader_t *)n; - ddsrt_free(rd); + struct delivery_reader_t *dr = (struct delivery_reader_t *)n; + ddsrt_free(dr); } static const ddsrt_avl_ctreedef_t delivery_readers_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct delivery_reader_t, node), offsetof (struct delivery_reader_t, key), cmp_delivery_reader, 0); @@ -493,7 +531,7 @@ static int dc_stringify_delivery_request (char *buf, size_t n, const struct deli if (i >= n) { goto trunc; } - if ((l = snprintf(buf+i, n-i, ", \", reader\":%" PRId32, dr->reader)) < 0) { + if ((l = snprintf(buf+i, n-i, ", \"reader\":%" PRId32, dr->reader)) < 0) { goto err; } i += (size_t)l; @@ -556,12 +594,11 @@ static const ddsrt_avl_ctreedef_t delivery_requests_td = DDSRT_AVL_CTREEDEF_INIT static const ddsrt_fibheap_def_t delivery_requests_fd = DDSRT_FIBHEAPDEF_INITIALIZER(offsetof (struct delivery_request_t, fhnode), cmp_exp_time); - struct delivery_ctx_t { ddsrt_avl_node_t node; DurableSupport_id_t id; /* id of the ds that delivers the data; key of the delivery context */ uint64_t delivery_id; /* the id of the delivery by this ds; this is a monotonic increased sequence number */ - ddsrt_avl_ctree_t readers; /* tree of reader guids for which this delivery is intended */ + ddsrt_avl_ctree_t readers; /* tree of reader guids for which this delivery is intended; populated when a delivery is opened */ }; static int dc_stringify_delivery_ctx (char *buf, size_t n, const struct delivery_ctx_t *delivery_ctx) @@ -626,7 +663,7 @@ static void cleanup_delivery_ctx (void *n) static const ddsrt_avl_ctreedef_t delivery_ctx_td = DDSRT_AVL_CTREEDEF_INITIALIZER(offsetof (struct delivery_ctx_t, node), offsetof (struct delivery_ctx_t, id), delivery_ctx_cmp, 0); -/* Administration to keep track of the request readers of a ds +/* Administration to keep track of the request readers of a DS * that can act as a target to send requests for historical data to.. * Based on this administration requests for historical data are published immediately, * or pending until a ds is found that matches. */ @@ -709,7 +746,7 @@ struct dc_t { ddsrt_mutex_t delivery_request_mutex; /* delivery request queue mutex */ ddsrt_cond_t delivery_request_cond; /* delivery request condition */ dds_instance_handle_t selected_request_reader_ih; /* instance handle to matched request reader, DDS_HANDLE_NIL if not available */ - ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on a ds that match with my request writer */ + ddsrt_avl_ctree_t matched_request_readers; /* tree containing the request readers on DSs that match with my request writer */ uint32_t nr_of_matched_dc_requests; /* indicates the number of matched dc_request readers for the dc_request writer of this client */ struct delivery_ctx_t *delivery_ctx; /* reference to current delivery context, NULL if none */ ddsrt_avl_ctree_t delivery_ctxs; /* table of delivery contexts, keyed by ds id */ @@ -1420,7 +1457,7 @@ static dds_return_t dc_com_request_write (struct com_t *com, const dds_guid_t rg request = DurableSupport_request__alloc(); memcpy(request->key.rguid, rguid.v, 16); memcpy(request->client, dc.cfg.id, 16); - request->timeout = DDS_INFINITY; + request->timeout = DDS_INFINITY; /* currently not used */ l = dc_stringify_request(str, sizeof(str), request, true); assert(l > 0); len = (size_t)l; @@ -1518,6 +1555,7 @@ static struct delivery_ctx_t *dc_get_delivery_ctx (struct dc_t *dc, DurableSuppo delivery_ctx = dc->delivery_ctx; } else if (((delivery_ctx = ddsrt_avl_clookup (&delivery_ctx_td, &dc->delivery_ctxs, id)) == NULL) && autocreate) { delivery_ctx = ddsrt_malloc(sizeof(struct delivery_ctx_t)); + memset(delivery_ctx, 0, sizeof(struct delivery_ctx_t)); memcpy(delivery_ctx->id,id,16); ddsrt_avl_cinit(&delivery_readers_td, &delivery_ctx->readers); ddsrt_avl_cinsert(&delivery_ctx_td, &dc->delivery_ctxs, delivery_ctx); @@ -1564,7 +1602,38 @@ static struct delivery_reader_t *dc_get_reader_from_delivery_ctx (struct deliver return delivery_reader; } -/* close the current delivery context for the ds identified by id */ +static void unblock_wfhd_for_reader (struct dc_t *dc, dds_entity_t reader) +{ + dds_entity *e; + dds_reader *rd; + dds_return_t rc; + dds_guid_t rguid; + char id_str[37]; + + if ((rc = dds_entity_lock (reader, DDS_KIND_READER, &e)) != DDS_RETCODE_OK) { + /* The reader could not be found, it may have been deleted. + * Since this is legitimate, we silently return from this function. */ + return; + } + if ((rc = dds_get_guid(reader, &rguid)) != DDS_RETCODE_OK) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "failed to retrieve reader guid for reader with handle %" PRId32 "\n", reader); + goto err_get_guid; + } + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "unblock wfhd for reader \"%s\"\n", dc_stringify_id(rguid.v, id_str)); + rd = (dds_reader *)e; + /* unblock wfhd for this reader */ + ddsrt_mutex_lock(&rd->wfhd_mutex); + ddsrt_cond_broadcast(&rd->wfhd_cond); + ddsrt_mutex_unlock(&rd->wfhd_mutex); + dds_entity_unlock(e); + return; + +err_get_guid: + dds_entity_unlock(e); + return; +} + +/* Close the current delivery context for the ds identified by id */ static void dc_close_delivery (struct dc_t *dc, DurableSupport_id_t id, DurableSupport_response_set_t *response_set) { char id_str[37]; @@ -1572,13 +1641,14 @@ static void dc_close_delivery (struct dc_t *dc, DurableSupport_id_t id, DurableS assert(response_set); assert(response_set->flags & DC_FLAG_SET_END); - /* lookup the align context for this aligner */ + (void)response_set; /* to silence the compiler for release builds */ + /* Lookup the delivery context for this aligner */ if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, id, false)) == NULL) { - /* There exists a delivery context for the ds that produced the response. */ + /* There does not exists a delivery context for the DS that produced the response. */ DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "unable to close delivery for ds \"%s\"\n", dc_stringify_id(id, id_str)); return; } - /* there exists a delivery context for the ds identified by id, close this delivery context */ + /* There exists a delivery context for the ds identified by id, close this delivery context */ (void)dc_stringify_delivery_ctx(str, sizeof(str), dc->delivery_ctx); DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "close delivery %s\n", str); /* remove current delivery ctx */ @@ -1666,20 +1736,39 @@ static void dc_process_set_response_begin(struct dc_t *dc, DurableSupport_respon static void dc_process_set_response_end (struct dc_t *dc, DurableSupport_response *response) { + char id_str[37]; + assert(response); assert(response->body._d == DurableSupport_RESPONSETYPE_SET); - dc_close_delivery(dc, response->id, &response->body._u.set); + if ((dc->delivery_ctx = dc_get_delivery_ctx(dc, response->id, false)) != NULL) { + assert(memcmp(dc->delivery_ctx->id, response->id, 16) == 0); + /* There exists an open delivery from the DS. + * Now check if end delivery id corresponds to the open delivery id. */ + if (dc->delivery_ctx->delivery_id != response->body._u.set.delivery_id) { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "current open delivery %" PRIu64 " does not match with end delivery %" PRIu64 "\n", dc->delivery_ctx->delivery_id, response->body._u.set.delivery_id); + /* abort the currently open delivery */ + dc_abort_delivery(dc, dc->delivery_ctx->id, &response->body._u.set); + } + dc_close_delivery(dc, response->id, &response->body._u.set); + } else { + DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "unable to close delivery %" PRIu64 " from ds \"%s\"\n", response->body._u.set.delivery_id, dc_stringify_id(response->id, id_str)); + } } -static void dc_process_set_response_not_found(struct dc_t *dc, DurableSupport_response *response) +static void dc_process_reader_response (struct dc_t *dc, DurableSupport_response *response) { - /* the set indicated in the response does not exist at the ds. - * This can for example happen when a transient reader has been created, - * but no transient writer exists. In such cases we can mark the reader - * as complete. - */ - DC_UNUSED_ARG(dc); - DC_UNUSED_ARG(response); + struct delivery_request_key_t key; + struct delivery_request_t *dr; + ddsrt_avl_dpath_t dpath; + + assert(response); + assert(response->body._d == DurableSupport_RESPONSETYPE_READER); + memcpy(key.guid.v, response->body._u.reader.rguid, 16); + /* Lookup if there is a delivery request for this reader. + * If so, unblock the reader. */ + if ((dr = ddsrt_avl_clookup_dpath(&delivery_requests_td, &dc->delivery_requests, &key, &dpath)) != NULL) { + unblock_wfhd_for_reader(dc, dr->reader); + } } static void dc_process_set_response (struct dc_t *dc, DurableSupport_response *response) @@ -1689,8 +1778,6 @@ static void dc_process_set_response (struct dc_t *dc, DurableSupport_response *r dc_process_set_response_begin(dc, response); } else if (response->body._u.set.flags & DC_FLAG_SET_END) { dc_process_set_response_end(dc, response); - } else if (response->body._u.set.flags & DC_FLAG_SET_NOT_FOUND) { - dc_process_set_response_not_found(dc, response); } else { DDS_ERROR("invalid response set flag 0x%04" PRIx32, response->body._u.set.flags); } @@ -1778,7 +1865,7 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * data_out.iov_base = response->body._u.data.blob._buffer + serdata_offset; /* Now deliver the data to the local readers. */ for (delivery_reader = ddsrt_avl_citer_first (&delivery_readers_td, &dc->delivery_ctx->readers, &it); delivery_reader; delivery_reader = ddsrt_avl_citer_next (&it)) { - /* take the guid and lookup the reader entity that requested the delivery */ + /* Lookup the reader entity that requested the delivery. */ /* check if the reader still exists by lookup the entity */ struct delivery_request_t *dr; struct delivery_request_key_t key; @@ -1796,9 +1883,9 @@ static void dc_process_data_response (struct dc_t *dc, DurableSupport_response * /* in order to insert the data in the rhc of the reader we first * need to resolve the type of the reader */ if ((ret = dds_get_entity_sertype (reader, &sertype)) < 0) { - /* We failed to get the sertype of the reader., so we cannot + /* We failed to get the sertype of the reader. * This could be because the reader does not exist any more, - * but frankly I don't about the reason. All that matters is + * but frankly I don't care about the reason. All that matters is * that we cannot inject data into the rhc of this reader. */ continue; } @@ -1860,6 +1947,9 @@ static int dc_process_response (dds_entity_t rd, struct dc_t *dc) case DurableSupport_RESPONSETYPE_SET: dc_process_set_response(dc, response); break; + case DurableSupport_RESPONSETYPE_READER: + dc_process_reader_response(dc, response); + break; case DurableSupport_RESPONSETYPE_DATA: dc_process_data_response(dc, response); break; @@ -1884,6 +1974,9 @@ static void dc_delete_delivery_request (struct dc_t *dc, dds_guid_t rguid) memcpy(key.guid.v, rguid.v, 16); if ((dr = ddsrt_avl_clookup_dpath (&delivery_requests_td, &dc->delivery_requests, &key, &dpath)) != NULL) { + /* remove from fibheap */ + ddsrt_fibheap_delete(&delivery_requests_fd, &dc->delivery_requests_fh, dr); + /* remove from delivery requests */ ddsrt_avl_cdelete_dpath(&delivery_requests_td, &dc->delivery_requests, dr, &dpath); (void)dc_stringify_delivery_request(dr_str, sizeof(dr_str), dr); DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "delete delivery request %s\n", dr_str); @@ -1902,7 +1995,7 @@ static struct delivery_request_t *dc_insert_delivery_request (struct dc_t *dc, d memcpy(key.guid.v, rguid.v, 16); if ((dr = ddsrt_avl_clookup_ipath (&delivery_requests_td, &dc->delivery_requests, &key, &ipath)) == NULL) { dr = ddsrt_malloc(sizeof(struct delivery_request_t)); - memcpy(dr->key.guid.v, rguid.v, 16); + memcpy(dr->key.guid.v, key.guid.v, 16); dr->reader = reader; dr->exp_time = DDS_NEVER; (void)dc_stringify_delivery_request(dr_str, sizeof(dr_str), dr); @@ -1929,7 +2022,7 @@ static void dc_send_request_for_reader (struct dc_t *dc, dds_entity_t reader, st DDS_ERROR("Unable to retrieve the guid of the reader [%s]", dds_strretcode(-rc)); goto err_get_guid; } - /* Administrate the outstanding request. + /* Remember the delivery request for this reader. * This is used a.o. to correlate reader guids to actual readers. */ dc_insert_delivery_request(dc, reader, rguid); /* Publish the quest */ @@ -1990,7 +2083,6 @@ static void dc_dispose_delivery_request (struct dc_t *dc, struct delivery_reques char id_str[37]; DC_UNUSED_ARG(dr); - /* create a dummy request containing the reader guid that */ memcpy(request.key.rguid, dr->key.guid.v, 16); if ((ih = dds_lookup_instance(dc->com->wr_request, &request)) == DDS_HANDLE_NIL) { DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "no delivery request for reader \"%s\" found, unable to dispose\n", dc_stringify_id(request.key.rguid, id_str)); @@ -2000,7 +2092,6 @@ static void dc_dispose_delivery_request (struct dc_t *dc, struct delivery_reques DDS_ERROR("failed to dispose delivery request for reader \"%s\" [%s]\n", dc_stringify_id(request.key.rguid, id_str), dds_strretcode(-rc)); goto err_dispose_delivery_request; } - /* LH: todo: use dc_stringify_request, but only print the keys */ DDS_CLOG(DDS_LC_DUR, &dc->gv->logconfig, "dispose delivery request for reader \"%s\"\n", dc_stringify_id(request.key.rguid, id_str)); err_dispose_delivery_request: return; @@ -2062,7 +2153,7 @@ static void default_request_writer_matched_cb (dds_entity_t writer, dds_publicat } if ((ep = dds_get_matched_subscription_data(writer, ih)) != NULL) { if (dc_is_ds_endpoint(dc->com, ep, dc->cfg.ident)) { - /* A dc_request reader on a data container has matched with the dc_request writer. + /* A dc_request reader on a DS has matched with the dc_request writer. * From now on it is allowed to publish requests. * In case there are any delivery requests, we can sent them now */ dc_add_matched_request_reader(dc, ep, ih); @@ -2112,7 +2203,7 @@ static void dc_process_delivery_request_guard (struct dc_t *dc, dds_time_t *time ddsrt_mutex_unlock(&dc->delivery_request_mutex); } -static uint32_t recv_handler (void *a) +static uint32_t delivery_handler (void *a) { struct dc_t *dc = (struct dc_t *)a; dds_time_t timeout = DDS_NEVER; @@ -2257,7 +2348,7 @@ static dds_return_t dds_durability_init (const dds_domainid_t domainid, struct d activate_request_listener(&dc); /* start a thread to process messages coming from a ds */ ddsrt_threadattr_init(&dc.recv_tattr); - if ((rc = ddsrt_thread_create(&dc.recv_tid, "dc", &dc.recv_tattr, recv_handler, &dc)) != DDS_RETCODE_OK) { + if ((rc = ddsrt_thread_create(&dc.recv_tid, "dc", &dc.recv_tattr, delivery_handler, &dc)) != DDS_RETCODE_OK) { goto err_recv_thread; } return DDS_RETCODE_OK; @@ -2394,7 +2485,7 @@ static dds_return_t dds_durability_new_local_reader (dds_entity_t reader, struct } if ((dkind == DDS_DURABILITY_TRANSIENT) || (dkind == DDS_DURABILITY_PERSISTENT)) { if (is_application_entity(&dc, reader)) { - /* the user data of the participant for this durable reader does + /* The user data of the participant for this durable reader does * not contain the ident, so the endpoint is not from a remote DS. * We can now publish a dc_request for this durable reader. The * dc_request is published as a transient-local topic. This means @@ -2499,11 +2590,34 @@ static dds_return_t dds_durability_get_quorum_reached (dds_entity_t writer, bool return ret; } +static dds_return_t dds_durability_wait_for_historical_data (dds_entity_t reader, dds_duration_t max_wait) +{ + dds_return_t ret = DDS_RETCODE_OK; + dds_entity *e; + dds_reader *rd; + + /* LH: The reader is pinned while waiting for wfhd. + * The reason for this is that I don't want the reader to be + * deleted while waiting for historical data. + * I am not sure if pinning alone is sufficient. */ + if ((ret = dds_entity_pin(reader, &e)) != DDS_RETCODE_OK) { + return ret; + } + rd = (dds_reader *) e; + ddsrt_mutex_lock(&rd->wfhd_mutex); + if (!ddsrt_cond_waitfor(&rd->wfhd_cond, &rd->wfhd_mutex, max_wait)) { + ret = DDS_RETCODE_TIMEOUT; + } + ddsrt_mutex_unlock(&rd->wfhd_mutex); + dds_entity_unpin(e); + return ret; +} + /* This function waits for a quorum of durable data containers to be available, * or timeout in case max_blocking_time is expired and quorum not yet reached. * * If the quorum is not reached before the max_blocking_time() is expired, - * DDS_RETCODE_PRECONDITION + * DDS_RETCODE_PRECONDITION is returned * * The quorum is calculated based on the number of discovered and matched data containers * for a writer. This also implies that if a writer has reached a quorum, @@ -2558,13 +2672,14 @@ static uint32_t dds_durability_get_quorum (void) return dc.cfg.quorum; } -void dds_durability_creator(dds_durability_t* ds) +void dds_durability_creator (dds_durability_t *dc) { - ds->dds_durability_init = dds_durability_init; - ds->_dds_durability_fini = _dds_durability_fini; - ds->dds_durability_get_quorum = dds_durability_get_quorum; - ds->dds_durability_new_local_reader = dds_durability_new_local_reader; - ds->dds_durability_new_local_writer = dds_durability_new_local_writer; - ds->dds_durability_wait_for_quorum = dds_durability_wait_for_quorum; - ds->dds_durability_is_terminating = dds_durability_is_terminating; + dc->dds_durability_init = dds_durability_init; + dc->_dds_durability_fini = _dds_durability_fini; + dc->dds_durability_get_quorum = dds_durability_get_quorum; + dc->dds_durability_new_local_reader = dds_durability_new_local_reader; + dc->dds_durability_new_local_writer = dds_durability_new_local_writer; + dc->dds_durability_wait_for_quorum = dds_durability_wait_for_quorum; + dc->dds_durability_is_terminating = dds_durability_is_terminating; + dc->dds_durability_wait_for_historical_data = dds_durability_wait_for_historical_data; } diff --git a/src/durability/src/durablesupport.idl b/src/durability/src/durablesupport.idl index 0e4d949512..6b0592fa59 100644 --- a/src/durability/src/durablesupport.idl +++ b/src/durability/src/durablesupport.idl @@ -15,6 +15,26 @@ module DurableSupport { /******************** * Durable client + * + * The following topics definitions specify the delivery topics used + * for communication between a durarable service and a user application + * (client). The following topics are defined: + * + * - request message send by a user application to a durable service. + * message to indicate that the user application requests delivery + * of historical data from a durable service to the user application. + * Typically, such request is done by an aplication reader that + * hat is interested in historical data. + * - response message send by a durable service to deliver historical data + * to a user application. Typically, a durable service sends a + * a stream of beads to a user application to provide the requested + * data. There are 3 types of responses: + * - set response: indicates the delivery start or delivery end of + * data set + * - data response: indicates delivery of historical data + * - reader response: indicates that all available historical data for + * a reader has been provided; signals that reader + * can return from dds_wait_for_historical_data(). ********************/ /* duration */ @@ -40,7 +60,8 @@ module DurableSupport { /* List of supported response types */ const responsetype_t RESPONSETYPE_SET = 1; - const responsetype_t RESPONSETYPE_DATA = 2; + const responsetype_t RESPONSETYPE_READER = 2; + const responsetype_t RESPONSETYPE_DATA = 3; @appendable @nested struct response_set_t { @@ -52,6 +73,11 @@ module DurableSupport { unsigned long flags; /* flags for this set */ }; + @appendable @nested + struct response_reader_t { + id_t rguid; /* guid of the reader that has become complete */ + }; + @appendable @nested struct response_data_t { sequence blob; @@ -60,6 +86,7 @@ module DurableSupport { @appendable @nested union response_content switch (responsetype_t) { case RESPONSETYPE_SET : response_set_t set; + case RESPONSETYPE_READER : response_reader_t reader; case RESPONSETYPE_DATA: response_data_t data; }; From 95ba340302f627942309b72bfb3e3bb4df8f990d Mon Sep 17 00:00:00 2001 From: TheFixer Date: Tue, 3 Sep 2024 00:06:53 +0200 Subject: [PATCH 207/207] Fix merge conflicts when rebasing on master Signed-off-by: TheFixer --- docs/manual/config/config_file_reference.rst | 11 ++++++----- docs/manual/options.md | 11 ++++++----- etc/cyclonedds.rnc | 10 +++++----- etc/cyclonedds.xsd | 12 ++++++------ src/core/ddsi/defconfig.c | 8 ++++---- 5 files changed, 27 insertions(+), 25 deletions(-) diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index 1f42273a2f..cae470edac 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -2665,12 +2665,13 @@ This element enables individual logging categories. These are enabled in additio * topic: tracing of topic definitions * plist: tracing of discovery parameter list interpretation - * durability: tracing of durable data * content: tracing of sample contents * malformed: dump malformed full packet as warning + * durability: tracing of durable data + * user: all user-defined tracing categories * user1: user-defined tracing category 1 @@ -2743,11 +2744,11 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: ``none`` .. - generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] + generated from ddsi_config.h[059f0d7bd76b557f73e670e06322d044d46960e6] generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] - generated from ddsi__cfgelems.h[fb5382bc6dbb34bca275d20c3c4282f948318862] - generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] - generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] + generated from ddsi__cfgelems.h[e6ac71277081b300188897a4713ff9a7d3406cb2] + generated from ddsi_config.c[edeb55de48ff9746fa3a088b871308194dcd5ab5] + generated from _confgen.h[9554f1d72645c0b8bb66ffbfbc3c0fb664fc1a43] generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] generated from generate_md.c[789b92e422631684352909cfb8bf43f6ceb16a01] diff --git a/docs/manual/options.md b/docs/manual/options.md index 288aad21ff..de93356d82 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -1863,12 +1863,13 @@ This element enables individual logging categories. These are enabled in additio * topic: tracing of topic definitions * plist: tracing of discovery parameter list interpretation - * durability: tracing of durable data * content: tracing of sample contents * malformed: dump malformed full packet as warning + * durability: tracing of durable data + * user: all user-defined tracing categories * user1: user-defined tracing category 1 @@ -1925,11 +1926,11 @@ While none prevents any message from being written to a DDSI2 log file. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest. The default value is: `none` - + - - - + + + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index b054f3c0cf..9a3143e89a 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -1292,7 +1292,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==

    The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is trace.

    The default value is: <empty>

    """ ] ] element Category { - xsd:token { pattern = "((fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|malformed|trace|user|user1|user2|user3)(,(fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|malformed|durability|trace|user|user1|user2|user3))*)|" } + xsd:token { pattern = "((fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|malformed|durability|trace|user|user1|user2|user3)(,(fatal|error|warning|info|config|discovery|data|radmin|timing|traffic|topic|tcp|plist|whc|throttle|rhc|content|malformed|durability|trace|user|user1|user2|user3))*)|" } }? & [ a:documentation [ xml:lang="en" """

    This option specifies where the logging is printed to. Note that stdout and stderr are treated as special values, representing "standard out" and "standard error" respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings.

    @@ -1330,11 +1330,11 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==
    duration_inf = xsd:token { pattern = "inf|0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)" } memsize = xsd:token { pattern = "0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B" } } -# generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] +# generated from ddsi_config.h[059f0d7bd76b557f73e670e06322d044d46960e6] # generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] -# generated from ddsi__cfgelems.h[fb5382bc6dbb34bca275d20c3c4282f948318862] -# generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] -# generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] +# generated from ddsi__cfgelems.h[e6ac71277081b300188897a4713ff9a7d3406cb2] +# generated from ddsi_config.c[edeb55de48ff9746fa3a088b871308194dcd5ab5] +# generated from _confgen.h[9554f1d72645c0b8bb66ffbfbc3c0fb664fc1a43] # generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] # generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] # generated from generate_md.c[789b92e422631684352909cfb8bf43f6ceb16a01] diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index 32a19ea027..7700ef8ab6 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -1919,7 +1919,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> <li><i>plist</i>: tracing of discovery parameter list interpretation</li> <li><i>content</i>: tracing of sample contents</li> <li><i>malformed</i>: dump malformed full packet as warning</li> -<li><i>durability</i>: tracing of durable data</li></li> +<li><i>durability</i>: tracing of durable data</li> <li><i>user</i>: all user-defined tracing categories</li> <li><i>user1</i>: user-defined tracing category 1</li> <li><i>user2</i>: user-defined tracing category 2</li> @@ -1931,7 +1931,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br>
    - +
    @@ -1999,11 +1999,11 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br> - + - - - + + + diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index c43ec9a58f..15b26743ff 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -102,11 +102,11 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->ssl_min_version.minor = 3; #endif /* DDS_HAS_TCP_TLS */ } -/* generated from ddsi_config.h[c86e7819dea81365c20acec4519abc2a022feca8] */ +/* generated from ddsi_config.h[059f0d7bd76b557f73e670e06322d044d46960e6] */ /* generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] */ -/* generated from ddsi__cfgelems.h[fb5382bc6dbb34bca275d20c3c4282f948318862] */ -/* generated from ddsi_config.c[95a436fb315153cae24f6d95f7e924e1004882e1] */ -/* generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] */ +/* generated from ddsi__cfgelems.h[e6ac71277081b300188897a4713ff9a7d3406cb2] */ +/* generated from ddsi_config.c[edeb55de48ff9746fa3a088b871308194dcd5ab5] */ +/* generated from _confgen.h[9554f1d72645c0b8bb66ffbfbc3c0fb664fc1a43] */ /* generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] */ /* generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] */ /* generated from generate_md.c[789b92e422631684352909cfb8bf43f6ceb16a01] */