diff --git a/.travis.yml b/.travis.yml
index ca8d69a..cf1729b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -182,7 +182,7 @@ script:
${SCAN_BUILD} cmake --build . --config ${BUILD_TYPE} --target install
;;
esac
- - CYCLONEDDS_URI='all' ctest -j 4 --output-on-failure -T test -C ${BUILD_TYPE}
+ - CYCLONEDDS_URI='all' ctest -j 4 --output-on-failure -T test -C ${BUILD_TYPE}
- if [ "${ASAN}" != "none" ]; then
CMAKE_LINKER_FLAGS="-DCMAKE_LINKER_FLAGS=-fsanitize=${USE_SANITIZER}";
CMAKE_C_FLAGS="-DCMAKE_C_FLAGS=-fsanitize=${USE_SANITIZER}";
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e174ce0..a07a950 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -157,7 +157,7 @@ if(${CMAKE_GENERATOR} STREQUAL "Xcode")
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VALUE YES)
set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VARIABLE YES)
set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_DOCUMENTATION_COMMENTS YES)
- set (CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_MISSING_PROTOTYPES YES)
+ set (CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_MISSING_PROTOTYPES YES)
endif()
# Make it easy to enable one of Clang's/gcc's analyzers, and default to using
diff --git a/README.md b/README.md
index 9e11dd6..1337cab 100644
--- a/README.md
+++ b/README.md
@@ -186,21 +186,23 @@ point to it. E.g. (on Linux):
$ cat cyclonedds.xml
-
- auto
- auto
- 65500B
- 65000B
-
-
-
- 500kB
-
-
-
- config
- stdout
-
+
+
+ auto
+ auto
+ 65500B
+ 4000B
+
+
+
+ 500kB
+
+
+
+ config
+ stdout
+
+
$ export CYCLONEDDS_URI=file://$PWD/cyclonedds.xml
diff --git a/appveyor.yml b/appveyor.yml
index e05dec9..276e4bf 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -46,5 +46,5 @@ build_script:
- cd ../../../../../..
test_script:
- - set "CYCLONEDDS_URI=all"
+ - set "CYCLONEDDS_URI=all"
- ctest --output-on-failure --parallel 4 --test-action test --build-config %CONFIGURATION%
diff --git a/src/core/ddsc/src/dds_domain.c b/src/core/ddsc/src/dds_domain.c
index 04e1dcc..3fe6786 100644
--- a/src/core/ddsc/src/dds_domain.c
+++ b/src/core/ddsc/src/dds_domain.c
@@ -45,11 +45,32 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
char * uri = NULL;
uint32_t len;
- domain->m_id = domain_id;
+ domain->gv.tstart = now ();
domain->m_refc = 1;
ddsrt_avl_init (&dds_topictree_def, &domain->m_topics);
- domain->gv.tstart = now ();
+ /* | domain_id | domain id in config | result
+ +-----------+---------------------+----------
+ | DEFAULT | any (or absent) | 0
+ | DEFAULT | n | n
+ | n | any (or absent) | n
+ | n | m = n | n
+ | n | m /= n | n, entire config ignored
+
+ Config models:
+ 1:
+ ...
+
+
+ where ... is all that can today be set in children of CycloneDDS
+ with the exception of the id
+ 2:
+ X
+ ...
+
+ legacy form, domain id must be the first element in the file with
+ a value (if nothing has been set previously, it a warning is good
+ enough) */
(void) ddsrt_getenv ("CYCLONEDDS_URI", &uri);
domain->cfgst = config_init (uri, &domain->gv.config, domain_id);
@@ -60,30 +81,8 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
goto fail_config;
}
- /* if a domain id was explicitly given, check & fix up the configuration */
- if (domain_id != DDS_DOMAIN_DEFAULT)
- {
- if (domain_id > 230)
- {
- DDS_ILOG (DDS_LC_ERROR, domain_id, "requested domain id %"PRIu32" is out of range\n", domain_id);
- ret = DDS_RETCODE_ERROR;
- goto fail_config_domainid;
- }
- else if (domain->gv.config.domainId.isdefault)
- {
- domain->gv.config.domainId.value = domain_id;
- }
- else if (domain_id != domain->gv.config.domainId.value)
- {
- DDS_ILOG (DDS_LC_ERROR, domain_id, "requested domain id %"PRIu32" is inconsistent with configured value %"PRIu32"\n", domain_id, domain->gv.config.domainId.value);
- ret = DDS_RETCODE_ERROR;
- goto fail_config_domainid;
- }
- }
-
- /* FIXME: The gv.config.domainId can change internally in DDSI. So, remember what the
- * main configured domain id is. */
- domain->m_id = domain->gv.config.domainId.value;
+ assert (domain_id == DDS_DOMAIN_DEFAULT || domain_id == domain->gv.config.domainId);
+ domain->m_id = domain->gv.config.domainId;
if (rtps_config_prep (&domain->gv, domain->cfgst) != 0)
{
@@ -146,7 +145,7 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
if (rtps_start (&domain->gv) < 0)
{
- DDS_LOG (DDS_LC_CONFIG, "Failed to start RTPS\n");
+ DDS_ILOG (DDS_LC_CONFIG, domain->m_id, "Failed to start RTPS\n");
ret = DDS_RETCODE_ERROR;
goto fail_rtps_start;
}
@@ -169,7 +168,6 @@ fail_threadmon_new:
rtps_fini (&domain->gv);
fail_rtps_init:
fail_rtps_config:
-fail_config_domainid:
config_fini (domain->cfgst);
fail_config:
return ret;
diff --git a/src/core/ddsc/tests/config_simple_udp.xml b/src/core/ddsc/tests/config_simple_udp.xml
index 52eb377..c333d64 100644
--- a/src/core/ddsc/tests/config_simple_udp.xml
+++ b/src/core/ddsc/tests/config_simple_udp.xml
@@ -13,24 +13,23 @@
-
- 3
+
+
+ 127.0.0.1
+ true
+ true
+
+
+ lax
+
+
+ warning
+ vortexdds-.${NON_EXISTENT_ENV_VARIABLE:-l}${CYCLONEDDS_URI:+o}g
+
+
+ ${MAX_PARTICIPANTS}
+ 100 ms
+
+
-
- 127.0.0.1
- true
- true
-
-
- lax
-
-
- warning
- vortexdds-.${NON_EXISTENT_ENV_VARIABLE:-l}${CYCLONEDDS_URI:+o}g
-
-
- ${MAX_PARTICIPANTS}
- 100 ms
-
-
diff --git a/src/core/ddsc/tests/participant.c b/src/core/ddsc/tests/participant.c
index 85b6be9..23d5d42 100644
--- a/src/core/ddsc/tests/participant.c
+++ b/src/core/ddsc/tests/participant.c
@@ -102,7 +102,7 @@ CU_Test(ddsc_participant, create_multiple_domains)
/* Test for creating participant with valid configuration file */
CU_Test(ddsc_participant, create_with_conf_no_env) {
- dds_entity_t participant, participant2, participant3;
+ dds_entity_t participant2, participant3;
dds_return_t status;
dds_domainid_t domain_id;
dds_domainid_t valid_domain=3;
@@ -114,10 +114,6 @@ CU_Test(ddsc_participant, create_with_conf_no_env) {
ddsrt_getenv(DDS_PROJECT_NAME_NOSPACE_CAPS"_URI", &env_uri);
CU_ASSERT_PTR_NOT_EQUAL_FATAL(env_uri, NULL);
- //invalid domain
- participant = dds_create_participant (1, NULL, NULL);
- CU_ASSERT_FATAL(participant < 0);
-
//valid specific domain value
participant2 = dds_create_participant (valid_domain, NULL, NULL);
CU_ASSERT_FATAL(participant2 > 0);
diff --git a/src/core/ddsi/include/dds/ddsi/q_config.h b/src/core/ddsi/include/dds/ddsi/q_config.h
index dd8a506..ffd1ede 100644
--- a/src/core/ddsi/include/dds/ddsi/q_config.h
+++ b/src/core/ddsi/include/dds/ddsi/q_config.h
@@ -224,7 +224,7 @@ struct ssl_min_version {
struct config
{
int valid;
- uint32_t enabled_logcats;
+ uint32_t tracemask;
uint32_t enabled_xchecks;
char *servicename;
char *pcap_file;
@@ -233,8 +233,8 @@ struct config
char **networkRecvAddressStrings;
char *externalAddressString;
char *externalMaskString;
- FILE *tracingOutputFile;
- char *tracingOutputFileName;
+ FILE *tracefp;
+ char *tracefile;
int tracingTimestamps;
int tracingAppendToFile;
uint32_t allowMulticast;
@@ -244,7 +244,7 @@ struct config
enum boolean_default compat_tcp_enable;
int dontRoute;
int enableMulticastLoopback;
- struct config_maybe_uint32 domainId;
+ uint32_t domainId;
int participantIndex;
int maxAutoParticipantIndex;
uint32_t port_base;
diff --git a/src/core/ddsi/include/dds/ddsi/q_rtps.h b/src/core/ddsi/include/dds/ddsi/q_rtps.h
index d81054f..0b6ff39 100644
--- a/src/core/ddsi/include/dds/ddsi/q_rtps.h
+++ b/src/core/ddsi/include/dds/ddsi/q_rtps.h
@@ -76,7 +76,7 @@ typedef int64_t seqno_t;
struct cfgst;
struct q_globals;
int rtps_config_prep (struct q_globals *config, struct cfgst *cfgst);
-int rtps_config_open (struct q_globals *config);
+int rtps_config_open_trace (struct q_globals *config);
int rtps_init (struct q_globals *config);
int rtps_start (struct q_globals *config);
void rtps_stop (struct q_globals *config);
diff --git a/src/core/ddsi/src/q_addrset.c b/src/core/ddsi/src/q_addrset.c
index 376e509..b04f064 100644
--- a/src/core/ddsi/src/q_addrset.c
+++ b/src/core/ddsi/src/q_addrset.c
@@ -105,7 +105,7 @@ static int add_addresses_to_addrset_1 (const struct q_globals *gv, struct addrse
assert (gv->config.maxAutoParticipantIndex >= 0);
for (uint32_t i = 0; i <= (uint32_t) gv->config.maxAutoParticipantIndex; i++)
{
- uint32_t port = gv->config.port_base + gv->config.port_dg * gv->config.domainId.value + i * gv->config.port_pg + gv->config.port_d1;
+ uint32_t port = gv->config.port_base + gv->config.port_dg * gv->config.domainId + i * gv->config.port_pg + gv->config.port_d1;
loc.port = (unsigned) port;
if (i == 0)
GVLOG (DDS_LC_CONFIG, "%s", ddsi_locator_to_string(gv, buf, sizeof(buf), &loc));
@@ -118,7 +118,7 @@ static int add_addresses_to_addrset_1 (const struct q_globals *gv, struct addrse
{
uint32_t port;
if (port_mode == -1)
- port = gv->config.port_base + gv->config.port_dg * gv->config.domainId.value + gv->config.port_d0;
+ port = gv->config.port_base + gv->config.port_dg * gv->config.domainId + gv->config.port_d0;
else
port = (uint32_t) port_mode;
loc.port = (unsigned) port;
diff --git a/src/core/ddsi/src/q_config.c b/src/core/ddsi/src/q_config.c
index 34935b2..b45eba5 100644
--- a/src/core/ddsi/src/q_config.c
+++ b/src/core/ddsi/src/q_config.c
@@ -41,10 +41,16 @@
struct cfgelem;
struct cfgst;
-typedef int(*init_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem);
-typedef int(*update_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value);
-typedef void(*free_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem);
-typedef void(*print_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources);
+enum update_result {
+ URES_SUCCESS, /* value processed successfully */
+ URES_ERROR, /* invalid value, reject configuration */
+ URES_SKIP_ELEMENT /* entire subtree should be ignored */
+};
+
+typedef int (*init_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem);
+typedef enum update_result (*update_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value);
+typedef void (*free_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem);
+typedef void (*print_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources);
#ifdef DDSI_INCLUDE_SECURITY
struct q_security_plugins q_security_plugin = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
@@ -84,24 +90,43 @@ struct cfgst_node {
};
enum implicit_toplevel {
- ITL_DISALLOWED,
- ITL_ALLOWED,
- ITL_INSERTED
+ ITL_DISALLOWED = -1,
+ ITL_ALLOWED = 0,
+ ITL_INSERTED_1 = 1,
+ ITL_INSERTED_2 = 2
};
struct cfgst {
ddsrt_avl_tree_t found;
struct config *cfg;
- uint32_t domid;
const struct ddsrt_log_cfg *logcfg; /* for LOG_LC_CONFIG */
/* error flag set so that we can continue parsing for some errors and still fail properly */
int error;
+ /* Whether this is the first element in this source: used to reject about configurations
+ where the deprecated Domain/Id element is used but is set after some other things
+ have been set. The underlying reason being that the configuration handling can't
+ backtrack and so needs to reject a configuration for an unrelated domain before
+ anything is set.
+
+ The new form, where the id is an attribute of the Domain element, avoids this
+ by guaranteeing that the id comes first. It seems most likely that the Domain/Id
+ was either not set or at the start of the file and that this is therefore good
+ enough. */
+ bool first_data_in_source;
+
+ /* Whether inserting an implicit CycloneDDS is allowed (for making it easier to hack
+ a configuration through the environment variables, and if allowed, whether it has
+ been inserted */
enum implicit_toplevel implicit_toplevel;
/* current input, mask with 1 bit set */
uint32_t source;
+ /* ~ current input and line number */
+ char *input;
+ int line;
+
/* path_depth, isattr and path together control the formatting of
error messages by cfg_error() */
int path_depth;
@@ -114,7 +139,7 @@ static int cfgst_node_cmp(const void *va, const void *vb);
static const ddsrt_avl_treedef_t cfgst_found_treedef =
DDSRT_AVL_TREEDEF_INITIALIZER(offsetof(struct cfgst_node, avlnode), offsetof(struct cfgst_node, key), cfgst_node_cmp, 0);
-#define DU(fname) static int uf_##fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
+#define DU(fname) static enum update_result uf_##fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
#define PF(fname) static void pf_##fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
#define DUPF(fname) DU(fname) ; PF(fname)
PF(nop);
@@ -130,7 +155,7 @@ PF(boolean_default);
DUPF(string);
DU(tracingOutputFileName);
DU(verbosity);
-DUPF(logcat);
+DUPF(tracemask);
DUPF(xcheck);
DUPF(int);
DUPF(uint);
@@ -208,7 +233,7 @@ DI(if_thread_properties);
#define MGROUP(name, children, attrs) name, children, attrs
#define ATTR(name) name, NULL, NULL
#define DEPRECATED_ATTR(name) "|" name, NULL, NULL
-/* MOVED: whereto must be a path relative to DDSI2Service, may not be used in/for lists and only for elements, may not be chained */
+/* MOVED: whereto must be a path starting with CycloneDDS, may not be used in/for lists and only for elements, may not be chained */
#define MOVED(name, whereto) ">" name, NULL, NULL, 0, whereto, 0, 0, 0, 0, 0, 0, NULL
#if 0
#define BLURB(text) text
@@ -283,7 +308,7 @@ static const struct cfgelem securityprofile_cfgattrs[] = {
};
static const struct cfgelem security_cfgelems[] = {
- { LEAF_W_ATTRS("SecurityProfile", securityprofile_cfgattrs), 0, 0, ABSOFF(securityProfiles), if_security_profile, 0, 0, 0,
+ { LEAF_W_ATTRS("SecurityProfile", securityprofile_cfgattrs), INT_MAX, 0, ABSOFF(securityProfiles), if_security_profile, 0, 0, 0,
BLURB("
This element defines a DDSI2E security profile.
") },
END_MARKER
};
@@ -305,7 +330,7 @@ static const struct cfgelem networkpartition_cfgattrs[] = {
};
static const struct cfgelem networkpartitions_cfgelems[] = {
- { LEAF_W_ATTRS("NetworkPartition", networkpartition_cfgattrs), 2, 0, ABSOFF(networkPartitions), if_network_partition, 0, 0, 0,
+ { LEAF_W_ATTRS("NetworkPartition", networkpartition_cfgattrs), INT_MAX, 0, ABSOFF(networkPartitions), if_network_partition, 0, 0, 0,
BLURB("This element defines a DDSI2E network partition.
") },
END_MARKER
};
@@ -317,7 +342,7 @@ static const struct cfgelem ignoredpartitions_cfgattrs[] = {
};
static const struct cfgelem ignoredpartitions_cfgelems[] = {
- { LEAF_W_ATTRS("IgnoredPartition", ignoredpartitions_cfgattrs), 0, 0, ABSOFF(ignoredPartitions), if_ignored_partition, 0, 0, 0,
+ { LEAF_W_ATTRS("IgnoredPartition", ignoredpartitions_cfgattrs), INT_MAX, 0, ABSOFF(ignoredPartitions), if_ignored_partition, 0, 0, 0,
BLURB("This element can be used to prevent certain combinations of DCPS partition and topic from being transmitted over the network. DDSI2E will complete ignore readers and writers for which all DCPS partitions as well as their topic is ignored, not even creating DDSI readers and writers to mirror the DCPS ones.
") },
END_MARKER
};
@@ -331,7 +356,7 @@ static const struct cfgelem partitionmappings_cfgattrs[] = {
};
static const struct cfgelem partitionmappings_cfgelems[] = {
- { LEAF_W_ATTRS("PartitionMapping", partitionmappings_cfgattrs), 0, 0, ABSOFF(partitionMappings), if_partition_mapping, 0, 0, 0,
+ { LEAF_W_ATTRS("PartitionMapping", partitionmappings_cfgattrs), INT_MAX, 0, ABSOFF(partitionMappings), if_partition_mapping, 0, 0, 0,
BLURB("This element defines a mapping from a DCPS partition/topic combination to a DDSI2E network partition. This allows partitioning data flows by using special multicast addresses for part of the data and possibly also encrypting the data flow.
") },
END_MARKER
};
@@ -376,7 +401,7 @@ static const struct cfgelem channel_cfgattrs[] = {
};
static const struct cfgelem channels_cfgelems[] = {
- { MGROUP("Channel", channel_cfgelems, channel_cfgattrs), 42, 0, ABSOFF(channels), if_channel, 0, 0, 0,
+ { MGROUP("Channel", channel_cfgelems, channel_cfgattrs), INT_MAX, 0, ABSOFF(channels), if_channel, 0, 0, 0,
BLURB("This element defines a channel.
") },
END_MARKER
};
@@ -413,7 +438,7 @@ static const struct cfgelem thread_properties_cfgelems[] = {
};
static const struct cfgelem threads_cfgelems[] = {
- { MGROUP("Thread", thread_properties_cfgelems, thread_properties_cfgattrs), 1000, 0, ABSOFF(thread_properties), if_thread_properties, 0, 0, 0,
+ { MGROUP("Thread", thread_properties_cfgelems, thread_properties_cfgattrs), INT_MAX, 0, ABSOFF(thread_properties), if_thread_properties, 0, 0, 0,
BLURB("This element is used to set thread properties.
") },
END_MARKER
};
@@ -696,13 +721,13 @@ static const struct cfgelem discovery_peer_cfgattrs[] = {
};
static const struct cfgelem discovery_peers_group_cfgelems[] = {
- { MGROUP("Peer", NULL, discovery_peer_cfgattrs), 0, NULL, ABSOFF(peers_group), if_peer, 0, 0, 0,
+ { MGROUP("Peer", NULL, discovery_peer_cfgattrs), INT_MAX, NULL, ABSOFF(peers_group), if_peer, 0, 0, 0,
BLURB("This element statically configures an addresses for discovery.
") },
END_MARKER
};
static const struct cfgelem discovery_peers_cfgelems[] = {
- { MGROUP("Peer", NULL, discovery_peer_cfgattrs), 0, NULL, ABSOFF(peers), if_peer, 0, 0, 0,
+ { MGROUP("Peer", NULL, discovery_peer_cfgattrs), INT_MAX, NULL, ABSOFF(peers), if_peer, 0, 0, 0,
BLURB("This element statically configures an addresses for discovery.
") },
{ GROUP("Group", discovery_peers_group_cfgelems),
BLURB("This element statically configures a fault tolerant group of addresses for discovery. Each member of the group is tried in sequence until one succeeds.
") },
@@ -736,7 +761,7 @@ static const struct cfgelem discovery_cfgelems[] = {
};
static const struct cfgelem tracing_cfgelems[] = {
- { LEAF("EnableCategory"), 1, "", 0, 0, 0, uf_logcat, 0, pf_logcat,
+ { LEAF("EnableCategory"), 1, "", 0, 0, 0, uf_tracemask, 0, pf_tracemask,
BLURB("This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are:
\n\
- fatal: all fatal errors, errors causing immediate termination
\n\
- error: failures probably impacting correctness but not necessarily causing immediate termination
\n\
@@ -766,7 +791,7 @@ static const struct cfgelem tracing_cfgelems[] = {
- finest: finer + trace
\n\
While none prevents any message from being written to a DDSI2 log file.
\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 target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest.
") },
- { LEAF("OutputFile"), 1, "cyclonedds.log", ABSOFF(tracingOutputFileName), 0, uf_tracingOutputFileName, ff_free, pf_string,
+ { LEAF("OutputFile"), 1, "cyclonedds.log", ABSOFF(tracefile), 0, uf_tracingOutputFileName, ff_free, pf_string,
BLURB("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.
") },
{ LEAF("AppendToFile"), 1, "false", ABSOFF(tracingAppendToFile), 0, uf_boolean, 0, pf_boolean,
BLURB("This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated.
") },
@@ -775,14 +800,14 @@ static const struct cfgelem tracing_cfgelems[] = {
END_MARKER
};
-static const struct cfgelem domain_cfgelems[] = {
- { LEAF("Id"), 1, "any", ABSOFF(domainId), 0, uf_domainId, 0, pf_domainId, NULL },
+static const struct cfgelem domain_cfgattrs[] = {
+ { LEAF("Id"), 0, "any", ABSOFF(domainId), 0, uf_domainId, 0, pf_domainId,
+ BLURB("Domain id this configuration applies to, or \"any\" if it applies to all domain ids.
") },
END_MARKER
};
-static const struct cfgelem root_cfgelems[] = {
- { GROUP("Domain", domain_cfgelems),
- BLURB("The General element specifying Domain related settings.
") },
+static const struct cfgelem domain_cfgelems[] = {
+ { MOVED("Id", "CycloneDDS/Domain[@Id]") },
{ GROUP("General", general_cfgelems),
BLURB("The General element specifies overall DDSI2E service settings.
") },
#ifdef DDSI_INCLUDE_ENCRYPTION
@@ -817,12 +842,39 @@ static const struct cfgelem root_cfgelems[] = {
{ GROUP("SSL", ssl_cfgelems),
BLURB("The SSL element allows specifying various parameters related to using SSL/TLS for DDSI over TCP.
") },
#endif
- { MOVED("DDSI2E|DDSI2", "CycloneDDS") },
+ END_MARKER
+};
+
+static const struct cfgelem root_cfgelems[] = {
+ { GROUP_W_ATTRS("Domain", domain_cfgelems, domain_cfgattrs),
+ BLURB("The General element specifying Domain related settings.
") },
+ { MOVED("General", "CycloneDDS/Domain/General") },
+#ifdef DDSI_INCLUDE_ENCRYPTION
+ { MOVED("Security", "CycloneDDS/Domain/Security") },
+#endif
+#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
+ { MOVED("Partitioning", "CycloneDDS/Domain/Partitioning") },
+#endif
+#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
+ { MOVED("Channels", "CycloneDDS/Domain/Channels") },
+#endif
+ { MOVED("Threads", "CycloneDDS/Domain/Threads") },
+ { MOVED("Sizing", "CycloneDDS/Domain/Sizing") },
+ { MOVED("Compatibility", "CycloneDDS/Domain/Compatibility") },
+ { MOVED("Discovery", "CycloneDDS/Domain/Discovery") },
+ { MOVED("Tracing", "CycloneDDS/Domain/Tracing") },
+ { MOVED("Internal|Unsupported", "CycloneDDS/Domain/Internal") },
+ { MOVED("TCP", "CycloneDDS/Domain/TCP") },
+ { MOVED("ThreadPool", "CycloneDDS/Domain/ThreadPool") },
+#ifdef DDSI_INCLUDE_SSL
+ { MOVED("SSL", "CycloneDDS/Domain/SSL") },
+#endif
+ { MOVED("DDSI2E|DDSI2", "CycloneDDS/Domain") },
END_MARKER
};
static const struct cfgelem cyclonedds_root_cfgelems[] = {
- { "CycloneDDS", root_cfgelems, NULL, NODATA, NULL },
+ { "CycloneDDS", root_cfgelems, NULL, NODATA, BLURB("CycloneDDS configuration") },
END_MARKER
};
@@ -898,7 +950,7 @@ static const struct unit unittab_bandwidth_Bps[] = {
static void free_configured_elements (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem);
static void free_configured_element (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem);
-static const struct cfgelem *lookup_element (const char *target);
+static const struct cfgelem *lookup_element (const char *target, bool *isattr);
static void cfgst_push (struct cfgst *cfgst, int isattr, const struct cfgelem *elem, void *parent)
{
@@ -916,12 +968,19 @@ static void cfgst_pop (struct cfgst *cfgst)
cfgst->path_depth--;
}
-static const struct cfgelem *cfgst_tos (const struct cfgst *cfgst)
+static const struct cfgelem *cfgst_tos_w_isattr (const struct cfgst *cfgst, bool *isattr)
{
assert(cfgst->path_depth > 0);
+ *isattr = cfgst->isattr[cfgst->path_depth - 1];
return cfgst->path[cfgst->path_depth - 1];
}
+static const struct cfgelem *cfgst_tos (const struct cfgst *cfgst)
+{
+ bool dummy_isattr;
+ return cfgst_tos_w_isattr (cfgst, &dummy_isattr);
+}
+
static void *cfgst_parent (const struct cfgst *cfgst)
{
assert(cfgst->path_depth > 0);
@@ -1043,10 +1102,22 @@ static size_t cfg_note (struct cfgst *cfgst, uint32_t cat, size_t bsz, const cha
}
cfg_note_snprintf (&bb, "%s", suffix);
+
+ if (cat & (DDS_LC_WARNING | DDS_LC_ERROR))
+ {
+ if (cfgst->input == NULL)
+ cfg_note_snprintf (&bb, " (line %d)", cfgst->line);
+ else
+ {
+ cfg_note_snprintf (&bb, " (%s line %d)", cfgst->input, cfgst->line);
+ cfgst->input = NULL;
+ }
+ }
+
if (cfgst->logcfg)
DDS_CLOG (cat, cfgst->logcfg, "%s\n", bb.buf);
else
- DDS_ILOG (cat, cfgst->domid, "%s\n", bb.buf);
+ DDS_ILOG (cat, cfgst->cfg->domainId, "%s\n", bb.buf);
ddsrt_free (bb.buf);
return 0;
@@ -1063,7 +1134,7 @@ static void cfg_warning (struct cfgst *cfgst, const char *fmt, ...)
} while (bsz > 0);
}
-static int cfg_error (struct cfgst *cfgst, const char *fmt, ...)
+static enum update_result cfg_error (struct cfgst *cfgst, const char *fmt, ...)
{
va_list ap;
size_t bsz = 0;
@@ -1072,10 +1143,10 @@ static int cfg_error (struct cfgst *cfgst, const char *fmt, ...)
bsz = cfg_note (cfgst, DDS_LC_ERROR, bsz, fmt, "", ap);
va_end (ap);
} while (bsz > 0);
- return 0;
+ return URES_ERROR;
}
-static int cfg_logelem (struct cfgst *cfgst, uint32_t sources, const char *fmt, ...)
+static void cfg_logelem (struct cfgst *cfgst, uint32_t sources, const char *fmt, ...)
{
/* 89 = 1 + 2 + 31 + 1 + 10 + 2*22: the number of characters in
a string formed by concatenating all numbers from 0 .. 31 in decimal notation,
@@ -1098,7 +1169,6 @@ static int cfg_logelem (struct cfgst *cfgst, uint32_t sources, const char *fmt,
bsz = cfg_note (cfgst, DDS_LC_CONFIG, bsz, fmt, srcinfo, ap);
va_end (ap);
} while (bsz > 0);
- return 0;
}
static int list_index (const char *list[], const char *elem)
@@ -1141,13 +1211,13 @@ static int64_t lookup_multiplier (struct cfgst *cfgst, const struct unit *unitta
static void *cfg_address (UNUSED_ARG (struct cfgst *cfgst), void *parent, struct cfgelem const * const cfgelem)
{
- assert (cfgelem->multiplicity == 1);
+ assert (cfgelem->multiplicity <= 1);
return (char *) parent + cfgelem->elem_offset;
}
static void *cfg_deref_address (UNUSED_ARG (struct cfgst *cfgst), void *parent, struct cfgelem const * const cfgelem)
{
- assert (cfgelem->multiplicity != 1);
+ assert (cfgelem->multiplicity > 1);
return *((void **) ((char *) parent + cfgelem->elem_offset));
}
@@ -1242,7 +1312,7 @@ static void pf_nop (UNUSED_ARG (struct cfgst *cfgst), UNUSED_ARG (void *parent),
{
}
-static int do_uint32_bitset (struct cfgst *cfgst, uint32_t *cats, const char **names, const uint32_t *codes, const char *value)
+static enum update_result do_uint32_bitset (struct cfgst *cfgst, uint32_t *cats, const char **names, const uint32_t *codes, const char *value)
{
char *copy = ddsrt_strdup (value), *cursor = copy, *tok;
while ((tok = ddsrt_strsep (&cursor, ",")) != NULL)
@@ -1250,14 +1320,14 @@ static int do_uint32_bitset (struct cfgst *cfgst, uint32_t *cats, const char **n
const int idx = list_index (names, tok);
if (idx < 0)
{
- const int ret = cfg_error (cfgst, "'%s' in '%s' undefined", tok, value);
+ const enum update_result ret = cfg_error (cfgst, "'%s' in '%s' undefined", tok, value);
ddsrt_free (copy);
return ret;
}
*cats |= codes[idx];
}
ddsrt_free (copy);
- return 1;
+ return URES_SUCCESS;
}
static unsigned uint32_popcnt (uint32_t x)
@@ -1318,7 +1388,7 @@ static void do_print_uint32_bitset (struct cfgst *cfgst, uint32_t mask, size_t n
cfg_logelem (cfgst, sources, "%s%s", res, suffix);
}
-static int uf_natint64_unit(struct cfgst *cfgst, int64_t *elem, const char *value, const struct unit *unittab, int64_t def_mult, int64_t min, int64_t max)
+static enum update_result uf_natint64_unit(struct cfgst *cfgst, int64_t *elem, const char *value, const struct unit *unittab, int64_t def_mult, int64_t min, int64_t max)
{
DDSRT_WARNING_MSVC_OFF(4996);
int pos;
@@ -1335,14 +1405,14 @@ static int uf_natint64_unit(struct cfgst *cfgst, int64_t *elem, const char *valu
if (v_int < 0 || v_int > max / mult || mult * v_int < min)
return cfg_error (cfgst, "%s: value out of range", value);
*elem = mult * v_int;
- return 1;
+ return URES_SUCCESS;
} else if (sscanf(value, "%lf%n", &v_dbl, &pos) == 1 && (mult = lookup_multiplier (cfgst, unittab, value, pos, v_dbl == 0, def_mult, 1)) != 0) {
double dmult = (double) mult;
assert (dmult > 0);
if ((int64_t) (v_dbl * dmult + 0.5) < min || (int64_t) (v_dbl * dmult + 0.5) > max)
return cfg_error(cfgst, "%s: value out of range", value);
*elem = (int64_t) (v_dbl * dmult + 0.5);
- return 1;
+ return URES_SUCCESS;
} else {
*elem = 0; /* some static analyzers don't "get it" */
return cfg_error (cfgst, "%s: invalid value", value);
@@ -1379,7 +1449,7 @@ static void pf_int64_unit (struct cfgst *cfgst, int64_t value, uint32_t sources,
DDSRT_STATIC_ASSERT (sizeof (en_##type_##_vs) / sizeof (*en_##type_##_vs) == \
sizeof (en_##type_##_ms) / sizeof (*en_##type_##_ms)); \
\
- static int uf_##type_ (struct cfgst *cfgst, void *parent, UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) \
+ static enum update_result uf_##type_ (struct cfgst *cfgst, void *parent, UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) \
{ \
const int idx = list_index (en_##type_##_vs, value); \
c_type_ * const elem = cfg_address (cfgst, parent, cfgelem); \
@@ -1387,7 +1457,7 @@ static void pf_int64_unit (struct cfgst *cfgst, int64_t value, uint32_t sources,
if (idx < 0 || idx >= (int) (sizeof (en_##type_##_ms) / sizeof (en_##type_##_ms[0]))) \
return cfg_error (cfgst, "'%s': undefined value", value); \
*elem = en_##type_##_ms[idx]; \
- return 1; \
+ return URES_SUCCESS; \
}
#define GENERIC_ENUM_CTYPE_PF(type_, c_type_) \
static void pf_##type_ (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources) \
@@ -1446,19 +1516,19 @@ static const enum nn_standards_conformance en_standards_conformance_ms[] = { NN_
GENERIC_ENUM_CTYPE (standards_conformance, enum nn_standards_conformance)
/* "trace" is special: it enables (nearly) everything */
-static const char *logcat_names[] = {
+static const char *tracemask_names[] = {
"fatal", "error", "warning", "info", "config", "discovery", "data", "radmin", "timing", "traffic", "topic", "tcp", "plist", "whc", "throttle", "rhc", "trace", NULL
};
-static const uint32_t logcat_codes[] = {
+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_ALL
};
-static int uf_logcat (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value)
+static enum update_result uf_tracemask (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value)
{
- return do_uint32_bitset (cfgst, &cfgst->cfg->enabled_logcats, logcat_names, logcat_codes, value);
+ return do_uint32_bitset (cfgst, &cfgst->cfg->tracemask, tracemask_names, tracemask_codes, value);
}
-static int uf_verbosity (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value)
+static enum update_result uf_verbosity (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value)
{
static const char *vs[] = {
"finest", "finer", "fine", "config", "info", "warning", "severe", "none", NULL
@@ -1471,21 +1541,22 @@ static int uf_verbosity (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_
if (idx < 0)
return cfg_error (cfgst, "'%s': undefined value", value);
for (int i = (int) (sizeof (vs) / sizeof (*vs)) - 1; i >= idx; i--)
- cfgst->cfg->enabled_logcats |= lc[i];
- return 1;
+ cfgst->cfg->tracemask |= lc[i];
+ return URES_SUCCESS;
}
-static void pf_logcat (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), uint32_t sources)
+static void pf_tracemask (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), uint32_t sources)
{
/* EnableCategory is also (and often) set by Verbosity, so make an effort to locate the sources for verbosity and merge them in */
struct cfgst_node *n;
struct cfgst_nodekey key;
- key.e = lookup_element ("CycloneDDS/Tracing/Verbosity");
+ bool isattr;
+ key.e = lookup_element ("CycloneDDS/Domain/Tracing/Verbosity", &isattr);
key.p = NULL;
assert (key.e != NULL);
if ((n = ddsrt_avl_lookup_succ_eq (&cfgst_found_treedef, &cfgst->found, &key)) != NULL && n->key.e == key.e)
sources |= n->sources;
- do_print_uint32_bitset (cfgst, cfgst->cfg->enabled_logcats, sizeof (logcat_codes) / sizeof (*logcat_codes), logcat_names, logcat_codes, sources, "");
+ do_print_uint32_bitset (cfgst, cfgst->cfg->tracemask, sizeof (tracemask_codes) / sizeof (*tracemask_codes), tracemask_names, tracemask_codes, sources, "");
}
static const char *xcheck_names[] = {
@@ -1495,7 +1566,7 @@ static const uint32_t xcheck_codes[] = {
DDS_XCHECK_WHC, DDS_XCHECK_RHC, ~(uint32_t) 0
};
-static int uf_xcheck (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_xcheck (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
uint32_t * const elem = cfg_address (cfgst, parent, cfgelem);
return do_uint32_bitset (cfgst, elem, xcheck_names, xcheck_codes, value);
@@ -1513,7 +1584,7 @@ static void pf_xcheck (struct cfgst *cfgst, void *parent, struct cfgelem const *
}
#ifdef DDSI_INCLUDE_SSL
-static int uf_min_tls_version (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value)
+static enum update_result uf_min_tls_version (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value)
{
static const char *vs[] = {
"1.2", "1.3", NULL
@@ -1527,7 +1598,7 @@ static int uf_min_tls_version (struct cfgst *cfgst, UNUSED_ARG (void *parent), U
if (idx < 0)
return cfg_error(cfgst, "'%s': undefined value", value);
*elem = ms[idx];
- return 1;
+ return URES_SUCCESS;
}
static void pf_min_tls_version (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
@@ -1537,11 +1608,11 @@ static void pf_min_tls_version (struct cfgst *cfgst, void *parent, struct cfgele
}
#endif
-static int uf_string (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_string (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
char ** const elem = cfg_address (cfgst, parent, cfgelem);
*elem = ddsrt_strdup (value);
- return 1;
+ return URES_SUCCESS;
}
static void pf_string (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
@@ -1551,25 +1622,25 @@ static void pf_string (struct cfgst *cfgst, void *parent, struct cfgelem const *
}
#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING
-static int uf_bandwidth (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_bandwidth (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
int64_t bandwidth_bps = 0;
if (strncmp (value, "inf", 3) == 0) {
/* special case: inf needs no unit */
uint32_t * const elem = cfg_address (cfgst, parent, cfgelem);
if (strspn (value + 3, " ") != strlen (value + 3) &&
- lookup_multiplier (cfgst, unittab_bandwidth_bps, value, 3, 1, 8, 1) == 0)
- return 0;
+ lo.up_multiplier (cfgst, unittab_bandwidth_bps, value, 3, 1, 8, 1) == 0)
+ return URES_ERROR;
*elem = 0;
- return 1;
- } else if (!uf_natint64_unit (cfgst, &bandwidth_bps, value, unittab_bandwidth_bps, 8, INT64_MAX)) {
- return 0;
+ return URES_SUCCESS;
+ } else if (uf_natint64_unit (cfgst, &bandwidth_bps, value, unittab_bandwidth_bps, 8, INT64_MAX) != URES_SUCCESS) {
+ return URES_ERROR;
} else if (bandwidth_bps / 8 > INT_MAX) {
return cfg_error (cfgst, "%s: value out of range", value);
} else {
uint32_t * const elem = cfg_address (cfgst, parent, cfgelem);
*elem = (uint32_t) (bandwidth_bps / 8);
- return 1;
+ return URES_SUCCESS;
}
}
@@ -1583,15 +1654,15 @@ static void pf_bandwidth(struct cfgst *cfgst, void *parent, struct cfgelem const
}
#endif
-static int uf_memsize (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_memsize (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
int64_t size = 0;
- if (!uf_natint64_unit (cfgst, &size, value, unittab_memsize, 1, 0, INT32_MAX))
- return 0;
+ if (uf_natint64_unit (cfgst, &size, value, unittab_memsize, 1, 0, INT32_MAX) != URES_SUCCESS)
+ return URES_ERROR;
else {
uint32_t * const elem = cfg_address (cfgst, parent, cfgelem);
*elem = (uint32_t) size;
- return 1;
+ return URES_SUCCESS;
}
}
@@ -1602,7 +1673,7 @@ static void pf_memsize (struct cfgst *cfgst, void *parent, struct cfgelem const
}
#ifdef DDSI_INCLUDE_ENCRYPTION
-static int uf_cipher(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG(int first), const char *value)
+static enum update_result uf_cipher(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG(int first), const char *value)
{
if (q_security_plugin.cipher_type_from_string)
{
@@ -1610,7 +1681,7 @@ static int uf_cipher(struct cfgst *cfgst, void *parent, struct cfgelem const * c
if (! q_security_plugin.cipher_type_from_string (value, elem))
return cfg_error (cfgst, "%s: undefined value", value);
}
- return 1;
+ return URES_SUCCESS;
}
static void pf_cipher (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
@@ -1626,20 +1697,20 @@ static void pf_key (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (
}
#endif /* DDSI_INCLUDE_ENCRYPTION */
-static int uf_tracingOutputFileName (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value)
+static enum update_result uf_tracingOutputFileName (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value)
{
struct config * const cfg = cfgst->cfg;
- cfg->tracingOutputFileName = ddsrt_strdup (value);
- return 1;
+ cfg->tracefile = ddsrt_strdup (value);
+ return URES_SUCCESS;
}
-static int uf_ipv4 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
+static enum update_result uf_ipv4 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
{
/* Not actually doing any checking yet */
return uf_string (cfgst, parent, cfgelem, first, value);
}
-static int uf_networkAddress (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
+static enum update_result uf_networkAddress (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
{
if (ddsrt_strcasecmp (value, "auto") != 0)
return uf_ipv4 (cfgst, parent, cfgelem, first, value);
@@ -1647,7 +1718,7 @@ static int uf_networkAddress (struct cfgst *cfgst, void *parent, struct cfgelem
{
char ** const elem = cfg_address (cfgst, parent, cfgelem);
*elem = NULL;
- return 1;
+ return URES_SUCCESS;
}
}
@@ -1657,7 +1728,7 @@ static void pf_networkAddress (struct cfgst *cfgst, void *parent, struct cfgelem
cfg_logelem (cfgst, sources, "%s", *p ? *p : "auto");
}
-static int uf_networkAddresses_simple (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_networkAddresses_simple (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
char *** const elem = cfg_address (cfgst, parent, cfgelem);
if ((*elem = ddsrt_malloc (2 * sizeof(char *))) == NULL)
@@ -1668,10 +1739,10 @@ static int uf_networkAddresses_simple (struct cfgst *cfgst, void *parent, struct
return cfg_error (cfgst, "out of memory");
}
(*elem)[1] = NULL;
- return 1;
+ return URES_SUCCESS;
}
-static int uf_networkAddresses (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
+static enum update_result uf_networkAddresses (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
{
/* Check for keywords first */
{
@@ -1716,7 +1787,7 @@ static int uf_networkAddresses (struct cfgst *cfgst, void *parent, struct cfgele
}
ddsrt_free (copy);
}
- return 1;
+ return URES_SUCCESS;
}
static void pf_networkAddresses (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
@@ -1742,13 +1813,13 @@ static const char *allow_multicast_names[] = { "false", "spdp", "asm", "true", N
static const uint32_t allow_multicast_codes[] = { AMC_FALSE, AMC_SPDP, AMC_ASM, AMC_TRUE };
#endif
-static int uf_allow_multicast (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG(int first), const char *value)
+static enum update_result uf_allow_multicast (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG(int first), const char *value)
{
uint32_t * const elem = cfg_address (cfgst, parent, cfgelem);
if (ddsrt_strcasecmp (value, "default") == 0)
{
*elem = AMC_DEFAULT;
- return 1;
+ return URES_SUCCESS;
}
else
{
@@ -1770,7 +1841,7 @@ static void pf_allow_multicast(struct cfgst *cfgst, void *parent, struct cfgelem
}
}
-static int uf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
DDSRT_WARNING_MSVC_OFF(4996);
struct config_maybe_int32 * const elem = cfg_address (cfgst, parent, cfgelem);
@@ -1778,10 +1849,10 @@ static int uf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem con
if (ddsrt_strcasecmp (value, "default") == 0) {
elem->isdefault = 1;
elem->value = 0;
- return 1;
+ return URES_SUCCESS;
} else if (sscanf (value, "%"SCNd32"%n", &elem->value, &pos) == 1 && value[pos] == 0) {
elem->isdefault = 0;
- return 1;
+ return URES_SUCCESS;
} else {
return cfg_error (cfgst, "'%s': neither 'default' nor a decimal integer\n", value);
}
@@ -1797,20 +1868,20 @@ static void pf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem co
cfg_logelem (cfgst, sources, "%d", p->value);
}
-static int uf_maybe_memsize (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_maybe_memsize (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
struct config_maybe_uint32 * const elem = cfg_address (cfgst, parent, cfgelem);
int64_t size = 0;
if (ddsrt_strcasecmp (value, "default") == 0) {
elem->isdefault = 1;
elem->value = 0;
- return 1;
- } else if (!uf_natint64_unit (cfgst, &size, value, unittab_memsize, 1, 0, INT32_MAX)) {
- return 0;
+ return URES_SUCCESS;
+ } else if (uf_natint64_unit (cfgst, &size, value, unittab_memsize, 1, 0, INT32_MAX) != URES_SUCCESS) {
+ return URES_ERROR;
} else {
elem->isdefault = 0;
elem->value = (uint32_t) size;
- return 1;
+ return URES_SUCCESS;
}
}
@@ -1823,7 +1894,7 @@ static void pf_maybe_memsize (struct cfgst *cfgst, void *parent, struct cfgelem
pf_int64_unit (cfgst, p->value, sources, unittab_memsize, "B");
}
-static int uf_int (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_int (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
int * const elem = cfg_address (cfgst, parent, cfgelem);
char *endptr;
@@ -1833,18 +1904,18 @@ static int uf_int (struct cfgst *cfgst, void *parent, struct cfgelem const * con
if (v != (int) v)
return cfg_error (cfgst, "%s: value out of range", value);
*elem = (int) v;
- return 1;
+ return URES_SUCCESS;
}
-static int uf_int_min_max (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value, int min, int max)
+static enum update_result uf_int_min_max (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value, int min, int max)
{
int *elem = cfg_address (cfgst, parent, cfgelem);
- if (!uf_int (cfgst, parent, cfgelem, first, value))
- return 0;
+ if (uf_int (cfgst, parent, cfgelem, first, value) != URES_SUCCESS)
+ return URES_ERROR;
else if (*elem < min || *elem > max)
return cfg_error (cfgst, "%s: out of range", value);
else
- return 1;
+ return URES_SUCCESS;
}
static void pf_int (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
@@ -1853,22 +1924,22 @@ static void pf_int (struct cfgst *cfgst, void *parent, struct cfgelem const * co
cfg_logelem (cfgst, sources, "%d", *p);
}
-static int uf_dyn_port(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
+static enum update_result uf_dyn_port(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
{
return uf_int_min_max(cfgst, parent, cfgelem, first, value, -1, 65535);
}
-static int uf_natint(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
+static enum update_result uf_natint(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
{
return uf_int_min_max(cfgst, parent, cfgelem, first, value, 0, INT32_MAX);
}
-static int uf_natint_255(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
+static enum update_result uf_natint_255(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
{
return uf_int_min_max(cfgst, parent, cfgelem, first, value, 0, 255);
}
-static int uf_uint (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_uint (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
unsigned * const elem = cfg_address (cfgst, parent, cfgelem);
char *endptr;
@@ -1878,7 +1949,7 @@ static int uf_uint (struct cfgst *cfgst, void *parent, struct cfgelem const * co
if (v != (unsigned) v)
return cfg_error (cfgst, "%s: value out of range", value);
*elem = (unsigned) v;
- return 1;
+ return URES_SUCCESS;
}
static void pf_uint (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
@@ -1887,49 +1958,49 @@ static void pf_uint (struct cfgst *cfgst, void *parent, struct cfgelem const * c
cfg_logelem (cfgst, sources, "%u", *p);
}
-static int uf_port(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
+static enum update_result uf_port(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
{
int *elem = cfg_address (cfgst, parent, cfgelem);
- if (!uf_uint (cfgst, parent, cfgelem, first, value))
- return 0;
+ if (uf_uint (cfgst, parent, cfgelem, first, value) != URES_SUCCESS)
+ return URES_ERROR;
else if (*elem < 1 || *elem > 65535)
return cfg_error (cfgst, "%s: out of range", value);
else
- return 1;
+ return URES_SUCCESS;
}
-static int uf_duration_gen (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, const char *value, int64_t def_mult, int64_t min_ns, int64_t max_ns)
+static enum update_result uf_duration_gen (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, const char *value, int64_t def_mult, int64_t min_ns, int64_t max_ns)
{
return uf_natint64_unit (cfgst, cfg_address (cfgst, parent, cfgelem), value, unittab_duration, def_mult, min_ns, max_ns);
}
-static int uf_duration_inf (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_duration_inf (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
if (ddsrt_strcasecmp (value, "inf") == 0) {
int64_t * const elem = cfg_address (cfgst, parent, cfgelem);
*elem = T_NEVER;
- return 1;
+ return URES_SUCCESS;
} else {
return uf_duration_gen (cfgst, parent, cfgelem, value, 0, 0, T_NEVER - 1);
}
}
-static int uf_duration_ms_1hr (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_duration_ms_1hr (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
return uf_duration_gen (cfgst, parent, cfgelem, value, T_MILLISECOND, 0, 3600 * T_SECOND);
}
-static int uf_duration_ms_1s (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_duration_ms_1s (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
return uf_duration_gen (cfgst, parent, cfgelem, value, T_MILLISECOND, 0, T_SECOND);
}
-static int uf_duration_us_1s (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_duration_us_1s (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
return uf_duration_gen (cfgst, parent, cfgelem, value, 1000, 0, T_SECOND);
}
-static int uf_duration_100ms_1hr (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_duration_100ms_1hr (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
return uf_duration_gen (cfgst, parent, cfgelem, value, 0, 100 * T_MILLISECOND, 3600 * T_SECOND);
}
@@ -1943,42 +2014,56 @@ static void pf_duration (struct cfgst *cfgst, void *parent, struct cfgelem const
pf_int64_unit (cfgst, *elem, sources, unittab_duration, "s");
}
-static int uf_domainId (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
+static enum update_result uf_domainId (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value)
{
DDSRT_WARNING_MSVC_OFF(4996);
- struct config_maybe_uint32 * const elem = cfg_address (cfgst, parent, cfgelem);
+ uint32_t * const elem = cfg_address (cfgst, parent, cfgelem);
+ uint32_t tmpval;
int pos;
if (ddsrt_strcasecmp (value, "any") == 0) {
- elem->isdefault = 1;
- elem->value = 0;
- return 1;
- } else if (sscanf (value, "%"SCNu32"%n", &elem->value, &pos) == 1 && value[pos] == 0 && elem->value != (uint32_t) 0xffffffff) {
- elem->isdefault = 0;
- return 1;
+ return URES_SUCCESS;
+ } else if (sscanf (value, "%"SCNu32"%n", &tmpval, &pos) == 1 && value[pos] == 0 && tmpval != UINT32_MAX) {
+ if (*elem == UINT32_MAX || *elem == tmpval)
+ {
+ if (!cfgst->first_data_in_source)
+ cfg_warning (cfgst, "not the first data in this source for compatible domain id");
+ *elem = tmpval;
+ return URES_SUCCESS;
+ }
+ else if (!cfgst->first_data_in_source)
+ {
+ /* something has been set and we can't undo any earlier assignments, so this is an error */
+ return cfg_error (cfgst, "not the first data in this source for incompatible domain id");
+ }
+ else
+ {
+ //cfg_warning (cfgst, "%"PRIu32" is incompatible with domain id being configured (%"PRIu32"), skipping", tmpval, elem->value);
+ return URES_SKIP_ELEMENT;
+ }
} else {
- return cfg_error (cfgst, "'%s': neither 'any' nor a less than 2**32-1\n", value);
+ return cfg_error (cfgst, "'%s': neither 'any' nor a less than 2**32-1", value);
}
DDSRT_WARNING_MSVC_ON(4996);
}
static void pf_domainId(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
{
- struct config_maybe_uint32 const * const p = cfg_address (cfgst, parent, cfgelem);
- if (p->isdefault)
- cfg_logelem (cfgst, sources, "any (%"PRIu32")", p->value);
+ uint32_t const * const p = cfg_address (cfgst, parent, cfgelem);
+ if (*p == UINT32_MAX)
+ cfg_logelem (cfgst, sources, "any");
else
- cfg_logelem (cfgst, sources, "%"PRIu32, p->value);
+ cfg_logelem (cfgst, sources, "%"PRIu32, *p);
}
-static int uf_participantIndex (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
+static enum update_result uf_participantIndex (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
{
int * const elem = cfg_address (cfgst, parent, cfgelem);
if (ddsrt_strcasecmp (value, "auto") == 0) {
*elem = PARTICIPANT_INDEX_AUTO;
- return 1;
+ return URES_SUCCESS;
} else if (ddsrt_strcasecmp (value, "none") == 0) {
*elem = PARTICIPANT_INDEX_NONE;
- return 1;
+ return URES_SUCCESS;
} else {
return uf_int_min_max (cfgst, parent, cfgelem, first, value, 0, 120);
}
@@ -2001,7 +2086,7 @@ static void pf_participantIndex (struct cfgst *cfgst, void *parent, struct cfgel
}
}
-static int uf_deaf_mute (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
+static enum update_result uf_deaf_mute (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
{
return uf_boolean (cfgst, parent, cfgelem, first, value);
}
@@ -2029,29 +2114,35 @@ static struct cfgst_node *lookup_or_create_elem_record (struct cfgst *cfgst, str
return n;
}
-static int do_update (struct cfgst *cfgst, update_fun_t upd, void *parent, struct cfgelem const * const cfgelem, const char *value, uint32_t source)
+static enum update_result do_update (struct cfgst *cfgst, update_fun_t upd, void *parent, struct cfgelem const * const cfgelem, const char *value, uint32_t source)
{
struct cfgst_node *n;
- int ok;
+ enum update_result res;
n = lookup_or_create_elem_record (cfgst, cfgelem, parent, source);
if (cfgelem->multiplicity == 1 && n->count == 1 && source > n->sources)
free_configured_element (cfgst, parent, cfgelem);
if (cfgelem->multiplicity == 0 || n->count < cfgelem->multiplicity)
- ok = upd (cfgst, parent, cfgelem, (n->count == n->failed), value);
+ res = upd (cfgst, parent, cfgelem, (n->count == n->failed), value);
else
- ok = cfg_error (cfgst, "only %d instance%s allowed", cfgelem->multiplicity, (cfgelem->multiplicity == 1) ? "" : "s");
+ res = cfg_error (cfgst, "only %d instance%s allowed", cfgelem->multiplicity, (cfgelem->multiplicity == 1) ? "" : "s");
n->count++;
n->sources |= source;
- if (!ok)
+ /* deciding to skip an entire subtree in the config is not an error */
+ if (res == URES_ERROR)
n->failed++;
- return ok;
+ return res;
}
static int set_default (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem)
{
+ enum update_result res;
if (cfgelem->defvalue == NULL)
- return cfg_error (cfgst, "element missing in configuration");
- return do_update (cfgst, cfgelem->update, parent, cfgelem, cfgelem->defvalue, 0);
+ {
+ cfg_error (cfgst, "element missing in configuration");
+ return 0;
+ }
+ res = do_update (cfgst, cfgelem->update, parent, cfgelem, cfgelem->defvalue, 0);
+ return (res != URES_ERROR);
}
static int set_defaults (struct cfgst *cfgst, void *parent, int isattr, struct cfgelem const * const cfgelem)
@@ -2064,7 +2155,7 @@ static int set_defaults (struct cfgst *cfgst, void *parent, int isattr, struct c
key.e = ce;
key.p = parent;
cfgst_push (cfgst, isattr, ce, parent);
- if (ce->multiplicity == 1)
+ if (ce->multiplicity <= 1)
{
if ((n = ddsrt_avl_lookup (&cfgst_found_treedef, &cfgst->found, &key)) == NULL)
{
@@ -2102,7 +2193,7 @@ static void print_configitems (struct cfgst *cfgst, void *parent, int isattr, st
if ((n = ddsrt_avl_lookup(&cfgst_found_treedef, &cfgst->found, &key)) != NULL)
sources = n->sources;
- if (ce->multiplicity == 1)
+ if (ce->multiplicity <= 1)
{
cfgst_push (cfgst, 0, NULL, NULL);
if (ce->print)
@@ -2144,7 +2235,7 @@ static void free_all_elements (struct cfgst *cfgst, void *parent, struct cfgelem
if (ce->free)
ce->free (cfgst, parent, ce);
- if (ce->multiplicity == 1) {
+ if (ce->multiplicity <= 1) {
if (ce->children)
free_all_elements (cfgst, parent, ce->children);
if (ce->attributes)
@@ -2179,7 +2270,7 @@ static void free_configured_element (struct cfgst *cfgst, void *parent, struct c
n->count = n->failed = 0;
}
- if (ce->multiplicity == 1)
+ if (ce->multiplicity <= 1)
{
if (ce->children)
free_configured_elements (cfgst, parent, ce->children);
@@ -2229,46 +2320,69 @@ static int matching_name_index (const char *name_w_aliases, const char *name)
return (ddsrt_strcasecmp (ns, name) == 0) ? idx : -1;
}
-static const struct cfgelem *lookup_element (const char *target)
+static const struct cfgelem *lookup_element (const char *target, bool *isattr)
{
const struct cfgelem *cfgelem = cyclonedds_root_cfgelems;
char *target_copy = ddsrt_strdup (target);
- const char *p = target_copy;
+ char *p = target_copy;
+ *isattr = false;
while (p)
{
- char *p1 = strchr (p, '/');
- if (p1)
- *p1++ = 0;
+ char *p1 = p + strcspn (p, "/[");
+ switch (*p1)
+ {
+ case '\0':
+ p1 = NULL;
+ break;
+ case '/':
+ *p1++ = 0;
+ break;
+ case '[':
+ assert (p1[1] == '@' && p1[strlen (p1) - 1] == ']');
+ p1[strlen (p1) - 1] = 0;
+ *p1 = 0; p1 += 2;
+ *isattr = true;
+ break;
+ default:
+ assert (0);
+ }
for (; cfgelem->name; cfgelem++)
{
- /* not supporting chained redirects */
- assert (cfgelem->name[0] != '>');
if (matching_name_index (cfgelem->name, p) >= 0)
+ {
+ /* not supporting chained redirects */
+ assert (cfgelem->name[0] != '>');
break;
+ }
}
if (p1)
- cfgelem = cfgelem->children;
+ cfgelem = *isattr ? cfgelem->attributes : cfgelem->children;
p = p1;
}
ddsrt_free (target_copy);
return cfgelem;
}
-static int proc_elem_open (void *varg, UNUSED_ARG (uintptr_t parentinfo), UNUSED_ARG (uintptr_t *eleminfo), const char *name)
+static int proc_elem_open (void *varg, UNUSED_ARG (uintptr_t parentinfo), UNUSED_ARG (uintptr_t *eleminfo), const char *name, int line)
{
struct cfgst * const cfgst = varg;
+ cfgst->line = line;
if (cfgst->implicit_toplevel == ITL_ALLOWED)
{
- assert (cyclonedds_root_cfgelems[1].name == NULL);
- if (ddsrt_strcasecmp (name, cyclonedds_root_cfgelems[0].name) == 0)
+ if (ddsrt_strcasecmp (name, "CycloneDDS") == 0)
cfgst->implicit_toplevel = ITL_DISALLOWED;
else
{
- int x = proc_elem_open (cfgst, 0, 0, cyclonedds_root_cfgelems[0].name);
- assert (x > 0);
- (void) x;
- cfgst->implicit_toplevel = ITL_INSERTED;
+ cfgst_push (cfgst, 0, &cyclonedds_root_cfgelems[0], cfgst_parent (cfgst));
+ /* Most likely one would want to override some domain settings without bothering,
+ so also allow an implicit "Domain" */
+ cfgst->implicit_toplevel = ITL_INSERTED_1;
+ if (ddsrt_strcasecmp (name, "Domain") != 0)
+ {
+ cfgst_push (cfgst, 0, &root_cfgelems[0], cfgst_parent (cfgst));
+ cfgst->implicit_toplevel = ITL_INSERTED_2;
+ }
}
}
@@ -2324,7 +2438,8 @@ static int proc_elem_open (void *varg, UNUSED_ARG (uintptr_t parentinfo), UNUSED
if (moved)
{
struct cfgelem const * const cfg_subelem_orig = cfg_subelem;
- cfg_subelem = lookup_element (cfg_subelem->defvalue);
+ bool isattr;
+ cfg_subelem = lookup_element (cfg_subelem->defvalue, &isattr);
cfgst_push (cfgst, 0, cfg_subelem_orig, NULL);
cfg_warning (cfgst, "setting%s moved to //%s", cfg_subelem->children ? "s" : "", cfg_subelem_orig->defvalue);
cfgst_pop (cfgst);
@@ -2338,7 +2453,7 @@ static int proc_elem_open (void *varg, UNUSED_ARG (uintptr_t parentinfo), UNUSED
return 0;
}
- if (cfg_subelem->multiplicity == 1)
+ if (cfg_subelem->multiplicity <= 1)
dynparent = parent;
else
dynparent = cfg_deref_address (cfgst, parent, cfg_subelem);
@@ -2346,58 +2461,108 @@ static int proc_elem_open (void *varg, UNUSED_ARG (uintptr_t parentinfo), UNUSED
cfgst_push (cfgst, 0, cfg_subelem, dynparent);
if (cfg_subelem == &cyclonedds_root_cfgelems[0])
+ {
cfgst->source = (cfgst->source == 0) ? 1 : cfgst->source << 1;
+ cfgst->first_data_in_source = true;
+ }
+ else if (cfg_subelem >= &root_cfgelems[0] && cfg_subelem < &root_cfgelems[0] + sizeof (root_cfgelems) / sizeof (root_cfgelems[0]))
+ {
+ if (!cfgst->first_data_in_source)
+ cfgst->source = (cfgst->source == 0) ? 1 : cfgst->source << 1;
+ cfgst->first_data_in_source = true;
+ }
return 1;
}
}
-static int proc_update_cfgelem (struct cfgst * cfgst, const struct cfgelem *ce, const char *value, bool isattr)
+static int proc_update_cfgelem (struct cfgst *cfgst, const struct cfgelem *ce, const char *value, bool isattr)
{
void *parent = cfgst_parent (cfgst);
- char *xvalue = ddsrt_expand_envvars (value, cfgst->domid);
- int ok;
+ char *xvalue = ddsrt_expand_envvars (value, cfgst->cfg->domainId);
+ enum update_result res;
cfgst_push (cfgst, isattr, isattr ? ce : NULL, parent);
- ok = do_update (cfgst, ce->update, parent, ce, xvalue, cfgst->source);
+ res = do_update (cfgst, ce->update, parent, ce, xvalue, cfgst->source);
cfgst_pop (cfgst);
ddsrt_free (xvalue);
- return ok;
+
+ /* Push a marker that we are to ignore this part of the DOM tree -- see the
+ handling of WILDCARD ("*"). This is currently only used for domain ids,
+ and there it is either:
+ - , in which case the element at the top of the stack is
+ Domain, which is the element to ignore, or:
+ - X, in which case the element at the top of the stack Id,
+ and we need to strip ignore the one that is one down.
+
+ The configuration processing doesn't allow an element to contain text and
+ have children at the same time, and with that restriction it never makes
+ sense to ignore just the TOS element if it is text: that would be better
+ done in the update function itself.
+
+ So replacing the top stack entry for an attribute and the top two entries
+ if it's text is a reasonable interpretation of SKIP. And it seems quite
+ likely that it won't be used for anything else ... */
+ if (res == URES_SKIP_ELEMENT)
+ {
+ cfgst_pop (cfgst);
+ if (!isattr)
+ {
+ cfgst_pop (cfgst);
+ cfgst_push (cfgst, 0, NULL, NULL);
+ }
+ cfgst_push (cfgst, 0, NULL, NULL);
+ }
+ else
+ {
+ cfgst->first_data_in_source = false;
+ }
+ return res != URES_ERROR;
}
-static int proc_attr(void *varg, UNUSED_ARG (uintptr_t eleminfo), const char *name, const char *value)
+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 cfgst * const cfgst = varg;
const struct cfgelem *cfgelem = cfgst_tos (cfgst);
const struct cfgelem *cfg_attr;
+ cfgst->line = line;
if (cfgelem == NULL)
return 1;
for (cfg_attr = cfgelem->attributes; cfg_attr && cfg_attr->name; cfg_attr++)
if (ddsrt_strcasecmp(cfg_attr->name, name) == 0)
break;
- if (cfg_attr == NULL || cfg_attr->name == NULL)
- return cfg_error (cfgst, "%s: unknown attribute", name);
- else
+ if (cfg_attr != NULL && cfg_attr->name != NULL)
return proc_update_cfgelem (cfgst, cfg_attr, value, true);
+ else
+ {
+ cfg_error (cfgst, "%s: unknown attribute", name);
+ return 0;
+ }
}
-static int proc_elem_data (void *varg, UNUSED_ARG (uintptr_t eleminfo), const char *value)
+static int proc_elem_data (void *varg, UNUSED_ARG (uintptr_t eleminfo), const char *value, int line)
{
struct cfgst * const cfgst = varg;
- const struct cfgelem *cfgelem = cfgst_tos (cfgst);
+ bool isattr; /* elem may have been moved to an attr */
+ const struct cfgelem *cfgelem = cfgst_tos_w_isattr (cfgst, &isattr);
+ cfgst->line = line;
if (cfgelem == NULL)
return 1;
- if (cfgelem->update == 0)
- return cfg_error (cfgst, "%s: no data expected", value);
+ if (cfgelem->update != 0)
+ return proc_update_cfgelem (cfgst, cfgelem, value, isattr);
else
- return proc_update_cfgelem (cfgst, cfgelem, value, false);
+ {
+ cfg_error (cfgst, "%s: no data expected", value);
+ return 0;
+ }
}
-static int proc_elem_close (void *varg, UNUSED_ARG (uintptr_t eleminfo))
+static int proc_elem_close (void *varg, UNUSED_ARG (uintptr_t eleminfo), int line)
{
struct cfgst * const cfgst = varg;
const struct cfgelem * cfgelem = cfgst_tos (cfgst);
int ok = 1;
- if (cfgelem && cfgelem->multiplicity != 1)
+ cfgst->line = line;
+ if (cfgelem && cfgelem->multiplicity > 1)
{
void *parent = cfgst_parent (cfgst);
int ok1;
@@ -2540,16 +2705,19 @@ struct cfgst *config_init (const char *configfile, struct config *cfg, uint32_t
cfgst->error = 0;
cfgst->source = 0;
cfgst->logcfg = NULL;
- cfgst->domid = domid;
+ cfgst->first_data_in_source = true;
+ cfgst->input = "init";
+ cfgst->line = 1;
/* eventually, we domainId.value will be the real domain id selected, even if it was configured
to the default of "any" and has "isdefault" set; initializing it to the default-default
value of 0 means "any" in the config & DDS_DOMAIN_DEFAULT in create participant automatically
ends up on the right value */
- cfgst->cfg->domainId.value = 0;
+ cfgst->cfg->domainId = domid;
/* configfile == NULL will get you the default configuration */
if (configfile) {
+ char env_input[32];
char *copy = ddsrt_strdup (configfile), *cursor = copy;
struct ddsrt_xmlp_callbacks cb;
@@ -2573,6 +2741,9 @@ struct cfgst *config_init (const char *configfile, struct config *cfg, uint32_t
qx = ddsrt_xmlp_new_string (tok, cfgst, &cb);
ddsrt_xmlp_set_options (qx, DDSRT_XMLP_ANONYMOUS_CLOSE_TAG | DDSRT_XMLP_MISSING_CLOSE_AS_EOF);
fp = NULL;
+ snprintf (env_input, sizeof (env_input), "CYCLONEDDS_URI+%u", (unsigned) (tok - copy));
+ cfgst->input = env_input;
+ cfgst->line = 1;
}
else if ((fp = config_open_file (tok, &cursor, domid)) == NULL)
{
@@ -2582,14 +2753,17 @@ struct cfgst *config_init (const char *configfile, struct config *cfg, uint32_t
else
{
qx = ddsrt_xmlp_new_file (fp, cfgst, &cb);
+ cfgst->input = tok;
+ cfgst->line = 1;
}
cfgst->implicit_toplevel = (fp == NULL) ? ITL_ALLOWED : ITL_DISALLOWED;
+ cfgst->first_data_in_source = true;
cfgst_push (cfgst, 0, &root_cfgelem, cfgst->cfg);
ok = (ddsrt_xmlp_parse (qx) >= 0) && !cfgst->error;
assert (!ok ||
- (cfgst->path_depth == 1 && cfgst->implicit_toplevel != ITL_INSERTED) ||
- (cfgst->path_depth == 2 && cfgst->implicit_toplevel == ITL_INSERTED));
+ (cfgst->path_depth == 1 && cfgst->implicit_toplevel == ITL_DISALLOWED) ||
+ (cfgst->path_depth == 1 + (int) cfgst->implicit_toplevel));
/* Pop until stack empty: error handling is rather brutal */
while (cfgst->path_depth > 0)
cfgst_pop (cfgst);
@@ -2598,7 +2772,7 @@ struct cfgst *config_init (const char *configfile, struct config *cfg, uint32_t
else if (ok)
cursor = tok + ddsrt_xmlp_get_bufpos (qx);
ddsrt_xmlp_free (qx);
- assert (fp == NULL || cfgst->implicit_toplevel != ITL_INSERTED);
+ assert (fp == NULL || cfgst->implicit_toplevel <= ITL_ALLOWED);
if (cursor)
{
while (*cursor && (isspace ((unsigned char) cursor[0]) || cursor[0] == ','))
@@ -2612,6 +2786,13 @@ struct cfgst *config_init (const char *configfile, struct config *cfg, uint32_t
for, signal errors for things unset but without a default. */
ok = ok && set_defaults (cfgst, cfgst->cfg, 0, root_cfgelems);
+ /* Domain id UINT32_MAX can only happen if the application specified DDS_DOMAIN_DEFAULT
+ and the configuration has "any" (either explicitly or as a default). In that case,
+ default to 0. (Leaving it as UINT32_MAX while reading the config has the advantage
+ of warnings/errors being output without a domain id present. */
+ if (cfgst->cfg->domainId == UINT32_MAX)
+ cfgst->cfg->domainId = 0;
+
/* Compatibility settings of IPv6, TCP -- a bit too complicated for
the poor framework */
{
@@ -2786,8 +2967,8 @@ void config_fini (struct cfgst *cfgst)
free_all_elements (cfgst, cfgst->cfg, root_cfgelems);
dds_set_log_file (stderr);
dds_set_trace_file (stderr);
- if (cfgst->cfg->tracingOutputFile && cfgst->cfg->tracingOutputFile != stdout && cfgst->cfg->tracingOutputFile != stderr) {
- fclose(cfgst->cfg->tracingOutputFile);
+ if (cfgst->cfg->tracefp && cfgst->cfg->tracefp != stdout && cfgst->cfg->tracefp != stderr) {
+ fclose(cfgst->cfg->tracefp);
}
memset (cfgst->cfg, 0, sizeof (*cfgst->cfg));
ddsrt_avl_free (&cfgst_found_treedef, &cfgst->found, ddsrt_free);
diff --git a/src/core/ddsi/src/q_init.c b/src/core/ddsi/src/q_init.c
index 001590e..ab46018 100644
--- a/src/core/ddsi/src/q_init.c
+++ b/src/core/ddsi/src/q_init.c
@@ -76,7 +76,7 @@ static int make_uc_sockets (struct q_globals *gv, uint32_t * pdisc, uint32_t * p
if (gv->config.many_sockets_mode == MSM_NO_UNICAST)
{
assert (ppid == PARTICIPANT_INDEX_NONE);
- *pdata = *pdisc = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId.value);
+ *pdata = *pdisc = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId);
if (gv->config.allowMulticast)
{
/* FIXME: ugly hack - but we'll fix up after creating the multicast sockets */
@@ -87,7 +87,7 @@ static int make_uc_sockets (struct q_globals *gv, uint32_t * pdisc, uint32_t * p
if (ppid >= 0)
{
/* FIXME: verify port numbers are in range instead of truncating them like this */
- uint32_t base = gv->config.port_base + (gv->config.port_dg * gv->config.domainId.value) + ((uint32_t) ppid * gv->config.port_pg);
+ uint32_t base = gv->config.port_base + (gv->config.port_dg * gv->config.domainId) + ((uint32_t) ppid * gv->config.port_pg);
*pdisc = base + gv->config.port_d1;
*pdata = base + gv->config.port_d3;
}
@@ -286,7 +286,7 @@ static int string_to_default_locator (const struct q_globals *gv, nn_locator_t *
static int set_spdp_address (struct q_globals *gv)
{
- const uint32_t port = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId.value + gv->config.port_d0);
+ const uint32_t port = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId + gv->config.port_d0);
int rc = 0;
/* FIXME: FIXME: FIXME: */
gv->loc_spdp_mc.kind = NN_LOCATOR_KIND_INVALID;
@@ -318,7 +318,7 @@ static int set_spdp_address (struct q_globals *gv)
static int set_default_mc_address (struct q_globals *gv)
{
- const uint32_t port = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId.value + gv->config.port_d2);
+ const uint32_t port = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId + gv->config.port_d2);
int rc;
if (!gv->config.defaultMulticastAddressString)
gv->loc_default_mc = gv->loc_spdp_mc;
@@ -404,11 +404,11 @@ static int check_thread_properties (const struct q_globals *gv)
}
if (chanprefix[i] == NULL)
{
- DDS_ILOG (DDS_LC_ERROR, gv->config.domainId.value, "config: DDSI2Service/Threads/Thread[@name=\"%s\"]: unknown thread\n", e->name);
+ DDS_ILOG (DDS_LC_ERROR, gv->config.domainId, "config: DDSI2Service/Threads/Thread[@name=\"%s\"]: unknown thread\n", e->name);
ok = 0;
}
#else
- DDS_ILOG (DDS_LC_ERROR, gv->config.domainId.value, "config: DDSI2Service/Threads/Thread[@name=\"%s\"]: unknown thread\n", e->name);
+ DDS_ILOG (DDS_LC_ERROR, gv->config.domainId, "config: DDSI2Service/Threads/Thread[@name=\"%s\"]: unknown thread\n", e->name);
ok = 0;
#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */
}
@@ -416,30 +416,30 @@ static int check_thread_properties (const struct q_globals *gv)
return ok;
}
-int rtps_config_open (struct q_globals *gv)
+int rtps_config_open_trace (struct q_globals *gv)
{
DDSRT_WARNING_MSVC_OFF(4996);
int status;
- if (gv->config.tracingOutputFileName == NULL || *gv->config.tracingOutputFileName == 0 || gv->config.enabled_logcats == 0)
+ if (gv->config.tracefile == NULL || *gv->config.tracefile == 0 || gv->config.tracemask == 0)
{
- gv->config.enabled_logcats = 0;
- gv->config.tracingOutputFile = NULL;
+ gv->config.tracemask = 0;
+ gv->config.tracefp = NULL;
status = 1;
}
- else if (ddsrt_strcasecmp (gv->config.tracingOutputFileName, "stdout") == 0)
+ else if (ddsrt_strcasecmp (gv->config.tracefile, "stdout") == 0)
{
- gv->config.tracingOutputFile = stdout;
+ gv->config.tracefp = stdout;
status = 1;
}
- else if (ddsrt_strcasecmp (gv->config.tracingOutputFileName, "stderr") == 0)
+ else if (ddsrt_strcasecmp (gv->config.tracefile, "stderr") == 0)
{
- gv->config.tracingOutputFile = stderr;
+ gv->config.tracefp = stderr;
status = 1;
}
- else if ((gv->config.tracingOutputFile = fopen (gv->config.tracingOutputFileName, gv->config.tracingAppendToFile ? "a" : "w")) == NULL)
+ else if ((gv->config.tracefp = fopen (gv->config.tracefile, gv->config.tracingAppendToFile ? "a" : "w")) == NULL)
{
- DDS_ILOG (DDS_LC_ERROR, gv->config.domainId.value, "%s: cannot open for writing\n", gv->config.tracingOutputFileName);
+ DDS_ILOG (DDS_LC_ERROR, gv->config.domainId, "%s: cannot open for writing\n", gv->config.tracefile);
status = 0;
}
else
@@ -447,7 +447,7 @@ int rtps_config_open (struct q_globals *gv)
status = 1;
}
- dds_log_cfg_init (&gv->logconfig, gv->config.domainId.value, gv->config.enabled_logcats, stderr, gv->config.tracingOutputFile);
+ dds_log_cfg_init (&gv->logconfig, gv->config.domainId, gv->config.tracemask, stderr, gv->config.tracefp);
return status;
DDSRT_WARNING_MSVC_ON(4996);
}
@@ -466,7 +466,7 @@ int rtps_config_prep (struct q_globals *gv, struct cfgst *cfgst)
gv->config.whc_init_highwater_mark.value < gv->config.whc_lowwater_mark ||
gv->config.whc_init_highwater_mark.value > gv->config.whc_highwater_mark)
{
- DDS_ILOG (DDS_LC_ERROR, gv->config.domainId.value, "Invalid watermark settings\n");
+ DDS_ILOG (DDS_LC_ERROR, gv->config.domainId, "Invalid watermark settings\n");
goto err_config_late_error;
}
@@ -478,7 +478,7 @@ int rtps_config_prep (struct q_globals *gv, struct cfgst *cfgst)
inherited by readers/writers), but in many sockets mode each
participant has its own socket, and therefore unique address
set */
- DDS_ILOG (DDS_LC_ERROR, gv->config.domainId.value, "Minimal built-in endpoint set mode and ManySocketsMode are incompatible\n");
+ DDS_ILOG (DDS_LC_ERROR, gv->config.domainId, "Minimal built-in endpoint set mode and ManySocketsMode are incompatible\n");
goto err_config_late_error;
}
@@ -554,8 +554,8 @@ int rtps_config_prep (struct q_globals *gv, struct cfgst *cfgst)
}
#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */
- /* Open tracing file after all possible gv->config errors have been printed */
- if (! rtps_config_open (gv))
+ /* Open tracing file after all possible config errors have been printed */
+ if (! rtps_config_open_trace (gv))
{
goto err_config_late_error;
}
@@ -633,7 +633,7 @@ int joinleave_spdp_defmcip (struct q_globals *gv, int dojoin)
unref_addrset (as);
if (arg.errcount)
{
- GVERROR ("rtps_init: failed to join multicast groups for domain %"PRIu32" participant %d\n", gv->config.domainId.value, gv->config.participantIndex);
+ GVERROR ("rtps_init: failed to join multicast groups for domain %"PRIu32" participant %d\n", gv->config.domainId, gv->config.participantIndex);
return -1;
}
return 0;
@@ -647,7 +647,7 @@ int create_multicast_sockets (struct q_globals *gv)
qos->m_multicast = 1;
/* FIXME: should check for overflow */
- port = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId.value + gv->config.port_d0);
+ port = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId + gv->config.port_d0);
if ((disc = ddsi_factory_create_conn (gv->m_factory, port, qos)) == NULL)
goto err_disc;
if (gv->config.many_sockets_mode == MSM_NO_UNICAST)
@@ -657,7 +657,7 @@ int create_multicast_sockets (struct q_globals *gv)
}
else
{
- port = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId.value + gv->config.port_d2);
+ port = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId + gv->config.port_d2);
if ((data = ddsi_factory_create_conn (gv->m_factory, port, qos)) == NULL)
goto err_data;
}
@@ -984,7 +984,7 @@ int rtps_init (struct q_globals *gv)
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
/* Convert address sets in partition mappings from string to address sets */
{
- const uint32_t port = gv->config.port_base + gv->config.port_dg * gv->config.domainId.value + gv->config.port_d2;
+ const uint32_t port = gv->config.port_base + gv->config.port_dg * gv->config.domainId + gv->config.port_d2;
struct config_networkpartition_listelem *np;
for (np = gv->config.networkPartitions; np; np = np->next)
{
@@ -1056,7 +1056,7 @@ int rtps_init (struct q_globals *gv)
{
if (make_uc_sockets (gv, &port_disc_uc, &port_data_uc, gv->config.participantIndex) < 0)
{
- GVERROR ("rtps_init: failed to create unicast sockets for domain %"PRId32" participant %d\n", gv->config.domainId.value, gv->config.participantIndex);
+ GVERROR ("rtps_init: failed to create unicast sockets for domain %"PRId32" participant %d\n", gv->config.domainId, gv->config.participantIndex);
goto err_unicast_sockets;
}
}
@@ -1074,13 +1074,13 @@ int rtps_init (struct q_globals *gv)
continue;
else /* Oops! */
{
- GVERROR ("rtps_init: failed to create unicast sockets for domain %"PRId32" participant %d\n", gv->config.domainId.value, ppid);
+ GVERROR ("rtps_init: failed to create unicast sockets for domain %"PRId32" participant %d\n", gv->config.domainId, ppid);
goto err_unicast_sockets;
}
}
if (ppid > gv->config.maxAutoParticipantIndex)
{
- GVERROR ("rtps_init: failed to find a free participant index for domain %"PRId32"\n", gv->config.domainId.value);
+ GVERROR ("rtps_init: failed to find a free participant index for domain %"PRId32"\n", gv->config.domainId);
goto err_unicast_sockets;
}
gv->config.participantIndex = ppid;
@@ -1091,7 +1091,7 @@ int rtps_init (struct q_globals *gv)
}
GVLOG (DDS_LC_CONFIG, "rtps_init: uc ports: disc %"PRIu32" data %"PRIu32"\n", port_disc_uc, port_data_uc);
}
- GVLOG (DDS_LC_CONFIG, "rtps_init: domainid %"PRId32" participantid %d\n", gv->config.domainId.value, gv->config.participantIndex);
+ GVLOG (DDS_LC_CONFIG, "rtps_init: domainid %"PRId32" participantid %d\n", gv->config.domainId, gv->config.participantIndex);
if (gv->config.pcap_file && *gv->config.pcap_file)
{
diff --git a/src/ddsrt/include/dds/ddsrt/log.h b/src/ddsrt/include/dds/ddsrt/log.h
index ea6011b..d3fbc2b 100644
--- a/src/ddsrt/include/dds/ddsrt/log.h
+++ b/src/ddsrt/include/dds/ddsrt/log.h
@@ -109,11 +109,21 @@ typedef struct {
} dds_log_data_t;
/** Function signature that log and trace callbacks must adhere too. */
-typedef void(*dds_log_write_fn_t)(void *, const dds_log_data_t *);
+typedef void (*dds_log_write_fn_t) (void *, const dds_log_data_t *);
/** Semi-opaque type for log/trace configuration. */
struct ddsrt_log_cfg_common {
+ /** Mask for testing whether the xLOG macro should forward to the
+ function (and so incur the cost of constructing the parameters).
+ Messages in DDS_LOG_MASK are rare, so the overhead of calling
+ the function and then dropping the message is not an issue, unlike
+ for messages in DDS_TRACE_MASK. */
uint32_t mask;
+
+ /** The actual configured trace mask */
+ uint32_t tracemask;
+
+ /** Domain id for reporting; UINT32_MAX = no domain */
uint32_t domid;
};
@@ -225,7 +235,7 @@ dds_set_trace_sink(
* other parameters.
* @param[in] domid Numerical identifier in log/trace, UINT32_MAX is
* reserved for global logging.
- * @param[in] mask Mask determining what to log/trace.
+ * @param[in] tracemask Mask determining which traces should be written.
* @param[in] log_fp File for default sink.
* @param[in] trace_fp File for default sink.
*/
@@ -233,7 +243,7 @@ DDS_EXPORT void
dds_log_cfg_init(
struct ddsrt_log_cfg *cfg,
uint32_t domid,
- uint32_t mask,
+ uint32_t tracemask,
FILE *log_fp,
FILE *trace_fp);
@@ -244,7 +254,7 @@ dds_log_cfg_init(
* Direct use of #dds_log is discouraged. Use #DDS_CINFO, #DDS_CWARNING,
* #DDS_CERROR, #DDS_CTRACE or #DDS_CLOG instead.
*/
-DDS_EXPORT int
+DDS_EXPORT void
dds_log_cfg(
const struct ddsrt_log_cfg *cfg,
uint32_t prio,
@@ -264,7 +274,7 @@ dds_log_cfg(
*
* Direct use of #dds_log_id is discouraged. Use #DDS_ILOG instead.
*/
-DDS_EXPORT int
+DDS_EXPORT void
dds_log_id(
uint32_t prio,
uint32_t domid,
@@ -283,7 +293,7 @@ dds_log_id(
* Direct use of #dds_log is discouraged. Use #DDS_INFO, #DDS_WARNING,
* #DDS_ERROR, #DDS_FATAL or #DDS_LOG instead.
*/
-DDS_EXPORT int
+DDS_EXPORT void
dds_log(
uint32_t prio,
const char *file,
diff --git a/src/ddsrt/include/dds/ddsrt/xmlparser.h b/src/ddsrt/include/dds/ddsrt/xmlparser.h
index 9c29a89..93bd92d 100644
--- a/src/ddsrt/include/dds/ddsrt/xmlparser.h
+++ b/src/ddsrt/include/dds/ddsrt/xmlparser.h
@@ -20,10 +20,10 @@
extern "C" {
#endif
- typedef int (*ddsrt_xmlp_proc_elem_open_t) (void *varg, uintptr_t parentinfo, uintptr_t *eleminfo, const char *name);
- typedef int (*ddsrt_xmlp_proc_attr_t) (void *varg, uintptr_t eleminfo, const char *name, const char *value);
- typedef int (*ddsrt_xmlp_proc_elem_data_t) (void *varg, uintptr_t eleminfo, const char *data);
- typedef int (*ddsrt_xmlp_proc_elem_close_t) (void *varg, uintptr_t eleminfo);
+ typedef int (*ddsrt_xmlp_proc_elem_open_t) (void *varg, uintptr_t parentinfo, uintptr_t *eleminfo, const char *name, int line);
+ typedef int (*ddsrt_xmlp_proc_attr_t) (void *varg, uintptr_t eleminfo, const char *name, const char *value, int line);
+ typedef int (*ddsrt_xmlp_proc_elem_data_t) (void *varg, uintptr_t eleminfo, const char *data, int line);
+ typedef int (*ddsrt_xmlp_proc_elem_close_t) (void *varg, uintptr_t eleminfo, int line);
typedef void (*ddsrt_xmlp_error) (void *varg, const char *msg, int line);
struct ddsrt_xmlp_callbacks {
@@ -46,8 +46,6 @@ extern "C" {
DDS_EXPORT void ddsrt_xmlp_free (struct ddsrt_xmlp_state *st);
DDS_EXPORT int ddsrt_xmlp_parse (struct ddsrt_xmlp_state *st);
- DDS_EXPORT int ddsrt_xmlUnescapeInsitu (char *buffer, size_t *n);
-
#if defined (__cplusplus)
}
#endif
diff --git a/src/ddsrt/src/expand_envvars.c b/src/ddsrt/src/expand_envvars.c
index ea64a16..bd988c7 100644
--- a/src/ddsrt/src/expand_envvars.c
+++ b/src/ddsrt/src/expand_envvars.c
@@ -44,7 +44,7 @@ static char *expand_env (const char *name, char op, const char *alt, expand_fn e
} else if (strcmp (name, "$") == 0 || strcmp (name, "CYCLONEDDS_PID") == 0) {
snprintf (idstr, sizeof (idstr), "%"PRIdPID, ddsrt_getpid ());
env = idstr;
- } else if (strcmp (name, "CYCLONEDDS_DOMAIN_ID") == 0) {
+ } else if (strcmp (name, "CYCLONEDDS_DOMAIN_ID") == 0 && domid != UINT32_MAX) {
snprintf (idstr, sizeof (idstr), "%"PRIu32, domid);
env = idstr;
}
diff --git a/src/ddsrt/src/log.c b/src/ddsrt/src/log.c
index eeb7cae..b7aef78 100644
--- a/src/ddsrt/src/log.c
+++ b/src/ddsrt/src/log.c
@@ -33,7 +33,7 @@ typedef struct {
} log_buffer_t;
typedef struct {
- dds_log_write_fn_t funcs[2];
+ dds_log_write_fn_t func;
void *ptr;
FILE *out;
} log_sink_t;
@@ -52,25 +52,20 @@ DDSRT_STATIC_ASSERT (sizeof (struct ddsrt_log_cfg_impl) <= sizeof (struct ddsrt_
static void default_sink (void *ptr, const dds_log_data_t *data)
{
- fwrite (data->message - data->hdrsize, 1, data->hdrsize + data->size + 1, (FILE *) ptr);
- fflush ((FILE *) ptr);
-}
-
-static void nop_sink (void *ptr, const dds_log_data_t *data)
-{
- (void) ptr;
- (void) data;
- return;
+ if (ptr)
+ {
+ fwrite (data->message - data->hdrsize, 1, data->hdrsize + data->size + 1, (FILE *) ptr);
+ fflush ((FILE *) ptr);
+ }
}
#define LOG (0)
#define TRACE (1)
-#define USE (0)
-#define SET (1)
static struct ddsrt_log_cfg_impl logconfig = {
.c = {
.mask = DDS_LC_ERROR | DDS_LC_WARNING,
+ .tracemask = 0,
.domid = UINT32_MAX
},
.sink_fps = {
@@ -80,11 +75,11 @@ static struct ddsrt_log_cfg_impl logconfig = {
};
static log_sink_t sinks[2] = {
- [LOG] = { .funcs = { [USE] = default_sink, [SET] = default_sink }, .ptr = NULL, .out = NULL },
- [TRACE] = { .funcs = { [USE] = default_sink, [SET] = default_sink }, .ptr = NULL, .out = NULL }
+ [LOG] = { .func = default_sink, .ptr = NULL, .out = NULL },
+ [TRACE] = { .func = default_sink, .ptr = NULL, .out = NULL }
};
-uint32_t *const dds_log_mask = &logconfig.c.mask;
+uint32_t * const dds_log_mask = &logconfig.c.mask;
static void init_lock (void)
{
@@ -112,17 +107,6 @@ static void unlock_sink (void)
ddsrt_rwlock_unlock (&lock);
}
-static void set_active_log_sinks (void)
-{
- sinks[LOG].funcs[USE] = sinks[LOG].funcs[SET];
- sinks[TRACE].funcs[USE] = sinks[TRACE].funcs[SET];
- if (sinks[LOG].funcs[USE] == sinks[TRACE].funcs[USE])
- {
- if (sinks[LOG].funcs[USE] != default_sink && sinks[LOG].ptr == sinks[TRACE].ptr)
- sinks[LOG].funcs[USE] = nop_sink;
- }
-}
-
static void set_log_sink (log_sink_t *sink, dds_log_write_fn_t func, void *ptr)
{
assert (sink != NULL);
@@ -132,9 +116,8 @@ static void set_log_sink (log_sink_t *sink, dds_log_write_fn_t func, void *ptr)
responsible for that. Ensure this operation is deterministic and that on
return, no thread in the DDS stack still uses the deprecated sink. */
lock_sink (WRLOCK);
- sink->funcs[SET] = (func != 0) ? func : default_sink;
+ sink->func = (func != 0) ? func : default_sink;
sink->ptr = ptr;
- set_active_log_sinks ();
unlock_sink ();
}
@@ -143,7 +126,6 @@ void dds_set_log_file (FILE *file)
{
lock_sink (WRLOCK);
logconfig.sink_fps[LOG] = (file == NULL ? stderr : file);
- set_active_log_sinks ();
unlock_sink ();
}
@@ -151,7 +133,6 @@ void dds_set_trace_file (FILE *file)
{
lock_sink (WRLOCK);
logconfig.sink_fps[TRACE] = (file == NULL ? stderr : file);
- set_active_log_sinks ();
unlock_sink ();
}
@@ -170,17 +151,18 @@ extern inline uint32_t dds_get_log_mask (void);
void dds_set_log_mask (uint32_t cats)
{
lock_sink (WRLOCK);
- *dds_log_mask = (cats & (DDS_LOG_MASK | DDS_TRACE_MASK));
- set_active_log_sinks ();
+ logconfig.c.tracemask = cats & DDS_TRACE_MASK;
+ logconfig.c.mask = (cats & (DDS_LOG_MASK | DDS_TRACE_MASK)) | DDS_LC_FATAL;
unlock_sink ();
}
-void dds_log_cfg_init (struct ddsrt_log_cfg *cfg, uint32_t domid, uint32_t mask, FILE *log_fp, FILE *trace_fp)
+void dds_log_cfg_init (struct ddsrt_log_cfg *cfg, uint32_t domid, uint32_t tracemask, FILE *log_fp, FILE *trace_fp)
{
struct ddsrt_log_cfg_impl *cfgimpl = (struct ddsrt_log_cfg_impl *) cfg;
assert (domid != UINT32_MAX); /* because that's reserved for global use */
memset (cfgimpl, 0, sizeof (*cfgimpl));
- cfgimpl->c.mask = mask;
+ cfgimpl->c.mask = tracemask | DDS_LOG_MASK;
+ cfgimpl->c.tracemask = tracemask;
cfgimpl->c.domid = domid;
cfgimpl->sink_fps[LOG] = log_fp;
cfgimpl->sink_fps[TRACE] = trace_fp;
@@ -220,7 +202,7 @@ static size_t print_header (char *str, uint32_t id)
return (size_t) cnt;
}
-static void vlog (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t domid, const char *file, uint32_t line, const char *func, const char *fmt, va_list ap)
+static void vlog1 (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t domid, const char *file, uint32_t line, const char *func, const char *fmt, va_list ap)
{
int n, trunc = 0;
size_t nrem;
@@ -242,8 +224,8 @@ static void vlog (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t d
/* Thread-local buffer is always initialized with all zeroes. The pos
member must always be greater or equal to BUF_OFFSET. */
if (lb->pos < BUF_OFFSET) {
- lb->pos = BUF_OFFSET;
- lb->buf[lb->pos] = 0;
+ lb->pos = BUF_OFFSET;
+ lb->buf[lb->pos] = 0;
}
nrem = sizeof (lb->buf) - lb->pos;
if (nrem > 0) {
@@ -263,7 +245,8 @@ static void vlog (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t d
}
}
- if (fmt[strlen (fmt) - 1] == '\n') {
+ if (fmt[strlen (fmt) - 1] == '\n' && lb->pos > BUF_OFFSET + 1) {
+ assert (lb->pos > BUF_OFFSET);
size_t hdrsize = print_header (lb->buf, domid);
data.priority = cat;
@@ -271,32 +254,28 @@ static void vlog (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t d
data.function = func;
data.line = line;
data.message = lb->buf + BUF_OFFSET;
- data.size = strlen(data.message) - 1;
+ data.size = lb->pos - BUF_OFFSET - 1;
data.hdrsize = hdrsize;
dds_log_write_fn_t f = 0;
void *f_arg = NULL;
- for (size_t i = (cat & DDS_LOG_MASK) ? LOG : TRACE;
- i < sizeof (sinks) / sizeof (sinks[0]);
- i++)
+ if (cat & DDS_LOG_MASK)
{
- if (sinks[i].funcs[USE] != default_sink) {
- if (sinks[i].funcs[USE] != f || sinks[i].ptr != f_arg) {
- assert (sinks[i].funcs[USE]);
- sinks[i].funcs[USE] (sinks[i].ptr, &data);
- f = sinks[i].funcs[USE]; f_arg = sinks[i].ptr;
- }
- } else if (cfg->sink_fps[i]) {
- if (default_sink != f || cfg->sink_fps[i] != f_arg) {
- default_sink (cfg->sink_fps[i], &data);
- f = default_sink; f_arg = cfg->sink_fps[i];
- }
- } else if (logconfig.sink_fps[i]) {
- if (default_sink != f || logconfig.sink_fps[i] != f_arg) {
- default_sink (logconfig.sink_fps[i], &data);
- f = default_sink; f_arg = logconfig.sink_fps[i];
- }
- }
+ f = sinks[LOG].func;
+ f_arg = (f == default_sink) ? cfg->sink_fps[LOG] : sinks[LOG].ptr;
+ assert (f != 0);
+ f (f_arg, &data);
+ }
+ /* if tracing is enabled, then print to trace if it matches the
+ trace flags or if it got written to the log
+ (mask == (tracemask | DDS_LOG_MASK)) */
+ if (cfg->c.tracemask && (cat & cfg->c.mask))
+ {
+ dds_log_write_fn_t const g = sinks[TRACE].func;
+ void * const g_arg = (g == default_sink) ? cfg->sink_fps[TRACE] : sinks[TRACE].ptr;
+ assert (g != 0);
+ if (g != f || g_arg != f_arg)
+ g (g_arg, &data);
}
lb->pos = BUF_OFFSET;
@@ -304,51 +283,45 @@ static void vlog (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t d
}
}
-int dds_log_cfg (const struct ddsrt_log_cfg *cfg, uint32_t cat, const char *file, uint32_t line, const char *func, const char *fmt, ...)
+static void vlog (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t domid, const char *file, uint32_t line, const char *func, const char *fmt, va_list ap)
+{
+ lock_sink (RDLOCK);
+ vlog1 (cfg, cat, domid, file, line, func, fmt, ap);
+ unlock_sink ();
+ if (cat & DDS_LC_FATAL)
+ abort();
+}
+
+void dds_log_cfg (const struct ddsrt_log_cfg *cfg, uint32_t cat, const char *file, uint32_t line, const char *func, const char *fmt, ...)
{
const struct ddsrt_log_cfg_impl *cfgimpl = (const struct ddsrt_log_cfg_impl *) cfg;
- if ((cfgimpl->c.mask & cat) || (cat & DDS_LC_FATAL)) {
+ /* cfgimpl->c.mask is too weak a test because it has all DDS_LOG_MASK bits set,
+ rather than just the ones in dds_get_log_mask() (so as not to cache the latter
+ and have to keep them synchronized */
+ if ((cfgimpl->c.mask & cat) && ((dds_get_log_mask () | cfgimpl->c.tracemask) & cat)) {
va_list ap;
va_start (ap, fmt);
- lock_sink (RDLOCK);
vlog (cfgimpl, cat, cfgimpl->c.domid, file, line, func, fmt, ap);
- unlock_sink ();
va_end (ap);
}
- if (cat & DDS_LC_FATAL) {
- abort();
- }
- return 0;
}
-int dds_log_id (uint32_t cat, uint32_t id, const char *file, uint32_t line, const char *func, const char *fmt, ...)
+void dds_log_id (uint32_t cat, uint32_t id, const char *file, uint32_t line, const char *func, const char *fmt, ...)
{
- if ((dds_get_log_mask () & cat) || (cat & DDS_LC_FATAL)) {
+ if (dds_get_log_mask () & cat) {
va_list ap;
va_start (ap, fmt);
- lock_sink (RDLOCK);
vlog (&logconfig, cat, id, file, line, func, fmt, ap);
- unlock_sink ();
va_end (ap);
}
- if (cat & DDS_LC_FATAL) {
- abort ();
- }
- return 0;
}
-int dds_log (uint32_t cat, const char *file, uint32_t line, const char *func, const char *fmt, ...)
+void dds_log (uint32_t cat, const char *file, uint32_t line, const char *func, const char *fmt, ...)
{
- if ((dds_get_log_mask () & cat) || (cat & DDS_LC_FATAL)) {
+ if (dds_get_log_mask () & cat) {
va_list ap;
va_start (ap, fmt);
- lock_sink (RDLOCK);
vlog (&logconfig, cat, UINT32_MAX, file, line, func, fmt, ap);
- unlock_sink ();
va_end (ap);
}
- if (cat & DDS_LC_FATAL) {
- abort ();
- }
- return 0;
}
diff --git a/src/ddsrt/src/xmlparser.c b/src/ddsrt/src/xmlparser.c
index 4b4bb4b..cd3580f 100644
--- a/src/ddsrt/src/xmlparser.c
+++ b/src/ddsrt/src/xmlparser.c
@@ -54,36 +54,40 @@ struct ddsrt_xmlp_state {
struct ddsrt_xmlp_callbacks cb; /* user-supplied callbacks (or stubs) */
};
-static int cb_null_elem_open (void *varg, uintptr_t parentinfo, uintptr_t *eleminfo, const char *name)
+static int cb_null_elem_open (void *varg, uintptr_t parentinfo, uintptr_t *eleminfo, const char *name, int line)
{
DDSRT_UNUSED_ARG (varg);
DDSRT_UNUSED_ARG (parentinfo);
DDSRT_UNUSED_ARG (eleminfo);
DDSRT_UNUSED_ARG (name);
+ DDSRT_UNUSED_ARG (line);
return 0;
}
-static int cb_null_attr (void *varg, uintptr_t eleminfo, const char *name, const char *value)
+static int cb_null_attr (void *varg, uintptr_t eleminfo, const char *name, const char *value, int line)
{
DDSRT_UNUSED_ARG (varg);
DDSRT_UNUSED_ARG (eleminfo);
DDSRT_UNUSED_ARG (name);
DDSRT_UNUSED_ARG (value);
+ DDSRT_UNUSED_ARG (line);
return 0;
}
-static int cb_null_elem_data (void *varg, uintptr_t eleminfo, const char *data)
+static int cb_null_elem_data (void *varg, uintptr_t eleminfo, const char *data, int line)
{
DDSRT_UNUSED_ARG (varg);
DDSRT_UNUSED_ARG (eleminfo);
DDSRT_UNUSED_ARG (data);
+ DDSRT_UNUSED_ARG (line);
return 0;
}
-static int cb_null_elem_close (void *varg, uintptr_t eleminfo)
+static int cb_null_elem_close (void *varg, uintptr_t eleminfo, int line)
{
DDSRT_UNUSED_ARG (varg);
DDSRT_UNUSED_ARG (eleminfo);
+ DDSRT_UNUSED_ARG (line);
return 0;
}
@@ -606,7 +610,7 @@ static int parse_element (struct ddsrt_xmlp_state *st, uintptr_t parentinfo)
PE_LOCAL_ERROR ("expecting '<'", 0);
}
- if ((ret = st->cb.elem_open (st->varg, parentinfo, &eleminfo, name)) < 0) {
+ if ((ret = st->cb.elem_open (st->varg, parentinfo, &eleminfo, name, st->line)) < 0) {
PE_ERROR ("failed in element open callback", name);
}
@@ -620,7 +624,7 @@ static int parse_element (struct ddsrt_xmlp_state *st, uintptr_t parentinfo)
ddsrt_free (content);
PE_LOCAL_ERROR ("expecting string value for attribute", aname);
}
- ret = st->cb.attr (st->varg, eleminfo, aname, content);
+ ret = st->cb.attr (st->varg, eleminfo, aname, content, st->line);
ddsrt_free (content);
if (ret < 0) {
PE_ERROR2 ("failed in attribute callback", name, aname);
@@ -633,7 +637,7 @@ static int parse_element (struct ddsrt_xmlp_state *st, uintptr_t parentinfo)
switch (tok)
{
case TOK_SHORTHAND_CLOSE_TAG:
- ret = st->cb.elem_close (st->varg, eleminfo);
+ ret = st->cb.elem_close (st->varg, eleminfo, st->line);
goto ok;
case '>':
st->nest++;
@@ -679,7 +683,7 @@ static int parse_element (struct ddsrt_xmlp_state *st, uintptr_t parentinfo)
PE_ERROR ("invalid character sequence", 0);
} else if (content != NULL) {
if (*content != '\0') {
- ret = st->cb.elem_data (st->varg, eleminfo, content);
+ ret = st->cb.elem_data (st->varg, eleminfo, content, st->line);
ddsrt_free (content);
if (ret < 0) {
PE_ERROR ("failed in data callback", 0);
@@ -706,7 +710,7 @@ static int parse_element (struct ddsrt_xmlp_state *st, uintptr_t parentinfo)
if (have_input_marker (st)) {
discard_input_marker (st);
}
- ret = st->cb.elem_close (st->varg, eleminfo);
+ ret = st->cb.elem_close (st->varg, eleminfo, st->line);
goto ok;
default:
PE_LOCAL_ERROR ("expecting '/>' or '>'", 0);
@@ -742,7 +746,3 @@ int ddsrt_xmlp_parse (struct ddsrt_xmlp_state *st)
}
}
}
-
-int ddsrt_xmlUnescapeInsitu (char *buffer, size_t *n) {
- return unescape_insitu (buffer, n);
-}
diff --git a/src/tools/config/CMakeLists.txt b/src/tools/config/CMakeLists.txt
index 3f7bded..139a46b 100644
--- a/src/tools/config/CMakeLists.txt
+++ b/src/tools/config/CMakeLists.txt
@@ -15,14 +15,10 @@ set(CONFJAR_TARGET "${CMAKE_PROJECT_NAME_SMALL}conf")
#set(CMAKE_JAVA_COMPILE_FLAGS "-source" "1.8" "-target" "1.8" -Xlint:deprecation)
-# Oddly enough, add_jar can't deal with a resource having an absolute path (experienced on Windows), so
-# generate into the list-dir.
-configure_file("metaconfig.xml.in" "${CMAKE_CURRENT_LIST_DIR}/metaconfig.xml" @ONLY)
-
file(GLOB_RECURSE JAVA_SOURCES LIST_DIRECTORIES true *.java)
-set(RESOURCES metaconfig.xml metaconfig.xsd resources/ptlogoc16.png resources/ptlogoc24.png resources/ptlogoc32.png resources/ptlogoc48.png)
-add_jar(${CONFJAR_TARGET} ${JAVA_SOURCES} ${RESOURCES} ENTRY_POINT org.eclipse.cyclonedds.config.SpliceConfig)
+set(RESOURCES metaconfig.xml metaconfig.xsd )
+add_jar(${CONFJAR_TARGET} ${JAVA_SOURCES} ${RESOURCES} ENTRY_POINT org.eclipse.cyclonedds.config.CycloneConfig)
#add_test(NAME TestHelloWorld COMMAND ${Java_JAVA_EXECUTABLE} -cp ${_jarFile} HelloWorld)
diff --git a/src/tools/config/excx.pl b/src/tools/config/excx.pl
new file mode 100644
index 0000000..a528b7b
--- /dev/null
+++ b/src/tools/config/excx.pl
@@ -0,0 +1,471 @@
+: # -*- perl -*-
+eval 'exec perl -w -S $0 "$@"'
+if 0;
+
+use strict;
+
+# NOTES:
+# - very fragile - and very sensitive to input formatting
+# - default value may not contain a semicolon
+#
+# UGLINESSES:
+# - knowledge of conversion functions in here
+# - hard definitions of enums in here
+# - negated_boolean is A BIT WEIRD and special-cased
+# - some other hard-coded knowledge of the top level nodes
+# - some hard-coded overrides for defaults
+$|=1;
+
+my %typehint2xmltype = ("____" => "____",
+ "networkAddress" => "String",
+ "partitionAddress" => "String",
+ "networkAddresses" => "String",
+ "ipv4" => "String",
+ "boolean" => "Boolean",
+ "negated_boolean" => "Boolean",
+ "boolean_default" => "Enum",
+ "string" => "String",
+ "tracingOutputFileName" => "String",
+ "verbosity" => "Enum",
+ "tracemask" => "String",
+ "peer" => "String",
+ "float" => "Float",
+ "int" => "Int",
+ "int32" => "Int",
+ "uint" => "Int",
+ "uint32" => "Int",
+ "natint" => "Int",
+ "natint_255" => "Int",
+ "domainId" => "String",
+ "participantIndex" => "String",
+ "port" => "Int",
+ "dyn_port" => "Int",
+ "duration_inf" => "String",
+ "duration_ms_1hr" => "String",
+ "duration_ms_1s" => "String",
+ "duration_100ms_1hr" => "String",
+ "duration_us_1s" => "String",
+ "memsize" => "String",
+ "bandwidth" => "String",
+ "standards_conformance" => "Enum",
+ "locators" => "Enum",
+ "service_name" => "String",
+ "sched_class" => "Enum",
+ "cipher" => "Enum",
+ "besmode" => "Enum",
+ "retransmit_merging" => "Enum",
+ "sched_prio_class" => "Enum",
+ "sched_class" => "Enum",
+ "maybe_int32" => "String",
+ "maybe_memsize" => "String",
+ "maybe_duration_inf" => "String",
+ "allow_multicast" => "String",
+ "transport_selector" => "String",
+ "many_sockets_mode" => "Enum",
+ "xcheck" => "String",
+ "min_tls_version" => "String");
+
+my %typehint2unit = ("duration_inf" => "duration_inf",
+ "duration_ms_1hr" => "duration",
+ "duration_100ms_1hr" => "duration",
+ "duration_ms_1s" => "duration",
+ "duration_us_1s" => "duration",
+ "bandwidth" => "bandwidth",
+ "memsize" => "memsize",
+ "maybe_memsize" => "memsize",
+ "maybe_duration_inf" => "duration_inf");
+
+my %enum_values = ("locators" => "local;none",
+ "standards_conformance" => "lax;strict;pedantic",
+ "verbosity" => "finest;finer;fine;config;info;warning;severe;none",
+ "besmode" => "full;writers;minimal",
+ "retransmit_merging" => "never;adaptive;always",
+ "sched_prio_class" => "relative;absolute",
+ "sched_class" => "realtime;timeshare;default",
+ "cipher" => "null;blowfish;aes128;aes192;aes256",
+ "boolean_default" => "false;true;default",
+ "many_sockets_mode" => "false;true;single;none;many");
+
+my %range = ("port" => "1;65535",
+ "dyn_port" => "-1;65535",
+ "general_cfgelems/startupmodeduration" => "0;60000",
+ "natint_255" => "0;255",
+ "duration_ms_1hr" => "0;1hr",
+ "duration_100ms_1hr" => "100ms;1hr",
+ "duration_ms_1s" => "0;1s",
+ "duration_us_1s" => "0;1s");
+
+my %unit_blurb = ("bandwidth" => "\nThe unit must be specified explicitly. Recognised units: Xb/s, Xbps for bits/s or XB/s, XBps for bytes/s; where X is an optional prefix: k for 103, Ki for 210, M for 106, Mi for 220, G for 109, Gi for 230.
",
+ "memsize" => "\nThe unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).
",
+ "duration" => "\nThe unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.
",
+ "duration_inf" => "\nValid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.
");
+
+while (my ($k, $v) = each %typehint2xmltype) {
+ die "script error: values of enum type $k unknown\n" if $v eq "Enum" && $enum_values{$k} eq "";
+}
+
+# Configurator can't handle UINT32_MAX ... instead of fixing it, just use a different
+# default for the rare ones that have a problem (that works as long as there is no
+# practical difference between the two)
+my %default_overrides = ("multiple_recv_threads_attrs/maxretries" => 2000000000);
+
+my ($name, $table, $kind, $subtable, $multiplicity, $defaultvalue, $typehint, $description);
+
+my %tab2elems;
+my %elem;
+my %desc;
+my %typehint_seen;
+my $gobbling_description;
+my $skip_lite;
+my $in_table;
+my $rest;
+my $deprecated;
+
+############################
+
+sub clean_description {
+ my ($desc) = @_;
+ $desc =~ s/^\s*BLURB\s*\(\s*//s;
+ $desc =~ s/^\s*"//s;
+ $desc =~ s/\s*"(\s*\))? *(\}\s*,\s*$)?$//s;
+ $desc =~ s/\\"/"/g;
+ $desc =~ s/\\n\s*\\/\n/g;
+ $desc =~ s/\\\\/\\/g;
+ $desc =~ s/\n\n/\n/g;
+ # should fix the source ...
+ $desc =~ s/DDSI2E?/Cyclone DDS/g;
+ return $desc;
+}
+
+sub store_entry {
+ $name =~ s/\|.*//; # aliases are not visible in osplconf
+ my $ltable = lc $table;
+ my $lname = lc $name;
+ if (not exists $tab2elems{$ltable}) {
+ $tab2elems{$ltable} = $name;
+ } else {
+ $tab2elems{$ltable} .= ";$name";
+ }
+ $elem{"$ltable/$lname"} = "$kind;$subtable;$multiplicity;$defaultvalue;$typehint";
+ my $ub = exists $typehint2unit{$typehint} && exists $unit_blurb{$typehint2unit{$typehint}} ? $unit_blurb{$typehint2unit{$typehint}} : "";
+ $desc{"$ltable/$lname"} = clean_description($description).$ub;
+ die "error: no mapping defined for type $typehint\n" if $typehint2xmltype{$typehint} eq "";
+ $typehint_seen{$typehint} = 1;
+ #printf "%s - $s\n", "$ltable/$lname", $elem{"$ltable/lname"};
+ #$typehint = "";
+}
+
+sub print_description {
+ my ($desc, $indent) = @_;
+ print "$indent \n";
+}
+
+sub kind_to_kstr {
+ my ($kind, $typehint, $table, $name, $isroot) = @_;
+ if ($isroot) {
+ die unless $kind eq "GROUP";
+ return "rootElement";
+ } elsif ($kind eq "GROUP" || $kind eq "MGROUP") {
+ return "element";
+ } elsif ($kind eq "ATTR") {
+ return "attribute$typehint2xmltype{$typehint}";
+ } elsif ($kind eq "LEAF") {
+ return "leaf$typehint2xmltype{$typehint}";
+ } else {
+ die "error: $kind unrecognized kind ($table/$name)\n";
+ }
+}
+
+sub transform_default {
+ my (@fs) = @_;
+ (my $tmp = $fs[3]) =~ s/^"(.*)"$/$1/;
+ if ($fs[4] ne "negated_boolean") {
+ return $tmp;
+ } else {
+ my %map = ("true" => "false", "false" => "true");
+ return $map{lc $tmp};
+ }
+}
+
+sub conv_to_xml {
+ my ($table, $name, $indent, $prefix, $isroot, $force_min_occ_1) = @_;
+ #, fs,vs,vsn,kstr,ts,tsi,tsn,i,min_occ,max_occ,rr,req) { # fs,vs,kstr,... are locals
+ my $lctn = lc "$table/$name";
+ my @fs = split /;/, $elem{$lctn};
+ #print "$table/$name - \n"; for (my $i = 0; $i < @fs; $i++) { print " - $i $fs[$i]\n" }
+ my $kstr = kind_to_kstr($fs[0], $fs[4], $table, $name, $isroot);
+ my ($min_occ, $max_occ);
+ if ($fs[2] =~ /MAX/) {
+ $min_occ = $max_occ = 0;
+ } elsif ($fs[2] == 0 || $fs[2] == 1) {
+ # multiplicity = 0 => special case, treat as-if 1
+ # multiplicity = 1 => required if no default
+ # force_min_occ_1 so we can mark "Domain" as required and have it
+ # show up in the config editor when creating a new file
+ if ($force_min_occ_1) {
+ $min_occ = 1;
+ } elsif ($fs[0] eq "GROUP" || $fs[0] eq "MGROUP") {
+ $min_occ = 0;
+ } elsif ($fs[3] eq "" || $fs[3] eq "NULL") {
+ $min_occ = 1;
+ } else {
+ $min_occ = 0;
+ }
+ $max_occ = 1;
+ } else {
+ $min_occ = 0; $max_occ = $fs[2];
+ }
+ if ($fs[0] eq "ATTR") {
+ my $req = ($min_occ == 0) ? "false" : "true";
+ print "$indent<$kstr name=\"$name\" required=\"$req\">\n";
+ } else {
+ print "$indent<$kstr name=\"$name\" minOccurrences=\"$min_occ\" maxOccurrences=\"$max_occ\">\n";
+ }
+ print_description ("$prefix$desc{$lctn}", $indent);
+ # enum, int ranges
+ if (exists $enum_values{$fs[4]}) {
+ my @vs = split /;/, $enum_values{$fs[4]};
+ print "$indent $_\n" for @vs;
+ }
+ my $rr = exists $range{$lctn} ? $range{$lctn} : "";
+ if ($rr eq "" && exists $range{$fs[4]}) { $rr = $range{$fs[4]}; }
+ if ($rr ne "") {
+ my @vs = split /;/, $rr;
+ print "$indent $vs[0]\n";
+ print "$indent $vs[1]\n";
+ }
+ # remarkably, osplconf can't deal with strings for which no maximum
+ # length is specified, even though it accepts unlimited length
+ # strings ...
+ if ($typehint2xmltype{$fs[4]} eq "String") {
+ print "$indent 0\n";
+ }
+ # default not applicable to GROUPs
+ if ($fs[0] ne "GROUP" && $fs[0] ne "MGROUP") {
+ my $defover = exists $default_overrides{$lctn} ? $default_overrides{$lctn} : "";
+ if ($defover ne "") {
+ print "$indent $defover\n";
+ } elsif ($fs[3] eq "" || $fs[3] eq "NULL") {
+ print "$indent \n";
+ } else {
+ print "$indent ".transform_default(@fs)."\n";
+ }
+ }
+ # recurse into subtables if any (except when it is the root: rootElement needs
+ # special treatment
+ if (!$isroot && $fs[1] ne "") {
+ my @ts = sort (split /,/, $fs[1]);
+ conv_table_to_xml($_, "$indent ", $prefix, 0, 0) for @ts;
+ }
+ print "$indent$kstr>\n";
+}
+
+sub conv_table_to_xml {
+ my ($table, $indent, $prefix, $isroot, $force_min_occ_1) = @_;
+ return unless exists $tab2elems{$table};
+ my @ns = sort (split /;/, $tab2elems{$table});
+ conv_to_xml($table, $_, $indent, ($table eq "unsupp_cfgelems") ? "Internal" : $prefix, $isroot, $force_min_occ_1) for @ns;
+}
+
+while (<>) {
+ if ($gobbling_description) {
+ $description .= $_;
+ #print " .. $_\n";
+ }
+
+ if ($gobbling_description && /(^|")(\s*\)) *\} *, *$/) {
+ $gobbling_description = 0;
+ store_entry() unless $deprecated;
+ next;
+ }
+
+ if ($gobbling_description) {
+ next;
+ }
+
+ if (/^[ \t]*(#[ \t]*(if|ifdef|ifndef|else|endif).*)?$/) { # skip empty lines, preproc
+ next;
+ }
+
+ if (/^ *END_MARKER *$/) {
+ if (!$in_table) {
+ warn "END_MARKER seen while not in a table";
+ }
+ $in_table = 0;
+ #print "END_MARKER $table\n";
+ next;
+ }
+
+ if (/^static +const +struct +cfgelem +([A-Za-z_0-9]+)\s*\[/) {
+ $in_table = 1;
+ $table = $1;
+ #print "TABLE $table\n";
+ next;
+ }
+
+ if ($in_table && /^ *WILDCARD *, *$|^ *\{ *(MOVED) *\(/) {
+ next;
+ }
+
+ # Recognise all "normal" entries: attributes, groups, leaves and
+ # leaves with attributes. This doesn't recognise the ones used for the
+ # root groups: those are dealt with by the next pattern
+ if ($in_table && /^ *\{ *((?:DEPRECATED_)?(?:ATTR|GROUP|GROUP_W_ATTRS|MGROUP|LEAF|LEAF_W_ATTRS)) *\(/) {
+ $rest = $_;
+ # extract kind
+ $rest =~ s/^ *\{ *((?:DEPRECATED_)?(?:ATTR|GROUP|GROUP_W_ATTRS|MGROUP|LEAF|LEAF_W_ATTRS)) *\( *(.*)/$2/;
+ $kind = $1;
+ $deprecated = ($kind =~ s/^DEPRECATED_//);
+ # extract name + reference to subtable
+ $rest =~ s/\"([A-Za-z_0-9|]+)\" *(.*)/$2/;
+ $name = $1;
+ my ($subelems, $subattrs) = ("", "");
+ if ($kind eq "GROUP" || $kind eq "GROUP_W_ATTRS" || $kind eq "MGROUP") {
+ $rest =~ s/, *([A-Za-z_0-9]+) *(.*)/$2/;
+ $subelems = $1;
+ }
+ if ($kind eq "LEAF_W_ATTRS" || $kind eq "GROUP_W_ATTRS" || $kind eq "MGROUP") {
+ $rest =~ s/, *([A-Za-z_0-9]+) *(.*)/$2/;
+ $subattrs = $1;
+ }
+ $subtable = "";
+ if ($subelems ne "") { $subtable = $subelems; }
+ if ($subattrs ne "") {
+ if ($subtable ne "") { $subtable = "$subtable,$subattrs"; }
+ else { $subtable = $subattrs; }
+ }
+ $rest =~ s/ *\) *, *//;
+ #print " kind $kind name $name subtable $subtable -- $rest\n";
+
+ # don't care about the distinction between GROUP/LEAF and
+ # GROUP/LEAF_W_ATTRS in the remainer of the code: we simply
+ # rely on subtable.
+ $kind =~ s/_W_ATTRS//;
+ }
+
+ # Root groups: use a special trick, which allows them to do groups
+ # with attributes. Which the DDSI2 proper doesn't use, but which the
+ # service configuration stuff does rely on.
+ if ($in_table && /^ *\{ *"([A-Za-z_0-9|]+)" *, */) {
+ $rest = $_;
+ # root elements are all groups, formatted as: , ,
+ # , NODATA, description. They're therefore pretty easy to
+ # parse.
+ $kind = "GROUP";
+ $rest =~ s/^ *\{ *\"([A-Za-z_0-9|]+)\" *, *(.*)/$2/;
+ $name = $1;
+ # then follow the sub-elements and the attributes
+ $rest =~ s/([A-Za-z_0-9]+) *, *(.*)/$2/;
+ my $subelems = $1;
+ $rest =~ s/([A-Za-z_0-9]+) *, *(.*)/$2/;
+ my $subattrs = $1;
+ # then we require NODATA (could do this in the pattern also)
+ die "error: NODATA expected" unless $rest =~ /^NODATA *,/;
+ # multiplicity is hard coded: we want to allow multiple ddsi2 services
+ $multiplicity = 0;
+ $subtable = "";
+ if ($subelems ne "NULL") { $subtable = $subelems; }
+ if ($subattrs ne "NULL") {
+ if ($subtable ne "") { $subtable = "$subtable,$subattrs"; }
+ else { $subtable = $subattrs; }
+ }
+ $rest =~ s/([A-Za-z_0-9]+) *, *(.*)/$2/;
+ }
+
+ # Extract stuff specific to ATTRs, LEAFs and MGROUPs
+ if ($in_table && ($kind eq "ATTR" || $kind eq "LEAF" || $kind eq "MGROUP")) {
+ # extract multiplicity
+ $rest =~ s/([0-9]+|U?INT(?:16|32|64)?_MAX) *, *(.*)/$2/;
+ $multiplicity = $1;
+ # extract default value
+ $rest =~ s/(\"(?:[^\"]*)\"|NULL|0) *, *(.*)/$2/;
+ $defaultvalue = $1;
+ if ($defaultvalue eq "0") { $defaultvalue = "NULL"; }
+ # skip reference to internal name (either ABSOFF(field),
+ # RELOFF(field,field) or , (the latter being used by
+ # "verbosity")
+ $rest =~ s/(ABSOFF *\( *[A-Za-z_0-9.]+ *\)|RELOFF *\( *[A-Za-z_0-9.]+ *, *[A-Za-z_0-9]+ *\)|[0-9]+ *, *[0-9]+) *, *//;
+ # skip init function
+ $rest =~ s/([A-Za-z_0-9]+|0) *, *//;
+ # type hint from conversion function
+ $rest =~ s/(uf_(?:[A-Za-z_0-9]+)|NULL|0) *, *(.*)/$2/;
+ $typehint = $1;
+ $typehint =~ s/^uf_//;
+ # accept typehint = NULL for a LEAF_WITH_ATTRS: there is no defined
+ # "syntax" for groups that have only attributes, pretending it is a
+ # group because that causes us to emit an "element" and not a
+ # "leaf".
+ if ($typehint eq "0" || $typehint eq "NULL") {
+ $kind = "GROUP";
+ $typehint = "____";
+ }
+ # skip free, print functions
+ $rest =~ s/([A-Za-z_0-9]+|0) *, *([A-Za-z_0-9]+|0) *, *//;
+ #print " .. multiplicity $multiplicity default $defaultvalue typehint $typehint\n";
+ }
+
+ # Extract description (or NULL, if not to be included in the configurator XML)
+ if ($in_table) {
+ #print " .. $rest\n";
+ # description or NULL
+ if ($rest =~ /NULL *\} *, *$/) {
+ # no description - discard this one/simply continue with next one
+ } elsif ($rest =~ /(?:BLURB\s*\(\s*)?(".*")(?:\s*\))? *\} *, *$/) {
+ # description ending on same line
+ $description = $1;
+ store_entry() unless $deprecated;
+ } else {
+ # strip the quotes &c. once the full text has been gathered
+ $description = $rest;
+ $gobbling_description = 1;
+ }
+ #print " .. gobbling $gobbling_description";
+ next;
+ }
+}
+
+#print "$tab2elems{cyclonedds_root_cfgelems}\n";
+my @rootnames = split /;/, $tab2elems{cyclonedds_root_cfgelems};
+die "error: cyclonedds_root_cfgelems has no or multiple entries\n" if @rootnames != 1;
+die "error: root_cfgelems doesn't exist\n" unless exists $tab2elems{root_cfgelems};
+
+# Override the type for ControlTopic/Deaf, .../Mute so that an empty
+# string is allowed by the configuration validation in spliced
+# (easier than adding a boolean_or_empty to DDSI2 for a quick hack)
+#if (elem["control_topic_cfgelems/deaf"] == "" || elem["control_topic_cfgelems/mute"] == "") {
+# print FILENAME": error: control_topic_cfgelems/{deaf,mute} missing" > "/dev/stderr";
+# exit 1;
+#}
+#elem["control_topic_cfgelems/deaf"] = "LEAF;;1;\"false\";string";
+#elem["control_topic_cfgelems/mute"] = "LEAF;;1;\"false\";string";
+
+print << 'EOT';
+
+
+
+
+EOT
+conv_table_to_xml("cyclonedds_root_cfgelems", " ", "", 1, 0);
+conv_table_to_xml("root_cfgelems", " ", "", 0, 1);
+print << 'EOT';
+
+EOT
+
+while (my ($k, $v) = each %typehint_seen) {
+ warn "script warning: type mapping defined for $k but not used" if $v == 0;
+}
diff --git a/src/tools/config/metaconfig.xml.in b/src/tools/config/metaconfig.xml
similarity index 74%
rename from src/tools/config/metaconfig.xml.in
rename to src/tools/config/metaconfig.xml
index 15c2ffd..1b421ce 100644
--- a/src/tools/config/metaconfig.xml.in
+++ b/src/tools/config/metaconfig.xml
@@ -9,47 +9,36 @@
http://www.eclipse.org/org/documents/edl-v10.php.
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+
+ ===
+ generated from src/core/ddsi/src/q_config.c using excx.pl
-->
-
+
@CMAKE_PROJECT_NAME@ is highly configurable, allowing many configuration parameters
- to be chosen by the user at deployment time by means of easily maintainable XML-file(s).
- ]]>
+CycloneDDS configuration
+ ]]>
+ 0
The Domain identifies the scope of communication.
- ]]>
-
-
-
-
- 0
- any
-
-
-
-
-
- DDSI2 settings ...
+The General element specifying Domain related settings.
]]>
- CDR_CLIENT
+ 0
+
+ Domain id this configuration applies to, or "any" if it applies to all domain ids.
+ ]]>
+ 0
+ any
+
This element is used to group a set of channels. The channels are independent data paths through DDSI2E and by using separate threads and setting their priorities appropriately, chanenls can be used to map transport priorities to operating system scheduler priorities, ensuring system-wide end-to-end priority preservation.
+This element is used to group a set of channels. The channels are independent data paths through Cyclone DDS and by using separate threads and setting their priorities appropriately, chanenls can be used to map transport priorities to operating system scheduler priorities, ensuring system-wide end-to-end priority preservation.
]]>
-
+ 0
+
This element defines a channel.
]]>
@@ -68,7 +57,7 @@
This element specifies the maximum transmit rate of auxiliary traffic on this channel (e.g. retransmits, heartbeats, etc). Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.
+This element specifies the maximum transmit rate of auxiliary traffic on this channel (e.g. retransmits, heartbeats, etc). Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means Cyclone DDS imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.
The unit must be specified explicitly. Recognised units: Xb/s, Xbps for bits/s or XB/s, XBps for bytes/s; where X is an optional prefix: k for 103, Ki for 210, M for 106, Mi for 220, G for 109, Gi for 230.
]]>
0
@@ -76,7 +65,7 @@
This element specifies the maximum transmit rate of new samples and directly related data, for this channel. Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.
+This element specifies the maximum transmit rate of new samples and directly related data, for this channel. Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means Cyclone DDS imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.
The unit must be specified explicitly. Recognised units: Xb/s, Xbps for bits/s or XB/s, XBps for bytes/s; where X is an optional prefix: k for 103, Ki for 210, M for 106, Mi for 220, G for 109, Gi for 230.
]]>
0
@@ -101,19 +90,7 @@ When an application is run without Administrative priveleges then only the diffs
The Compatibility elements allows specifying various settings related to compatability with standards and with other DDSI implementations.
]]>
-
- This element governs the representation of an acknowledgement message that does not also negatively-acknowledge some samples. If set to 0, the generated acknowledgements have an invalid form and will be reject by the strict and pedantic conformance modes, but several other implementation require this setting for smooth interoperation.
-If set to 1, all acknowledgements sent by DDSI2E adhere the form of acknowledgement messages allowed by the standard, but this causes problems when interoperating with these other implementations. The strict and pedantic standards conformance modes always overrule an AckNackNumbitsEmptySet=0 to prevent the transmitting of invalid messages.
- ]]>
- 0
-
-
- When set to true, arrival of a message from a peer asserts liveliness of that peer. When set to false, only SPDP and explicit lease renewals have this effect.
- ]]>
- true
-
+ 0
This option assumes ParticipantMessageData endpoints required by the liveliness protocol are present in RTI participants even when not properly advertised by the participant discovery protocol.
@@ -130,7 +107,7 @@ When an application is run without Administrative priveleges then only the diffs
This option specifies whether a network socket will be created for each domain participant on a host. The specification seems to assume that each participant has a unique address, and setting this option will ensure this to be the case. This is not the defeault.
-Disabling it slightly improves performance and reduces network traffic somewhat. It also causes the set of port numbers needed by DDSI2E to become predictable, which may be useful for firewall and NAT configuration.
+Disabling it slightly improves performance and reduces network traffic somewhat. It also causes the set of port numbers needed by Cyclone DDS to become predictable, which may be useful for firewall and NAT configuration.
]]>
false
true
@@ -139,16 +116,9 @@ When an application is run without Administrative priveleges then only the diffs
many
single
-
- This element allows a closer mimicking of the behaviour of some other DDSI implementations, albeit at the cost of generating even more invalid messages. Setting it to true ensures a Heartbeat can be sent at any time when a remote node requests one, setting it to false delays it until a valid one can be sent.
-The latter is fully compliant with the specification, and no adverse effects have been observed. It is the default.
- ]]>
- false
-
This element sets the level of standards conformance of this instance of the DDSI2E Service. Stricter conformance typically means less interoperability with other implementations. Currently three modes are defined:
+This element sets the level of standards conformance of this instance of the Cyclone DDS Service. Stricter conformance typically means less interoperability with other implementations. Currently three modes are defined:
- pedantic: very strictly conform to the specification, ultimately for compliancy testing, but currently of little value because it adheres even to what will most likely turn out to be editing errors in the DDSI standard. Arguably, as long as no errata have been published it is the current text that is in effect, and that is what pedantic currently does.
- strict: a slightly less strict view of the standard than does pedantic: it follows the established behaviour where the standard is obviously in error.
- lax: attempt to provide the smoothest possible interoperability, anticipating future revisions of elements in the standard in areas that other implementations do not adhere to, even though there is no good reason not to.
@@ -164,12 +134,7 @@ When an application is run without Administrative priveleges then only the diffs
The Discovery element allows specifying various parameters related to the discovery of peers.
]]>
-
- This element controls whether or not DDSI2E advertises writers for the built-in topics from its discovery for backwards compatibility with older OpenSplice versions.
- ]]>
- true
-
+ 0
This setting controls for how long endpoints discovered via a Cloud discovery service will survive after the discovery service disappeared, allowing reconnect without loss of data when the discovery service restarts (or another instance takes over).
@@ -193,13 +158,13 @@ When an application is run without Administrative priveleges then only the diffs
This element specifies the maximum DDSI participant index selected by this instance of the DDSI2E service if the Discovery/ParticipantIndex is "auto".
+This element specifies the maximum DDSI participant index selected by this instance of the Cyclone DDS service if the Discovery/ParticipantIndex is "auto".
]]>
9
This element specifies the DDSI participant index used by this instance of the DDSI2E service for discovery purposes. Only one such participant id is used, independent of the number of actual DomainParticipants on the node. It is either:
+This element specifies the DDSI participant index used by this instance of the Cyclone DDS service for discovery purposes. Only one such participant id is used, independent of the number of actual DomainParticipants on the node. It is either:
- auto: which will attempt to automatically determine an available participant index (see also Discovery/MaxAutoParticipantIndex), or
- a non-negative integer less than 120, or
- none:, which causes it to use arbitrary port numbers for unicast sockets which entirely removes the constraints on the participant index but makes unicast discovery impossible.
@@ -313,21 +278,23 @@ When an application is run without Administrative priveleges then only the diffs
The General element specifies overall DDSI2E service settings.
+The General element specifies overall Cyclone DDS service settings.
]]>
+ 0
This element controls whether DDSI2E uses multicasts for data traffic.
-It is a comma-separated list of some of the following keywords: "spdp", "asm", "ssm", or either of "false" or "true".
+This element controls whether Cyclone DDS uses multicasts for data traffic.
+It is a comma-separated list of some of the following keywords: "spdp", "asm", "ssm", or either of "false" or "true", or "default".
-- spdp: enables the use of ASM (any-source multicast) for participant discovery
-- asm: enables the use of ASM for all traffic (including SPDP)
+- spdp: enables the use of ASM (any-source multicast) for participant discovery, joining the multicast group on the discovery socket, transmitting SPDP messages to this group, but never advertising nor using any multicast address in any discovery message, thus forcing unicast communications for all endpoint discovery and user data.
+- asm: enables the use of ASM for all traffic, including receiving SPDP but not transmitting SPDP messages via multicast
- ssm: enables the use of SSM (source-specific multicast) for all non-SPDP traffic (if supported)
When set to "false" all multicasting is disabled. The default, "true" enables full use of multicasts. Listening for multicasts can be controlled by General/MulticastRecvNetworkInterfaceAddresses.
+"default" maps on spdp if the network is a WiFi network, on true if it is a wired network
]]>
0
- true
+ default
false
-
- This element specifies whether DDSI packets are visible to all DDSI participants in the same process. It must be "true" for intra-process communications, i.e. a reader and writer communicating in the same address space. If enabled and using multicast then EnableMulticastLoopback must also be enabled.
- ]]>
- false
-
This element specifies whether DDSI2E allows IP multicast packets to be visible to all DDSI participants in the same node, including itself. It must be "true" for intra-node multicast communications, but if a node runs only a single DDSI2E service and does not host any other DDSI-capable programs, it should be set to "false" for improved performance.
+This element specifies whether Cyclone DDS allows IP multicast packets to be visible to all DDSI participants in the same node, including itself. It must be "true" for intra-node multicast communications, but if a node runs only a single Cyclone DDS service and does not host any other DDSI-capable programs, it should be set to "false" for improved performance.
]]>
true
This element allows explicitly overruling the network address DDSI2E advertises in the discovery protocol, which by default is the address of the preferred network interface (General/NetworkInterfaceAddress), to allow DDSI2E to communicate across a Network Address Translation (NAT) device.
+This element allows explicitly overruling the network address Cyclone DDS advertises in the discovery protocol, which by default is the address of the preferred network interface (General/NetworkInterfaceAddress), to allow Cyclone DDS to communicate across a Network Address Translation (NAT) device.
]]>
0
auto
@@ -364,7 +324,7 @@ When an application is run without Administrative priveleges then only the diffs
This element specifies the size of DDSI sample fragments generated by DDSI2E. Samples larger than FragmentSize are fragmented into fragments of FragmentSize bytes each, except the last one, which may be smaller. The DDSI spec mandates a minimum fragment size of 1025 bytes, but DDSI2E will do whatever size is requested, accepting fragments of which the size is at least the minimum of 1025 and FragmentSize.
+This element specifies the size of DDSI sample fragments generated by Cyclone DDS. Samples larger than FragmentSize are fragmented into fragments of FragmentSize bytes each, except the last one, which may be smaller. The DDSI spec mandates a minimum fragment size of 1025 bytes, but Cyclone DDS will do whatever size is requested, accepting fragments of which the size is at least the minimum of 1025 and FragmentSize.
The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).
]]>
0
@@ -372,7 +332,7 @@ When an application is run without Administrative priveleges then only the diffs
This element specifies the maximum size of the UDP payload that DDSI2E will generate. DDSI2E will try to maintain this limit within the bounds of the DDSI specification, which means that in some cases (especially for very low values of MaxMessageSize) larger payloads may sporadically be observed (currently up to 1192 B).
+This element specifies the maximum size of the UDP payload that Cyclone DDS will generate. Cyclone DDS will try to maintain this limit within the bounds of the DDSI specification, which means that in some cases (especially for very low values of MaxMessageSize) larger payloads may sporadically be observed (currently up to 1192 B).
On some networks it may be necessary to set this item to keep the packetsize below the MTU to prevent IP fragmentation. In those cases, it is generally advisable to also consider reducing Internal/FragmentSize.
The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).
]]>
@@ -381,15 +341,15 @@ When an application is run without Administrative priveleges then only the diffs
This element specifies on which network interfaces DDSI2E listens to multicasts. The following options are available:
+This element specifies on which network interfaces Cyclone DDS listens to multicasts. The following options are available:
- all: listen for multicasts on all multicast-capable interfaces; or
- any: listen for multicasts on the operating system default interface; or
- preferred: listen for multicasts on the preferred interface (General/NetworkInterfaceAddress); or
- none: does not listen for multicasts on any interface; or
-- a comma-separated list of network addresses: configures DDSI2E to listen for multicasts on all of the listed addresses.
+- a comma-separated list of network addresses: configures Cyclone DDS to listen for multicasts on all of the listed addresses.
-If DDSI2E is in IPv6 mode and the address of the preferred network interface is a link-local address, "all" is treated as a synonym for "preferred" and a comma-separated list is treated as "preferred" if it contains the preferred interface and as "none" if not.
+If Cyclone DDS is in IPv6 mode and the address of the preferred network interface is a link-local address, "all" is treated as a synonym for "preferred" and a comma-separated list is treated as "preferred" if it contains the preferred interface and as "none" if not.
]]>
0
preferred
@@ -404,29 +364,17 @@ When an application is run without Administrative priveleges then only the diffs
This element specifies the preferred network interface for use by DDSI2E. The preferred network interface determines the IP address that DDSI2E advertises in the discovery protocol (but see also General/ExternalNetworkAddress), and is also the only interface over which multicasts are transmitted. The interface can be identified by its IP address, network interface name or network portion of the address. If the value "auto" is entered here, DDSI2E will select what it considers the most suitable interface.
+This element specifies the preferred network interface for use by Cyclone DDS. The preferred network interface determines the IP address that Cyclone DDS advertises in the discovery protocol (but see also General/ExternalNetworkAddress), and is also the only interface over which multicasts are transmitted. The interface can be identified by its IP address, network interface name or network portion of the address. If the value "auto" is entered here, Cyclone DDS will select what it considers the most suitable interface.
]]>
0
auto
-
+
This element configures whether startup-mode should also cover transient and persistent data, for configurations where the durability service does not take care of it. Configurations without defined merge policies best leave this enabled.
+When false (default) Cyclone DDS uses unicast for data whenever there a single unicast suffices. Setting this to true makes it prefer multicasting data, falling back to unicast only when no multicast address is available.
]]>
- true
+ false
-
- This element specifies how long the DDSI2E remains in its "startup" mode. While in "startup" mode all volatile reliable data published on the local node is retained as-if it were transient-local data, allowing existing readers on remote nodes to obtain the data even though discovering them takes some time. Best-effort data by definition need not arrive, and transient and persistent data are covered by the durability service.
-Once the system is stable, DDSI2E keeps track of the existence of remote readers whether or not matching writers exist locally, avoiding this discovery delay and ensuring this is merely a node startup issue.
-Setting General/StartupModeDuration to 0s will disable it.
-The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.
- ]]>
- 0
- 60000
- 0
- 2 s
-
This element allows selecting the transport to be used (udp, udp6, tcp, tcp6, raweth)
@@ -448,18 +396,13 @@ When an application is run without Administrative priveleges then only the diffs
The Internal elements deal with a variety of settings that evolving and that are not necessarily fully supported. For the vast majority of the Internal settings, the functionality per-se is supported, but the right to change the way the options control the functionality is reserved. This includes renaming or moving options.
]]>
+ 0
InternalProxy readers that are assumed to sill be retrieving historical data get this many samples retransmitted when they NACK something, even if some of these samples have sequence numbers outside the set covered by the NACK.
]]>
0
-
- InternalThis element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.
- ]]>
- true
-
InternalThis element controls which network interfaces are assumed to be capable of multicasting even when the interface flags returned by the operating system state it is not (this provides a workaround for some platforms). It is a comma-separated lists of patterns (with ? and * wildcards) against which the interface names are matched.
@@ -477,7 +420,7 @@ When an application is run without Administrative priveleges then only the diffs
InternalThis element specifies the maximum transmit rate of auxiliary traffic not bound to a specific channel, such as discovery traffic, as well as auxiliary traffic related to a certain channel if that channel has elected to share this global AuxiliaryBandwidthLimit. Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.
+InternalThis element specifies the maximum transmit rate of auxiliary traffic not bound to a specific channel, such as discovery traffic, as well as auxiliary traffic related to a certain channel if that channel has elected to share this global AuxiliaryBandwidthLimit. Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means Cyclone DDS imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.
The unit must be specified explicitly. Recognised units: Xb/s, Xbps for bits/s or XB/s, XBps for bytes/s; where X is an optional prefix: k for 103, Ki for 210, M for 106, Mi for 220, G for 109, Gi for 230.
]]>
0
@@ -496,53 +439,10 @@ When an application is run without Administrative priveleges then only the diffs
minimal
writers
-
- InternalThis element forces all DDSI2E built-in discovery-related readers to request all historical data, instead of just one for each "topic". There is no indication that any of the current DDSI implementations requires changing of this setting, but it is conceivable that an implementation might track which participants have been informed of the existence of endpoints and which have not been, refusing communication with those that have "can't" know.
-Should it be necessary to hide DDSI2E's shared discovery behaviour, set this to true and Internal/BuiltinEndpointSet to full.
- ]]>
- false
-
InternalThe ControlTopic element allows configured whether DDSI2E provides a special control interface via a predefined topic or not.
+Internal
The ControlTopic element allows configured whether Cyclone DDS provides a special control interface via a predefined topic or not.
]]>
-
- Internal[DEPRECATED]
- "This element controls whether DDSI2E should create a topic to control DDSI2E's behaviour dynamically.
"
- },
-
- ]]>
- false
-
-
- Internal[DEPRECATED]
- "This element controls after how much time an initial deaf/mute state will automatically reset.
"
- },
-
-
Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.
- ]]>
- 0
- inf
-
-
- Internal[DEPRECATED]
- "This element controls whether DDSI2E defaults to deaf mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to.
- ]]>
- 0
- false
-
-
- Internal[DEPRECATED]
- "This element controls whether DDSI2E defaults to mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to.
- ]]>
- 0
- false
-
256
-
+
InternalForward all messages from a writer, rather than trying to forward each sample only once. The default of trying to forward each sample only once filters out duplicates for writers in multiple partitions under nearly all circumstances, but may still publish the odd duplicate. Note: the current implementation also can lose in contrived test cases, that publish more than 2**32 samples using a single data writer in conjunction with carefully controlled management of the writer history via cooperating local readers.
+InternalThis element enables expensive checks in builds with assertions enabled and is ignored otherwise. Recognised categories are:
+ - whc: writer history cache checking
+ - rhc: reader history cache checking
+ In addition, there is the keyword all that enables all checks.
]]>
- false
-
+ 0
+
+
InternalWhen true, include keyhashes in outgoing data for topics with keys.
@@ -628,27 +532,31 @@ When an application is run without Administrative priveleges then only the diffs
0
10 s
-
- InternalThis option enables a backwards-compatible, non-compliant setting and interpretation of the control flags in fragmented data messages. To be enabled only when requiring interoperability between compliant and non-compliant versions of DDSI2E for large messages.
- ]]>
- false
-
InternalThis element controls whether or not implementation should internally monitor its own liveliness. If liveliness monitoring is enabled, stack traces can be dumped automatically when some thread appears to have stopped making progress.
]]>
false
+
+ InternalThis element controls the interval at which to check whether threads have been making progress.
+The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.
+ ]]>
+ 100ms
+ 1hr
+ 0
+ 1s
+
InternalThis element controls whether or not to write stack traces to the DDSI2 trace when a thread fails to make progress (on select platforms only).
+InternalThis element controls whether or not to write stack traces to the Cyclone DDS trace when a thread fails to make progress (on select platforms only).
]]>
true
InternalThis elements configures the maximum number of DCPS domain participants this DDSI2E instance is willing to service. 0 is unlimited.
+InternalThis elements configures the maximum number of DCPS domain participants this Cyclone DDS instance is willing to service. 0 is unlimited.
]]>
0
@@ -668,7 +576,7 @@ When an application is run without Administrative priveleges then only the diffs
InternalThis setting controls the maximum (CDR) serialised size of samples that DDSI2E will forward in either direction. Samples larger than this are discarded with a warning.
+InternalThis setting controls the maximum (CDR) serialised size of samples that Cyclone DDS will forward in either direction. Samples larger than this are discarded with a warning.
The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).
]]>
0
@@ -676,14 +584,14 @@ When an application is run without Administrative priveleges then only the diffs
InternalThis element enables heartbeat-to-ack latency among DDSI2E services by prepending timestamps to Heartbeat and AckNack messages and calculating round trip times. This is non-standard behaviour. The measured latencies are quite noisy and are currently not used anywhere.
+InternalThis element enables heartbeat-to-ack latency among Cyclone DDS services by prepending timestamps to Heartbeat and AckNack messages and calculating round trip times. This is non-standard behaviour. The measured latencies are quite noisy and are currently not used anywhere.
]]>
false
InternalThis setting controls the minimum size of socket receive buffers. The operating system provides some size receive buffer upon creation of the socket, this option can be used to increase the size of the buffer beyond that initially provided by the operating system. If the buffer size cannot be increased to the specified size, an error is reported.
-The default setting is the word "default", which means DDSI2E will attempt to increase the buffer size to 1MB, but will silently accept a smaller buffer should that attempt fail.
+The default setting is the word "default", which means Cyclone DDS will attempt to increase the buffer size to 1MB, but will silently accept a smaller buffer should that attempt fail.
The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).
]]>
0
@@ -708,13 +616,12 @@ When an application is run without Administrative priveleges then only the diffs
InternalThis element controls whether all traffic is handled by a single receive thread or whether multiple receive threads may be used to improve latency. Currently multiple receive threads are only used for connectionless transport (e.g., UDP) and ManySocketsMode not set to single (the default).
]]>
true
-
+
InternalReceive threads dedicated to a single socket can only be triggered for termination by sending a packet. Reception of any packet will do, so termination failure due to packet loss is exceedingly unlikely, but to eliminate all risks, it will retry as many times as specified by this attribute before aborting.
]]>
- 0
- 4294967295
-
+ 2000000000
+
InternalThis element sets the maximum size in samples of a primary re-order administration. Each proxy writer has one primary re-order administration to buffer the packet flow in case some packets arrive out of order. Old samples are forwarded to secondary re-order administrations associated with readers in need of historical data.
]]>
- 64
+ 128
InternalThis element controls for how long a remote participant that was previously deleted will remain on a blacklist to prevent rediscovery, giving the software on a node time to perform any cleanup actions it needs to do. To some extent this delay is required internally by DDSI2E, but in the default configuration with the 'enforce' attribute set to false, DDSI2E will reallow rediscovery as soon as it has cleared its internal administration. Setting it to too small a value may result in the entry being pruned from the blacklist before DDSI2E is ready, it is therefore recommended to set it to at least several seconds.
+InternalThis element controls for how long a remote participant that was previously deleted will remain on a blacklist to prevent rediscovery, giving the software on a node time to perform any cleanup actions it needs to do. To some extent this delay is required internally by Cyclone DDS, but in the default configuration with the 'enforce' attribute set to false, Cyclone DDS will reallow rediscovery as soon as it has cleared its internal administration. Setting it to too small a value may result in the entry being pruned from the blacklist before Cyclone DDS is ready, it is therefore recommended to set it to at least several seconds.
Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.
]]>
0
10s
InternalThis attribute controls whether the configured time during which recently deleted participants will not be rediscovered (i.e., "black listed") is enforced and following complete removal of the participant in DDSI2E, or whether it can be rediscovered earlier provided all traces of that participant have been removed already.
+InternalThis attribute controls whether the configured time during which recently deleted participants will not be rediscovered (i.e., "black listed") is enforced and following complete removal of the participant in Cyclone DDS, or whether it can be rediscovered earlier provided all traces of that participant have been removed already.
]]>
false
@@ -768,12 +675,12 @@ When an application is run without Administrative priveleges then only the diffs
- never: retransmit only to the NACK-ing reader;
- adaptive: attempt to combine retransmits needed for reliability, but send historical (transient-local) data to the requesting reader only;
- always: do not distinguish between different causes, always try to merge.
-The default is adaptive. See also Internal/RetransmitMergingPeriod.
+The default is never. See also Internal/RetransmitMergingPeriod.
]]>
never
adaptive
always
- adaptive
+ never
InternalThis element sets the maximum size in samples of a secondary re-order administration. The secondary re-order administration is per reader in need of historical data.
]]>
- 16
+ 128
InternalThis element controls whether DDSI2E advertises all the domain participants it serves in DDSI (when set to false), or rather only one domain participant (the one corresponding to the DDSI2E process; when set to true). In the latter case DDSI2E becomes the virtual owner of all readers and writers of all domain participants, dramatically reducing discovery traffic (a similar effect can be obtained by setting Internal/BuiltinEndpointSet to "minimal" but with less loss of information).
- ]]>
- false
-
-
- InternalThe element controls whether the mandatory multicasting of the participant discovery packets occurs. Completely disabling multicasting requires this element be set to true, and generally requires explicitly listing peers to ping for unicast discovery.
-See also General/AllowMulticast.
+InternalThis element controls whether Cyclone DDS advertises all the domain participants it serves in DDSI (when set to false), or rather only one domain participant (the one corresponding to the Cyclone DDS process; when set to true). In the latter case Cyclone DDS becomes the virtual owner of all readers and writers of all domain participants, dramatically reducing discovery traffic (a similar effect can be obtained by setting Internal/BuiltinEndpointSet to "minimal" but with less loss of information).
]]>
false
@@ -880,13 +780,13 @@ When an application is run without Administrative priveleges then only the diffs
]]>
InternalThis element controls whether DDSI2E will adapt the high-water mark to current traffic conditions, based on retransmit requests and transmit pressure.
+InternalThis element controls whether Cyclone DDS will adapt the high-water mark to current traffic conditions, based on retransmit requests and transmit pressure.
]]>
true
InternalThis element sets the maximum allowed high-water mark for the DDSI2E WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size.
+InternalThis element sets the maximum allowed high-water mark for the Cyclone DDS WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size.
The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).
]]>
0
@@ -894,7 +794,7 @@ When an application is run without Administrative priveleges then only the diffs
InternalThis element sets the initial level of the high-water mark for the DDSI2E WHCs, expressed in bytes.
+InternalThis element sets the initial level of the high-water mark for the Cyclone DDS WHCs, expressed in bytes.
The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).
]]>
0
@@ -902,7 +802,7 @@ When an application is run without Administrative priveleges then only the diffs
InternalThis element sets the low-water mark for the DDSI2E WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2E WHC shrinks to this size.
+InternalThis element sets the low-water mark for the Cyclone DDS WHCs, expressed in bytes. A suspended writer resumes transmitting when its Cyclone DDS WHC shrinks to this size.
The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).
]]>
0
@@ -928,19 +828,20 @@ When an application is run without Administrative priveleges then only the diffs
The Partitioning element specifies DDSI2E network partitions and how DCPS partition/topic combinations are mapped onto the network partitions.
+The Partitioning element specifies Cyclone DDS network partitions and how DCPS partition/topic combinations are mapped onto the network partitions.
]]>
+ 0
The IgnoredPartitions element specifies DCPS partition/topic combinations that are not distributed over the network.
]]>
This element can be used to prevent certain combinations of DCPS partition and topic from being transmitted over the network. DDSI2E will complete ignore readers and writers for which all DCPS partitions as well as their topic is ignored, not even creating DDSI readers and writers to mirror the DCPS ones.
+This element can be used to prevent certain combinations of DCPS partition and topic from being transmitted over the network. Cyclone DDS will complete ignore readers and writers for which all DCPS partitions as well as their topic is ignored, not even creating DDSI readers and writers to mirror the DCPS ones.
]]>
This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic will be ignored or not. The expressions may use the usual wildcards '*' and '?'. DDSI2E will consider an wildcard DCPS partition to match an expression iff there exists a string that satisfies both expressions.
+This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic will be ignored or not. The expressions may use the usual wildcards '*' and '?'. Cyclone DDS will consider an wildcard DCPS partition to match an expression iff there exists a string that satisfies both expressions.
]]>
0
@@ -949,11 +850,11 @@ When an application is run without Administrative priveleges then only the diffs
The NetworkPartitions element specifies the DDSI2E network partitions.
+The NetworkPartitions element specifies the Cyclone DDS network partitions.
]]>
This element defines a DDSI2E network partition.
+This element defines a Cyclone DDS network partition.
]]>
This attribute specifies the name of this DDSI2E network partition. Two network partitions cannot have the same name.
+This attribute specifies the name of this Cyclone DDS network partition. Two network partitions cannot have the same name.
]]>
0
This attribute selects the DDSI2E security profile for encrypting the traffic mapped to this DDSI2E network partition. The default "null" means the network partition is unsecured; any other name refers to a security profile defined using the Security/SecurityProfile elements.
+This attribute selects the Cyclone DDS security profile for encrypting the traffic mapped to this Cyclone DDS network partition. The default "null" means the network partition is unsecured; any other name refers to a security profile defined using the Security/SecurityProfile elements.
]]>
0
null
@@ -986,22 +887,22 @@ When an application is run without Administrative priveleges then only the diffs
The PartitionMappings element specifies the mapping from DCPS partition/topic combinations to DDSI2E network partitions.
+The PartitionMappings element specifies the mapping from DCPS partition/topic combinations to Cyclone DDS network partitions.
]]>
This element defines a mapping from a DCPS partition/topic combination to a DDSI2E network partition. This allows partitioning data flows by using special multicast addresses for part of the data and possibly also encrypting the data flow.
+This element defines a mapping from a DCPS partition/topic combination to a Cyclone DDS network partition. This allows partitioning data flows by using special multicast addresses for part of the data and possibly also encrypting the data flow.
]]>
This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic maps to the DDSI2E network partition named by the NetworkPartition attribute in this PartitionMapping element. The expressions may use the usual wildcards '*' and '?'. DDSI2E will consider a wildcard DCPS partition to match an expression if there exists a string that satisfies both expressions.
+This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic maps to the Cyclone DDS network partition named by the NetworkPartition attribute in this PartitionMapping element. The expressions may use the usual wildcards '*' and '?'. Cyclone DDS will consider a wildcard DCPS partition to match an expression if there exists a string that satisfies both expressions.
]]>
0
This attribute specifies which DDSI2E network partition is to be used for DCPS partition/topic combinations matching the DCPSPartitionTopic attribute within this PartitionMapping element.
+This attribute specifies which Cyclone DDS network partition is to be used for DCPS partition/topic combinations matching the DCPSPartitionTopic attribute within this PartitionMapping element.
]]>
0
@@ -1013,6 +914,7 @@ When an application is run without Administrative priveleges then only the diffs
The SSL element allows specifying various parameters related to using SSL/TLS for DDSI over TCP.
]]>
+ 0
If disabled this allows SSL connections to occur even if an X509 certificate fails verification.
@@ -1053,14 +955,13 @@ When an application is run without Administrative priveleges then only the diffs
0
keystore
-
+
The minimum TLS version that may be negotiated, valid values are 1.2 and 1.3.
]]>
- 1.2
- 1.3
+ 0
1.3
-
+
This enables the use of self signed X509 certificates.
@@ -1076,11 +977,12 @@ When an application is run without Administrative priveleges then only the diffs
The Security element specifies DDSI2E security profiles that can be used to encrypt traffic mapped to DDSI2E network partitions.
+The Security element specifies Cyclone DDS security profiles that can be used to encrypt traffic mapped to Cyclone DDS network partitions.
]]>
+ 0
This element defines a DDSI2E security profile.
+This element defines a Cyclone DDS security profile.
]]>
This attribute specifies the name of this DDSI2E security profile. Two security profiles cannot have the same name.
+This attribute specifies the name of this Cyclone DDS security profile. Two security profiles cannot have the same name.
]]>
0
@@ -1122,6 +1024,7 @@ When an application is run without Administrative priveleges then only the diffs
The Sizing element specifies a variety of configuration settings dealing with expected system sizes, buffer sizes, &c.
]]>
+ 0
This element specifies the size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway.
@@ -1130,48 +1033,20 @@ When an application is run without Administrative priveleges then only the diffs
0
128 KiB
-
+
This element sets the size of a single receive buffer. Many receive buffers may be needed. Their size must be greater than ReceiveBufferChunkSize by a modest amount.
+This element sets the size of a single receive buffer. Many receive buffers may be needed. The minimum workable size a little bit larger than Sizing/ReceiveBufferChunkSize, and the value used is taken as the configured value and the actual minimum workable size.
+The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).
]]>
-
- This element controls whether DDSI2E will adapt the high-water mark to current traffic conditions, based on retransmit requests and transmit pressure.
- ]]>
- true
-
-
- This element sets the maximum allowed high-water mark for the DDSI2E WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size.
-The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).
- ]]>
- 0
- 100 kB
-
-
- This element sets the initial level of the high-water mark for the DDSI2E WHCs, expressed in bytes.
-The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).
- ]]>
- 0
- 30 kB
-
-
- This element sets the low-water mark for the DDSI2E WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2E WHC shrinks to this size.
-The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).
- ]]>
- 0
- 1 kB
-
-
+ 0
+ 1 MiB
+
The TCP element allows specifying various parameters related to running DDSI over TCP.
]]>
+ 0
Setting this to true means the unicast addresses in SPDP packets will be ignored and the peer address from the TCP connection will be used instead. This may help work around incorrectly advertised addresses when using TCP.
@@ -1195,7 +1070,7 @@ When an application is run without Administrative priveleges then only the diffs
This element specifies the TCP port number on which DDSI2E accepts connections. If the port is set it is used in entity locators, published with DDSI discovery. Dynamically allocated if zero. Disabled if -1 or not configured. If disabled other DDSI services will not be able to establish connections with the service, the service can only communicate by establishing connections to other services.
+This element specifies the TCP port number on which Cyclone DDS accepts connections. If the port is set it is used in entity locators, published with DDSI discovery. Dynamically allocated if zero. Disabled if -1 or not configured. If disabled other DDSI services will not be able to establish connections with the service, the service can only communicate by establishing connections to other services.
]]>
-1
65535
@@ -1226,6 +1101,7 @@ When an application is run without Administrative priveleges then only the diffs
The ThreadPool element allows specifying various parameters related to using a thread pool to send DDSI messages to multiple unicast addresses (TCP or UDP).
]]>
+ 0
This element enables the optional thread pool.
@@ -1249,7 +1125,8 @@ When an application is run without Administrative priveleges then only the diffs
This element is used to set thread properties.
]]>
-
+ 0
+
This element is used to set thread properties.
]]>
@@ -1304,6 +1181,7 @@ When an application is run without Administrative priveleges then only the diffs
The Tracing element controls the amount and type of information that is written into the tracing log by the DDSI service. This is useful to track the DDSI service during application development.
]]>
+ 0
This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated.
@@ -1338,7 +1216,7 @@ When an application is run without Administrative priveleges then only the diffs
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.
]]>
0
- .log
+ cyclonedds.log
0
-
- This option has no effect.
- ]]>
- true
-
- This option has no effect
- ]]>
- true
-
-
This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/EnableCategory setting. Recognised verbosity levels and the categories they map to are:
-- none: no DDSI2E log
+- none: no Cyclone DDS log
- severe: error and fatal
- warning: severe + warning
- info: warning + info
@@ -1370,7 +1236,7 @@ When an application is run without Administrative priveleges then only the diffs
- fine: config + discovery
- finer: fine + traffic and timing
- finest: finer + trace
-While none prevents any message from being written to a DDSI2 log file.
+While none prevents any message from being written to a Cyclone DDS 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.
]]>
finest
@@ -1384,40 +1250,5 @@ When an application is run without Administrative priveleges then only the diffs
none
-
- This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.
- ]]>
-
- This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.
- ]]>
-
- This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
- ]]>
- realtime
- timeshare
- default
- default
-
-
- This element specifies the thread priority. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.
- ]]>
- 0
-
- This attribute specifies whether the specified Priority is a relative or absolute priority.
- ]]>
- relative
- absolute
- relative
-
-
-
-
-
-
diff --git a/src/tools/config/org/eclipse/cyclonedds/config/SpliceConfig.java b/src/tools/config/org/eclipse/cyclonedds/config/CycloneConfig.java
similarity index 88%
rename from src/tools/config/org/eclipse/cyclonedds/config/SpliceConfig.java
rename to src/tools/config/org/eclipse/cyclonedds/config/CycloneConfig.java
index 71a3d0d..091a93c 100644
--- a/src/tools/config/org/eclipse/cyclonedds/config/SpliceConfig.java
+++ b/src/tools/config/org/eclipse/cyclonedds/config/CycloneConfig.java
@@ -15,17 +15,16 @@ import org.eclipse.cyclonedds.common.util.Initializer;
import org.eclipse.cyclonedds.common.util.Report;
import org.eclipse.cyclonedds.config.swing.ConfigWindow;
-public class SpliceConfig extends Initializer {
+public class CycloneConfig extends Initializer {
/**
- * Starts Splice Tuner. This function is the main class of Splice Tuner;
- * - It checks for the right version of the JVM, this must be 1.5.0.
+ * Starts configuration. This function is the main class.
+ *
* - It passes on the commandline arguments. Arguments that are supported
* are:
* -#
*
- * @param args These are passed on to the initialize function of the
- * SpliceTuner object.
+ * @param args These are passed on to the initialize function
*/
public static void main(String[] args) {
boolean redirect = true;
@@ -33,7 +32,7 @@ public class SpliceConfig extends Initializer {
String[] args2;
String uri = null;
- SpliceConfig t = new SpliceConfig();
+ CycloneConfig t = new CycloneConfig();
for (int i = 0; i < args.length; i++) {
if ("-noredirect".equals(args[i])) {
diff --git a/src/tools/config/org/eclipse/cyclonedds/config/swing/ConfigWindow.java b/src/tools/config/org/eclipse/cyclonedds/config/swing/ConfigWindow.java
index 26dc2ed..7e6d8ea 100644
--- a/src/tools/config/org/eclipse/cyclonedds/config/swing/ConfigWindow.java
+++ b/src/tools/config/org/eclipse/cyclonedds/config/swing/ConfigWindow.java
@@ -614,14 +614,8 @@ public class ConfigWindow extends MainWindow implements DataConfigurationListene
try {
List imgUrls = new ArrayList(4);
// Expected location of the icons in tuner jar
- URL url = getClass().getResource("/resources/ptlogoc16.png");
- imgUrls.add(url != null ? url : getClass().getResource("/ptlogoc16.png"));
- url = getClass().getResource("/resources/ptlogoc24.png");
- imgUrls.add(url != null ? url : getClass().getResource("/ptlogoc24.png"));
- url = getClass().getResource("/resources/ptlogoc32.png");
- imgUrls.add(url != null ? url : getClass().getResource("/ptlogoc32.png"));
- url = getClass().getResource("/resources/ptlogoc48.png");
- imgUrls.add(url != null ? url : getClass().getResource("/ptlogoc48.png"));
+ //URL url = getClass().getResource("/resources/LOGO.png");
+ //imgUrls.add(url != null ? url : getClass().getResource("/ptlogoc16.png"));
appLogos = new ArrayList(4);
for (URL imgUrl : imgUrls) {
diff --git a/src/tools/config/resources/ptlogoc16.png b/src/tools/config/resources/ptlogoc16.png
deleted file mode 100755
index dcabcd2..0000000
Binary files a/src/tools/config/resources/ptlogoc16.png and /dev/null differ
diff --git a/src/tools/config/resources/ptlogoc24.png b/src/tools/config/resources/ptlogoc24.png
deleted file mode 100755
index 3ddc6d1..0000000
Binary files a/src/tools/config/resources/ptlogoc24.png and /dev/null differ
diff --git a/src/tools/config/resources/ptlogoc32.png b/src/tools/config/resources/ptlogoc32.png
deleted file mode 100755
index d4957ae..0000000
Binary files a/src/tools/config/resources/ptlogoc32.png and /dev/null differ
diff --git a/src/tools/config/resources/ptlogoc48.png b/src/tools/config/resources/ptlogoc48.png
deleted file mode 100755
index 533131b..0000000
Binary files a/src/tools/config/resources/ptlogoc48.png and /dev/null differ
diff --git a/src/tools/ddsperf/ddsperf.c b/src/tools/ddsperf/ddsperf.c
index e4e8163..d0eeb89 100644
--- a/src/tools/ddsperf/ddsperf.c
+++ b/src/tools/ddsperf/ddsperf.c
@@ -1549,6 +1549,7 @@ OPTIONS:\n\
-M DUR require those participants to match within DUR seconds\n\
-R TREF timestamps in the output relative to TREF instead of\n\
process start\n\
+ -i ID use domain ID instead of the default domain\n\
\n\
MODE... is zero or more of:\n\
ping [R[Hz]] [size S] [waitset|listener]\n\
@@ -1856,7 +1857,7 @@ int main (int argc, char *argv[])
argv0 = argv[0];
- while ((opt = getopt (argc, argv, "cd:D:n:k:uLK:T:M:N:R:h")) != EOF)
+ while ((opt = getopt (argc, argv, "cd:D:i:n:k:uLK:T:M:N:R:h")) != EOF)
{
switch (opt)
{
@@ -1872,6 +1873,7 @@ int main (int argc, char *argv[])
break;
}
case 'D': dur = atof (optarg); if (dur <= 0) dur = HUGE_VAL; break;
+ case 'i': did = (dds_domainid_t) atoi (optarg); break;
case 'n': nkeyvals = (unsigned) atoi (optarg); break;
case 'u': reliable = false; break;
case 'k': histdepth = atoi (optarg); if (histdepth < 0) histdepth = 0; break;