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 interpretationdurability: 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><empty></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/CycloneDDS/Domain[@Id]>`
-Children: :ref:`Compatibility/CycloneDDS/Domain/Compatibility>`, :ref:`Discovery/CycloneDDS/Domain/Discovery>`, :ref:`General/CycloneDDS/Domain/General>`, :ref:`Internal|Unsupported/CycloneDDS/Domain/Internal>`, :ref:`Partitioning/CycloneDDS/Domain/Partitioning>`, :ref:`SSL/CycloneDDS/Domain/SSL>`, :ref:`Security|DDSSecurity/CycloneDDS/Domain/Security>`, :ref:`SharedMemory/CycloneDDS/Domain/SharedMemory>`, :ref:`Sizing/CycloneDDS/Domain/Sizing>`, :ref:`TCP/CycloneDDS/Domain/TCP>`, :ref:`Threads/CycloneDDS/Domain/Threads>`, :ref:`Tracing/CycloneDDS/Domain/Tracing>`
+Children: :ref:`Compatibility/CycloneDDS/Domain/Compatibility>`, :ref:`Discovery/CycloneDDS/Domain/Discovery>`, :ref:`Discovery/CycloneDDS/Domain/Durability>`, :ref:`General/CycloneDDS/Domain/General>`, :ref:`Internal|Unsupported/CycloneDDS/Domain/Internal>`, :ref:`Partitioning/CycloneDDS/Domain/Partitioning>`, :ref:`SSL/CycloneDDS/Domain/SSL>`, :ref:`Security|DDSSecurity/CycloneDDS/Domain/Security>`, :ref:`SharedMemory/CycloneDDS/Domain/SharedMemory>`, :ref:`Sizing/CycloneDDS/Domain/Sizing>`, :ref:`TCP/CycloneDDS/Domain/TCP>`, :ref:`Threads/CycloneDDS/Domain/Threads>`, :ref:`Tracing/CycloneDDS/Domain/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><empty></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/CycloneDDS/Domain[@Id]>`
-Children: :ref:`Compatibility/CycloneDDS/Domain/Compatibility>`, :ref:`Discovery/CycloneDDS/Domain/Discovery>`, :ref:`Discovery/CycloneDDS/Domain/Durability>`, :ref:`General/CycloneDDS/Domain/General>`, :ref:`Internal|Unsupported/CycloneDDS/Domain/Internal>`, :ref:`Partitioning/CycloneDDS/Domain/Partitioning>`, :ref:`SSL/CycloneDDS/Domain/SSL>`, :ref:`Security|DDSSecurity/CycloneDDS/Domain/Security>`, :ref:`SharedMemory/CycloneDDS/Domain/SharedMemory>`, :ref:`Sizing/CycloneDDS/Domain/Sizing>`, :ref:`TCP/CycloneDDS/Domain/TCP>`, :ref:`Threads/CycloneDDS/Domain/Threads>`, :ref:`Tracing/CycloneDDS/Domain/Tracing>`
+Children: :ref:`Compatibility/CycloneDDS/Domain/Compatibility>`, :ref:`Discovery/CycloneDDS/Domain/Discovery>`, :ref:`Durability/CycloneDDS/Domain/Durability>`, :ref:`General/CycloneDDS/Domain/General>`, :ref:`Internal|Unsupported/CycloneDDS/Domain/Internal>`, :ref:`Partitioning/CycloneDDS/Domain/Partitioning>`, :ref:`SSL/CycloneDDS/Domain/SSL>`, :ref:`Security|DDSSecurity/CycloneDDS/Domain/Security>`, :ref:`SharedMemory/CycloneDDS/Domain/SharedMemory>`, :ref:`Sizing/CycloneDDS/Domain/Sizing>`, :ref:`TCP/CycloneDDS/Domain/TCP>`, :ref:`Threads/CycloneDDS/Domain/Threads>`, :ref:`Tracing/CycloneDDS/Domain/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/CycloneDDS/Domain/Durability/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/CycloneDDS/Domain/Internal/AccelerateRexmitBlockSize>`, :ref:`AckDelay/CycloneDDS/Domain/Internal/AckDelay>`, :ref:`AutoReschedNackDelay/CycloneDDS/Domain/Internal/AutoReschedNackDelay>`, :ref:`BuiltinEndpointSet/CycloneDDS/Domain/Internal/BuiltinEndpointSet>`, :ref:`BurstSize/CycloneDDS/Domain/Internal/BurstSize>`, :ref:`ControlTopic/CycloneDDS/Domain/Internal/ControlTopic>`, :ref:`DefragReliableMaxSamples/CycloneDDS/Domain/Internal/DefragReliableMaxSamples>`, :ref:`DefragUnreliableMaxSamples/CycloneDDS/Domain/Internal/DefragUnreliableMaxSamples>`, :ref:`DeliveryQueueMaxSamples/CycloneDDS/Domain/Internal/DeliveryQueueMaxSamples>`, :ref:`EnableExpensiveChecks/CycloneDDS/Domain/Internal/EnableExpensiveChecks>`, :ref:`ExtendedPacketInfo/CycloneDDS/Domain/Internal/ExtendedPacketInfo>`, :ref:`GenerateKeyhash/CycloneDDS/Domain/Internal/GenerateKeyhash>`, :ref:`HeartbeatInterval/CycloneDDS/Domain/Internal/HeartbeatInterval>`, :ref:`LateAckMode/CycloneDDS/Domain/Internal/LateAckMode>`, :ref:`LivelinessMonitoring/CycloneDDS/Domain/Internal/LivelinessMonitoring>`, :ref:`MaxParticipants/CycloneDDS/Domain/Internal/MaxParticipants>`, :ref:`MaxQueuedRexmitBytes/CycloneDDS/Domain/Internal/MaxQueuedRexmitBytes>`, :ref:`MaxQueuedRexmitMessages/CycloneDDS/Domain/Internal/MaxQueuedRexmitMessages>`, :ref:`MaxSampleSize/CycloneDDS/Domain/Internal/MaxSampleSize>`, :ref:`MeasureHbToAckLatency/CycloneDDS/Domain/Internal/MeasureHbToAckLatency>`, :ref:`MonitorPort/CycloneDDS/Domain/Internal/MonitorPort>`, :ref:`MultipleReceiveThreads/CycloneDDS/Domain/Internal/MultipleReceiveThreads>`, :ref:`NackDelay/CycloneDDS/Domain/Internal/NackDelay>`, :ref:`PreEmptiveAckDelay/CycloneDDS/Domain/Internal/PreEmptiveAckDelay>`, :ref:`PrimaryReorderMaxSamples/CycloneDDS/Domain/Internal/PrimaryReorderMaxSamples>`, :ref:`PrioritizeRetransmit/CycloneDDS/Domain/Internal/PrioritizeRetransmit>`, :ref:`RediscoveryBlacklistDuration/CycloneDDS/Domain/Internal/RediscoveryBlacklistDuration>`, :ref:`RetransmitMerging/CycloneDDS/Domain/Internal/RetransmitMerging>`, :ref:`RetransmitMergingPeriod/CycloneDDS/Domain/Internal/RetransmitMergingPeriod>`, :ref:`RetryOnRejectBestEffort/CycloneDDS/Domain/Internal/RetryOnRejectBestEffort>`, :ref:`SPDPResponseMaxDelay/CycloneDDS/Domain/Internal/SPDPResponseMaxDelay>`, :ref:`SecondaryReorderMaxSamples/CycloneDDS/Domain/Internal/SecondaryReorderMaxSamples>`, :ref:`SocketReceiveBufferSize/CycloneDDS/Domain/Internal/SocketReceiveBufferSize>`, :ref:`SocketSendBufferSize/CycloneDDS/Domain/Internal/SocketSendBufferSize>`, :ref:`SquashParticipants/CycloneDDS/Domain/Internal/SquashParticipants>`, :ref:`SynchronousDeliveryLatencyBound/CycloneDDS/Domain/Internal/SynchronousDeliveryLatencyBound>`, :ref:`SynchronousDeliveryPriorityThreshold/CycloneDDS/Domain/Internal/SynchronousDeliveryPriorityThreshold>`, :ref:`Test/CycloneDDS/Domain/Internal/Test>`, :ref:`UnicastResponseToSPDPMessages/CycloneDDS/Domain/Internal/UnicastResponseToSPDPMessages>`, :ref:`UseMulticastIfMreqn/CycloneDDS/Domain/Internal/UseMulticastIfMreqn>`, :ref:`Watermarks/CycloneDDS/Domain/Internal/Watermarks>`, :ref:`WriterLingerDuration/CycloneDDS/Domain/Internal/WriterLingerDuration>`
+Children: :ref:`AccelerateRexmitBlockSize/CycloneDDS/Domain/Internal/AccelerateRexmitBlockSize>`, :ref:`AckDelay/CycloneDDS/Domain/Internal/AckDelay>`, :ref:`AutoReschedNackDelay/CycloneDDS/Domain/Internal/AutoReschedNackDelay>`, :ref:`BuiltinEndpointSet/CycloneDDS/Domain/Internal/BuiltinEndpointSet>`, :ref:`BurstSize/CycloneDDS/Domain/Internal/BurstSize>`, :ref:`ControlTopic/CycloneDDS/Domain/Internal/ControlTopic>`, :ref:`DefragReliableMaxSamples/CycloneDDS/Domain/Internal/DefragReliableMaxSamples>`, :ref:`DefragUnreliableMaxSamples/CycloneDDS/Domain/Internal/DefragUnreliableMaxSamples>`, :ref:`DeliveryQueueMaxSamples/CycloneDDS/Domain/Internal/DeliveryQueueMaxSamples>`, :ref:`EnableExpensiveChecks/CycloneDDS/Domain/Internal/EnableExpensiveChecks>`, :ref:`ExtendedPacketInfo/CycloneDDS/Domain/Internal/ExtendedPacketInfo>`, :ref:`GenerateKeyhash/CycloneDDS/Domain/Internal/GenerateKeyhash>`, :ref:`HeartbeatInterval/CycloneDDS/Domain/Internal/HeartbeatInterval>`, :ref:`LateAckMode/CycloneDDS/Domain/Internal/LateAckMode>`, :ref:`LivelinessMonitoring/CycloneDDS/Domain/Internal/LivelinessMonitoring>`, :ref:`MaxParticipants/CycloneDDS/Domain/Internal/MaxParticipants>`, :ref:`MaxQueuedRexmitBytes/CycloneDDS/Domain/Internal/MaxQueuedRexmitBytes>`, :ref:`MaxQueuedRexmitMessages/CycloneDDS/Domain/Internal/MaxQueuedRexmitMessages>`, :ref:`MaxSampleSize/CycloneDDS/Domain/Internal/MaxSampleSize>`, :ref:`MeasureHbToAckLatency/CycloneDDS/Domain/Internal/MeasureHbToAckLatency>`, :ref:`MonitorPort/CycloneDDS/Domain/Internal/MonitorPort>`, :ref:`MultipleReceiveThreads/CycloneDDS/Domain/Internal/MultipleReceiveThreads>`, :ref:`NackDelay/CycloneDDS/Domain/Internal/NackDelay>`, :ref:`PreEmptiveAckDelay/CycloneDDS/Domain/Internal/PreEmptiveAckDelay>`, :ref:`PrimaryReorderMaxSamples/CycloneDDS/Domain/Internal/PrimaryReorderMaxSamples>`, :ref:`PrioritizeRetransmit/CycloneDDS/Domain/Internal/PrioritizeRetransmit>`, :ref:`RediscoveryBlacklistDuration/CycloneDDS/Domain/Internal/RediscoveryBlacklistDuration>`, :ref:`RetransmitMerging/CycloneDDS/Domain/Internal/RetransmitMerging>`, :ref:`RetransmitMergingPeriod/CycloneDDS/Domain/Internal/RetransmitMergingPeriod>`, :ref:`RetryOnRejectBestEffort/CycloneDDS/Domain/Internal/RetryOnRejectBestEffort>`, :ref:`SPDPResponseMaxDelay/CycloneDDS/Domain/Internal/SPDPResponseMaxDelay>`, :ref:`SecondaryReorderMaxSamples/CycloneDDS/Domain/Internal/SecondaryReorderMaxSamples>`, :ref:`SocketReceiveBufferSize/CycloneDDS/Domain/Internal/SocketReceiveBufferSize>`, :ref:`SocketSendBufferSize/CycloneDDS/Domain/Internal/SocketSendBufferSize>`, :ref:`SquashParticipants/CycloneDDS/Domain/Internal/SquashParticipants>`, :ref:`SynchronousDeliveryLatencyBound/CycloneDDS/Domain/Internal/SynchronousDeliveryLatencyBound>`, :ref:`SynchronousDeliveryPriorityThreshold/CycloneDDS/Domain/Internal/SynchronousDeliveryPriorityThreshold>`, :ref:`Test/CycloneDDS/Domain/Internal/Test>`, :ref:`UseMulticastIfMreqn/CycloneDDS/Domain/Internal/UseMulticastIfMreqn>`, :ref:`Watermarks/CycloneDDS/Domain/Internal/Watermarks>`, :ref:`WriterLingerDuration/CycloneDDS/Domain/Internal/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><empty></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 " #kind "_qos>"
+#define ENT_N(nm,qos,kind) \
+ "\n <" #kind "_qos name=\""#nm"\">"qos"\n " #kind "_qos>"
+
+
+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"#unit">"
+#define QOS_DURATION_FMT_STR(unit) \
+ "<"#unit">%s"#unit">"
+#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