diff --git a/src/core/ddsc/include/dds/dds.h b/src/core/ddsc/include/dds/dds.h
index a6f7f73..a2bdb5c 100644
--- a/src/core/ddsc/include/dds/dds.h
+++ b/src/core/ddsc/include/dds/dds.h
@@ -747,9 +747,35 @@ dds_create_participant(
* @brief Creates a domain with a given configuration
*
* To explicitly create a domain based on a configuration passed as a string.
- * Normally, the domain is created implicitly on the first call to
- * dds_create_particiant based on the configuration specified throught
- * the environment. This function allows to by-pass this behaviour.
+ *
+ * It will not be created if a domain with the given domain id already exists.
+ * This could have been created implicitly by a dds_create_participant().
+ *
+ * Please be aware that the given domain_id always takes precedence over the
+ * configuration.
+ *
+ * | domain_id | domain id in config | result
+ * +-----------+---------------------+----------
+ * | n | any (or absent) | n, config is used
+ * | n | m == n | n, config is used
+ * | n | m != n | n, config is ignored: default
+ *
+ * Config models:
+ * 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)
+ *
+ * Using NULL or "" as config will create a domain with default settings.
*
*
* @param[in] domain The domain to be created. DEFAULT_DOMAIN is not allowed.
@@ -759,7 +785,7 @@ dds_create_participant(
*
* @retval DDS_RETCODE_BAD_PARAMETER
* Illegal value for domain id or the configfile parameter is NULL.
- * @retval DDS_PRECONDITION_NOT_MET
+ * @retval DDS_RETCODE_PRECONDITION_NOT_MET
* The domain already existed and cannot be created again.
* @retval DDS_RETCODE_ERROR
* An internal error has occurred.
@@ -774,15 +800,10 @@ dds_create_domain(const dds_domainid_t domain, const char *config);
* For instance, it will return the Participant that was used when
* creating a Publisher (when that Publisher was provided here).
*
- * When a reader or a writer are created with a partition, then a
- * subscriber or publisher respectively are created implicitly. These
- * implicit subscribers or publishers will be deleted automatically
- * when the reader or writer is deleted. However, when this function
- * returns such an implicit entity, it is from there on out considered
- * 'explicit'. This means that it isn't deleted automatically anymore.
- * The application should explicitly call dds_delete on those entities
- * now (or delete the parent participant which will delete all entities
- * within its hierarchy).
+ * When a reader or a writer are created with a participant, then a
+ * subscriber or publisher are created implicitly.
+ * This function will return the implicit parent and not the used
+ * participant.
*
* @param[in] entity Entity from which to get its parent.
*
@@ -849,15 +870,10 @@ dds_get_participant(dds_entity_t entity);
* When supplying NULL as list and 0 as size, you can use this to acquire
* the number of children without having to pre-allocate a list.
*
- * When a reader or a writer are created with a partition, then a
- * subscriber or publisher respectively are created implicitly. These
- * implicit subscribers or publishers will be deleted automatically
- * when the reader or writer is deleted. However, when this function
- * returns such an implicit entity, it is from there on out considered
- * 'explicit'. This means that it isn't deleted automatically anymore.
- * The application should explicitly call dds_delete on those entities
- * now (or delete the parent participant which will delete all entities
- * within its hierarchy).
+ * When a reader or a writer are created with a participant, then a
+ * subscriber or publisher are created implicitly.
+ * When used on the participant, this function will return the implicit
+ * subscriber and/or publisher and not the related reader/writer.
*
* @param[in] entity Entity from which to get its children.
* @param[out] children Pre-allocated array to contain the found children.
@@ -866,7 +882,7 @@ dds_get_participant(dds_entity_t entity);
* @returns Number of children or an error code.
*
* @retval >=0
- * Number of childer found children (can be larger than 'size').
+ * Number of found children (can be larger than 'size').
* @retval DDS_RETCODE_ERROR
* An internal error has occurred.
* @retval DDS_RETCODE_BAD_PARAMETER
@@ -1197,6 +1213,7 @@ dds_wait_for_acks(dds_entity_t publisher_or_writer, dds_duration_t timeout);
/**
* @brief Creates a new instance of a DDS reader.
*
+ * When a participant is used to create a reader, an implicit subscriber is created.
* This implicit subscriber will be deleted automatically when the created reader
* is deleted.
*
@@ -1223,6 +1240,7 @@ dds_create_reader(
/**
* @brief Creates a new instance of a DDS reader with a custom history cache.
*
+ * When a participant is used to create a reader, an implicit subscriber is created.
* This implicit subscriber will be deleted automatically when the created reader
* is deleted.
*
@@ -1270,6 +1288,7 @@ dds_reader_wait_for_historical_data(
/**
* @brief Creates a new instance of a DDS writer.
*
+ * When a participant is used to create a writer, an implicit publisher is created.
* This implicit publisher will be deleted automatically when the created writer
* is deleted.
*
diff --git a/src/core/ddsc/src/dds_domain.c b/src/core/ddsc/src/dds_domain.c
index 78028af..686ffce 100644
--- a/src/core/ddsc/src/dds_domain.c
+++ b/src/core/ddsc/src/dds_domain.c
@@ -270,9 +270,12 @@ dds_entity_t dds_create_domain (const dds_domainid_t domain, const char *config)
dds_domain *dom;
dds_entity_t ret;
- if (domain == DDS_DOMAIN_DEFAULT || config == NULL)
+ if (domain > 230)
return DDS_RETCODE_BAD_PARAMETER;
+ if (config == NULL)
+ config = "";
+
/* Make sure DDS instance is initialized. */
if ((ret = dds_init ()) < 0)
return ret;
diff --git a/src/core/ddsc/tests/config.c b/src/core/ddsc/tests/config.c
index 6f5789c..82eda1b 100644
--- a/src/core/ddsc/tests/config.c
+++ b/src/core/ddsc/tests/config.c
@@ -83,30 +83,3 @@ CU_Test (ddsc_config, user_config, .init = ddsrt_init, .fini = ddsrt_fini)
dds_delete (domain);
}
-CU_Test (ddsc_config, incorrect_config, .init = ddsrt_init, .fini = ddsrt_fini)
-{
- dds_entity_t dom;
-
- dom = dds_create_domain (1, NULL);
- CU_ASSERT_FATAL (dom == DDS_RETCODE_BAD_PARAMETER);
-
- dom = dds_create_domain (1, "any"
- "2"
- ""DDS_PROJECT_NAME">");
- CU_ASSERT_FATAL (dom == DDS_RETCODE_BAD_PARAMETER);
-
- dom = dds_create_domain (2,
- "<"DDS_PROJECT_NAME">any"
- "2"
- ""DDS_PROJECT_NAME">");
- CU_ASSERT_FATAL (dom > 0);
-
- /* 2nd attempt at creating the same domain should fail */
- CU_ASSERT_FATAL (dds_create_domain (2, "") == DDS_RETCODE_PRECONDITION_NOT_MET);
-
- dds_delete (dom);
-}
diff --git a/src/core/ddsc/tests/domain.c b/src/core/ddsc/tests/domain.c
index ea4f4cf..4f10beb 100644
--- a/src/core/ddsc/tests/domain.c
+++ b/src/core/ddsc/tests/domain.c
@@ -140,3 +140,157 @@ CU_Test(ddsc_domain, delete_cyclonedds)
rc = dds_get_domainid (pp[0], &did);
CU_ASSERT_FATAL (rc == DDS_RETCODE_PRECONDITION_NOT_MET);
}
+
+CU_Test(ddsc_domain_create, valid)
+{
+ dds_return_t ret;
+ dds_domainid_t did;
+ dds_entity_t domain;
+
+ domain = dds_create_domain(1, "<"DDS_PROJECT_NAME">1"DDS_PROJECT_NAME">");
+ CU_ASSERT_FATAL(domain > 0);
+
+ ret = dds_get_domainid (domain, &did);
+ CU_ASSERT_FATAL(ret == DDS_RETCODE_OK);
+ CU_ASSERT_FATAL(did == 1);
+
+ ret = dds_delete(domain);
+ CU_ASSERT_FATAL(ret == DDS_RETCODE_OK);
+ ret = dds_delete(domain);
+ CU_ASSERT_FATAL(ret != DDS_RETCODE_OK);
+}
+
+CU_Test(ddsc_domain_create, mismatch)
+{
+ dds_return_t ret;
+ dds_domainid_t did;
+ dds_entity_t domain;
+
+ /* The config should have been ignored. */
+ domain = dds_create_domain(2, "<"DDS_PROJECT_NAME">3"DDS_PROJECT_NAME">");
+ CU_ASSERT_FATAL(domain > 0);
+
+ ret = dds_get_domainid (domain, &did);
+ CU_ASSERT_FATAL(ret == DDS_RETCODE_OK);
+ CU_ASSERT_FATAL(did == 2);
+
+ ret = dds_delete(domain);
+ CU_ASSERT_FATAL(ret == DDS_RETCODE_OK);
+}
+
+CU_Test(ddsc_domain_create, empty)
+{
+ dds_return_t ret;
+ dds_domainid_t did;
+ dds_entity_t domain;
+
+ /* This should create a domain with default settings. */
+ domain = dds_create_domain(3, "");
+ CU_ASSERT_FATAL(domain > 0);
+
+ ret = dds_get_domainid (domain, &did);
+ CU_ASSERT_FATAL(ret == DDS_RETCODE_OK);
+ CU_ASSERT_FATAL(did == 3);
+
+ ret = dds_delete(domain);
+ CU_ASSERT_FATAL(ret == DDS_RETCODE_OK);
+}
+
+CU_Test(ddsc_domain_create, null)
+{
+ dds_return_t ret;
+ dds_domainid_t did;
+ dds_entity_t domain;
+
+ /* This should start create a domain with default settings. */
+ domain = dds_create_domain(5, NULL);
+ CU_ASSERT_FATAL(domain > 0);
+
+ ret = dds_get_domainid (domain, &did);
+ CU_ASSERT_FATAL(ret == DDS_RETCODE_OK);
+ CU_ASSERT_FATAL(did == 5);
+
+ ret = dds_delete(domain);
+ CU_ASSERT_FATAL(ret == DDS_RETCODE_OK);
+}
+
+CU_Test(ddsc_domain_create, after_domain)
+{
+ dds_entity_t domain1;
+ dds_entity_t domain2;
+
+ domain1 = dds_create_domain(4, "<"DDS_PROJECT_NAME">any"DDS_PROJECT_NAME">");
+ CU_ASSERT_FATAL(domain1 > 0);
+
+ domain2 = dds_create_domain(4, "<"DDS_PROJECT_NAME">any"DDS_PROJECT_NAME">");
+ CU_ASSERT_FATAL(domain2 == DDS_RETCODE_PRECONDITION_NOT_MET);
+
+ dds_delete(domain1);
+}
+
+CU_Test(ddsc_domain_create, after_participant)
+{
+ dds_entity_t domain;
+ dds_entity_t participant;
+
+ participant = dds_create_participant (5, NULL, NULL);
+ CU_ASSERT_FATAL(participant > 0);
+
+ domain = dds_create_domain(5, "<"DDS_PROJECT_NAME">any"DDS_PROJECT_NAME">");
+ CU_ASSERT_FATAL(domain == DDS_RETCODE_PRECONDITION_NOT_MET);
+
+ dds_delete(participant);
+}
+
+CU_Test(ddsc_domain_create, diff)
+{
+ dds_return_t ret;
+ dds_domainid_t did;
+ dds_entity_t domain1;
+ dds_entity_t domain2;
+
+ domain1 = dds_create_domain(1, "<"DDS_PROJECT_NAME">any"DDS_PROJECT_NAME">");
+ CU_ASSERT_FATAL(domain1 > 0);
+
+ domain2 = dds_create_domain(2, "<"DDS_PROJECT_NAME">any"DDS_PROJECT_NAME">");
+ CU_ASSERT_FATAL(domain2 > 0);
+
+ ret = dds_get_domainid (domain1, &did);
+ CU_ASSERT_FATAL(ret == DDS_RETCODE_OK);
+ CU_ASSERT_FATAL(did == 1);
+
+ ret = dds_get_domainid (domain2, &did);
+ CU_ASSERT_FATAL(ret == DDS_RETCODE_OK);
+ CU_ASSERT_FATAL(did == 2);
+
+ ret = dds_delete(domain1);
+ CU_ASSERT_FATAL(ret == DDS_RETCODE_OK);
+ ret = dds_delete(domain2);
+ CU_ASSERT_FATAL(ret == DDS_RETCODE_OK);
+
+ ret = dds_delete(domain1);
+ CU_ASSERT_FATAL(ret != DDS_RETCODE_OK);
+ ret = dds_delete(domain2);
+ CU_ASSERT_FATAL(ret != DDS_RETCODE_OK);
+}
+
+CU_Test(ddsc_domain_create, domain_default)
+{
+ dds_entity_t domain;
+ domain = dds_create_domain(DDS_DOMAIN_DEFAULT, "<"DDS_PROJECT_NAME">any"DDS_PROJECT_NAME">");
+ CU_ASSERT_FATAL(domain == DDS_RETCODE_BAD_PARAMETER);
+}
+
+CU_Test(ddsc_domain_create, invalid_xml)
+{
+ dds_entity_t domain;
+ domain = dds_create_domain(1, "any"DDS_PROJECT_NAME">");
+ CU_ASSERT_FATAL(domain == DDS_RETCODE_BAD_PARAMETER);
+}
diff --git a/src/core/ddsc/tests/entity_hierarchy.c b/src/core/ddsc/tests/entity_hierarchy.c
index 04f7f96..44d5917 100644
--- a/src/core/ddsc/tests/entity_hierarchy.c
+++ b/src/core/ddsc/tests/entity_hierarchy.c
@@ -992,6 +992,70 @@ CU_Test(ddsc_entity_get_parent, implicit_subscriber)
}
/*************************************************************************************************/
+/*************************************************************************************************/
+CU_Test(ddsc_entity_implicit, delete_publisher)
+{
+ dds_entity_t participant;
+ dds_entity_t writer;
+ dds_entity_t parent;
+ dds_entity_t topic;
+ dds_return_t ret;
+ char name[100];
+
+ participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
+ CU_ASSERT_FATAL(participant > 0);
+
+ topic = dds_create_topic(participant, &RoundTripModule_DataType_desc, create_topic_name("ddsc_entity_implicit_delete_publisher", name, 100), NULL, NULL);
+ CU_ASSERT_FATAL(topic > 0);
+
+ writer = dds_create_writer(participant, topic, NULL, NULL);
+ CU_ASSERT_FATAL(writer > 0);
+
+ parent = dds_get_parent(writer);
+ CU_ASSERT_FATAL(parent > 0);
+
+ ret = dds_delete(parent);
+ CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
+
+ ret = dds_delete(writer);
+ CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER);
+
+ dds_delete(participant);
+}
+/*************************************************************************************************/
+
+/*************************************************************************************************/
+CU_Test(ddsc_entity_implicit, delete_subscriber)
+{
+ dds_entity_t participant;
+ dds_entity_t reader;
+ dds_entity_t parent;
+ dds_entity_t topic;
+ dds_return_t ret;
+ char name[100];
+
+ participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
+ CU_ASSERT_FATAL(participant > 0);
+
+ topic = dds_create_topic(participant, &RoundTripModule_DataType_desc, create_topic_name("ddsc_entity_implicit_delete_subscriber", name, 100), NULL, NULL);
+ CU_ASSERT_FATAL(topic > 0);
+
+ reader = dds_create_reader(participant, topic, NULL, NULL);
+ CU_ASSERT_FATAL(reader > 0);
+
+ parent = dds_get_parent(reader);
+ CU_ASSERT_FATAL(parent > 0);
+
+ ret = dds_delete(parent);
+ CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
+
+ ret = dds_delete(reader);
+ CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER);
+
+ dds_delete(participant);
+}
+/*************************************************************************************************/
+
/*************************************************************************************************/
#endif