Table-driven parameter list handling

The old parameter list parsing was a mess of custom code with tons of
duplicated checks, even though parameter list parsing really is a fairly
straightforward affair.  This commit changes it to a mostly table-driven
implementation, where the vast majority of the settings are handled by a
generic deserializer and the irregular ones (like reliability, locators)
are handled by custom functions.  The crazy ones (IPv4 address and port
rely on additional state and are completely special-cased).

Given these tables, the serialization, finalisation, validation,
merging, unalias'ing can all be handled by a very small amount of custom
code and an appropriately defined generic function for the common cases.
This also makes it possible to have all QoS validation in place, and so
removes the need for the specialized implementations for the various
entity kinds in the upper layer.

QoS inapplicable to an entity were previously ignored, allowing one to
have invalid values set in a QoS object when creating an entity,
provided that the invalid values are irrelevant to that entity.  Whether
this is a good thing or not is debatable, but certainly it is a good
thing to avoid copying in inapplicable QoS settings.  That in turn means
the behaviour of the API can remain the same.

It does turn out that the code used to return "inconsistent QoS" also
for invalid values.  That has now been rectified, and it returns
"inconsistent QoS" or "bad parameter" as appropriate.  Tests have been
updated accordingly.

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2019-05-29 14:03:53 +02:00 committed by eboasson
parent 8ae81db490
commit 3322fc086d
36 changed files with 2367 additions and 2735 deletions

View file

@ -374,7 +374,8 @@ dds_qset_durability_service (
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
* @param[in] ignore - True if readers and writers owned by the same participant should be ignored
*/
DDS_EXPORT void dds_qset_ignorelocal (
DDS_EXPORT void
dds_qset_ignorelocal (
dds_qos_t * __restrict qos,
dds_ignorelocal_kind_t ignore);

View file

@ -14,21 +14,11 @@
#include "dds__entity.h"
#include "dds/ddsi/q_xqos.h"
#include "dds/ddsi/q_time.h"
#include "dds/ddsi/q_plist.h"
#if defined (__cplusplus)
extern "C" {
#endif
bool validate_deadline_and_timebased_filter (const dds_duration_t deadline, const dds_duration_t minimum_separation);
bool validate_entityfactory_qospolicy (const dds_entity_factory_qospolicy_t * entityfactory);
bool validate_octetseq (const ddsi_octetseq_t* seq);
bool validate_partition_qospolicy (const dds_partition_qospolicy_t * partition);
bool validate_reliability_qospolicy (const dds_reliability_qospolicy_t * reliability);
bool validate_stringseq (const ddsi_stringseq_t* seq);
bool dds_qos_validate_common (const dds_qos_t *qos);
dds_return_t dds_qos_validate_mutable_common (const dds_qos_t *qos);
#if defined (__cplusplus)

View file

@ -11,9 +11,11 @@
*/
#include <assert.h>
#include <string.h>
#include "dds/ddsrt/string.h"
#include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_thread.h"
#include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_plist.h" /* for nn_keyhash */
#include "dds__init.h"
#include "dds__qos.h"
#include "dds__domain.h"
@ -103,6 +105,7 @@ dds_entity_t dds__get_builtin_topic (dds_entity_t e, dds_entity_t topic)
static bool qos_has_resource_limits (const dds_qos_t *qos)
{
assert (qos->present & QP_RESOURCE_LIMITS);
return (qos->resource_limits.max_samples != DDS_LENGTH_UNLIMITED ||
qos->resource_limits.max_instances != DDS_LENGTH_UNLIMITED ||
qos->resource_limits.max_samples_per_instance != DDS_LENGTH_UNLIMITED);
@ -115,8 +118,9 @@ bool dds__validate_builtin_reader_qos (dds_entity_t topic, const dds_qos_t *qos)
return true;
else
{
/* failing writes on built-in topics are unwelcome complications, so we simply forbid the creation of
a reader matching a built-in topics writer that has resource limits */
/* failing writes on built-in topics are unwelcome complications, so we simply
forbid the creation of a reader matching a built-in topics writer that has
resource limits */
struct local_orphan_writer *bwr;
if (topic == DDS_BUILTIN_TOPIC_DCPSPARTICIPANT) {
bwr = builtintopic_writer_participant;
@ -128,7 +132,15 @@ bool dds__validate_builtin_reader_qos (dds_entity_t topic, const dds_qos_t *qos)
assert (0);
return false;
}
return !qos_match_p (qos, bwr->wr.xqos, NULL) && !qos_has_resource_limits (qos);
/* FIXME: DDSI-level readers, writers have topic, type name in their QoS, but
DDSC-level ones don't and that gives an automatic mismatch when comparing
the full QoS object ... Here the two have the same topic by construction
so ignoring them in the comparison makes things work. The discrepancy
should be addressed one day. */
const uint64_t qmask = ~(QP_TOPIC_NAME | QP_TYPE_NAME);
dds_qos_policy_id_t dummy;
return qos_match_mask_p (qos, bwr->wr.xqos, qmask, &dummy) && !qos_has_resource_limits (qos);
}
}

View file

@ -20,6 +20,7 @@
#include "dds__reader.h"
#include "dds__listener.h"
#include "dds/version.h"
#include "dds/ddsi/q_xqos.h"
extern inline dds_entity *dds_entity_from_handle_link (struct dds_handle_link *hdllink);
extern inline bool dds_entity_is_enabled (const dds_entity *e);
@ -354,7 +355,8 @@ dds_return_t dds_get_qos (dds_entity_t entity, dds_qos_t *qos)
else
{
dds_reset_qos (qos);
ret = dds_copy_qos (qos, e->m_qos);
nn_xqos_mergein_missing (qos, e->m_qos, ~(QP_TOPIC_NAME | QP_TYPE_NAME));
ret = DDS_RETCODE_OK;
}
dds_entity_unlock(e);
return ret;

View file

@ -15,6 +15,7 @@
#include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_thread.h"
#include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_plist.h"
#include "dds__init.h"
#include "dds__qos.h"
#include "dds__domain.h"
@ -73,13 +74,10 @@ static dds_return_t dds_participant_qos_validate (const dds_qos_t *qos, bool ena
static dds_return_t dds_participant_qos_validate (const dds_qos_t *qos, bool enabled)
{
dds_return_t ret;
(void)enabled;
if ((qos->present & QP_USER_DATA) && !validate_octetseq (&qos->user_data))
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy (&qos->entity_factory))
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((ret = nn_xqos_valid (qos)) < 0)
return ret;
return DDS_RETCODE_OK;
}
@ -112,13 +110,14 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_
if ((ret = dds__check_domain (domain)) != DDS_RETCODE_OK)
goto err_domain_check;
/* Validate qos or use default if NULL */
if (qos && (ret = dds_participant_qos_validate (qos, false)) != DDS_RETCODE_OK)
goto err_qos_validation;
#define DDS_QOSMASK_PARTICIPANT (QP_USER_DATA | QP_PRISMTECH_ENTITY_FACTORY | QP_CYCLONE_IGNORELOCAL)
new_qos = dds_create_qos ();
if (qos != NULL)
(void) dds_copy_qos (new_qos, qos);
nn_xqos_mergein_missing (new_qos, qos, DDS_QOSMASK_PARTICIPANT);
/* Validate qos or use default if NULL */
if ((ret = dds_participant_qos_validate (new_qos, false)) != DDS_RETCODE_OK)
goto err_qos_validation;
/* Translate qos */
nn_plist_init_empty (&plist);
@ -157,8 +156,8 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_
err_entity_init:
dds_free (pp);
err_new_participant:
dds_delete_qos (new_qos);
err_qos_validation:
dds_delete_qos (new_qos);
err_domain_check:
dds_fini ();
err_dds_init:

View file

@ -17,6 +17,7 @@
#include "dds__publisher.h"
#include "dds__qos.h"
#include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_globals.h"
#include "dds/version.h"
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_publisher)
@ -37,14 +38,9 @@ static dds_return_t dds_publisher_qos_validate (const dds_qos_t *qos, bool enabl
static dds_return_t dds_publisher_qos_validate (const dds_qos_t *qos, bool enabled)
{
if ((qos->present & QP_GROUP_DATA) && !validate_octetseq (&qos->group_data))
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_PRESENTATION) && validate_presentation_qospolicy (&qos->presentation) < 0)
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_PARTITION) && !validate_stringseq (&qos->partition))
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy (&qos->entity_factory))
return DDS_RETCODE_INCONSISTENT_POLICY;
dds_return_t ret;
if ((ret = nn_xqos_valid (qos)) < 0)
return ret;
/* FIXME: Improve/check immutable check. */
if (enabled && (qos->present & QP_PRESENTATION))
return DDS_RETCODE_IMMUTABLE_POLICY;
@ -74,21 +70,25 @@ dds_entity_t dds_create_publisher (dds_entity_t participant, const dds_qos_t *qo
dds_participant *par;
dds_publisher *pub;
dds_entity_t hdl;
dds_qos_t *new_qos = NULL;
dds_qos_t *new_qos;
dds_return_t ret;
if (qos && (ret = dds_publisher_qos_validate (qos, false)) != DDS_RETCODE_OK)
return ret;
if ((ret = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
return ret;
#define DDS_QOSMASK_PUBLISHER (QP_PARTITION | QP_PRESENTATION | QP_GROUP_DATA | QP_PRISMTECH_ENTITY_FACTORY | QP_CYCLONE_IGNORELOCAL)
new_qos = dds_create_qos ();
if (qos)
nn_xqos_mergein_missing (new_qos, qos, DDS_QOSMASK_PUBLISHER);
nn_xqos_mergein_missing (new_qos, &gv.default_xqos_pub, ~(uint64_t)0);
if ((ret = dds_publisher_qos_validate (new_qos, false)) != DDS_RETCODE_OK)
{
new_qos = dds_create_qos ();
(void) dds_copy_qos (new_qos, qos);
dds_delete_qos (new_qos);
return ret;
}
if ((ret = dds_participant_lock (participant, &par)) != DDS_RETCODE_OK)
{
dds_delete_qos (new_qos);
return ret;
}
pub = dds_alloc (sizeof (*pub));
hdl = dds_entity_init (&pub->m_entity, &par->m_entity, DDS_KIND_PUBLISHER, new_qos, listener, DDS_PUBLISHER_STATUS_MASK);
pub->m_entity.m_deriver.set_qos = dds_publisher_qos_set;

View file

@ -12,21 +12,16 @@
#include <assert.h>
#include <string.h>
#include "dds__qos.h"
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/string.h"
#include "dds/ddsi/q_config.h"
static void dds_qos_data_copy_in (ddsi_octetseq_t *data, const void * __restrict value, size_t sz)
static void dds_qos_data_copy_in (ddsi_octetseq_t *data, const void * __restrict value, size_t sz, bool overwrite)
{
if (data->value)
{
dds_free (data->value);
data->value = NULL;
}
if (overwrite && data->value)
ddsrt_free (data->value);
data->length = (uint32_t) sz;
if (sz && value)
{
data->value = dds_alloc (sz);
memcpy (data->value, value, sz);
}
data->value = ddsrt_memdup (value, sz);
}
static bool dds_qos_data_copy_out (const ddsi_octetseq_t *data, void **value, size_t *sz)
@ -52,57 +47,6 @@ static bool dds_qos_data_copy_out (const ddsi_octetseq_t *data, void **value, si
return true;
}
bool validate_octetseq (const ddsi_octetseq_t *seq)
{
/* default value is NULL with length 0 */
return ((seq->length == 0 && seq->value == NULL) || (seq->length > 0 && seq->length < UINT32_MAX));
}
bool validate_stringseq (const ddsi_stringseq_t *seq)
{
if (seq->n == 0)
return (seq->strs == NULL);
else
{
for (uint32_t i = 0; i < seq->n; i++)
if (seq->strs[i] == NULL)
return false;
return true;
}
}
bool validate_entityfactory_qospolicy (const dds_entity_factory_qospolicy_t *entityfactory)
{
/* Bools must be 0 or 1, i.e., only the lsb may be set */
return !(entityfactory->autoenable_created_entities & ~1);
}
bool validate_reliability_qospolicy (const dds_reliability_qospolicy_t *reliability)
{
return ((reliability->kind == DDS_RELIABILITY_BEST_EFFORT || reliability->kind == DDS_RELIABILITY_RELIABLE) &&
(validate_duration (reliability->max_blocking_time) == 0));
}
bool validate_deadline_and_timebased_filter (const dds_duration_t deadline, const dds_duration_t minimum_separation)
{
return (validate_duration (deadline) == DDS_RETCODE_OK &&
validate_duration (minimum_separation) == DDS_RETCODE_OK &&
minimum_separation <= deadline);
}
bool dds_qos_validate_common (const dds_qos_t *qos)
{
return !(((qos->present & QP_DURABILITY) && validate_durability_qospolicy (&qos->durability) != DDS_RETCODE_OK) ||
((qos->present & QP_DEADLINE) && validate_duration (qos->deadline.deadline) != DDS_RETCODE_OK) ||
((qos->present & QP_LATENCY_BUDGET) && validate_duration (qos->latency_budget.duration) != DDS_RETCODE_OK) ||
((qos->present & QP_OWNERSHIP) && validate_ownership_qospolicy (&qos->ownership) != DDS_RETCODE_OK) ||
((qos->present & QP_LIVELINESS) && validate_liveliness_qospolicy (&qos->liveliness) != DDS_RETCODE_OK) ||
((qos->present & QP_RELIABILITY) && ! validate_reliability_qospolicy (&qos->reliability)) ||
((qos->present & QP_DESTINATION_ORDER) && validate_destination_order_qospolicy (&qos->destination_order) != DDS_RETCODE_OK) ||
((qos->present & QP_HISTORY) && validate_history_qospolicy (&qos->history) != DDS_RETCODE_OK) ||
((qos->present & QP_RESOURCE_LIMITS) && validate_resource_limits_qospolicy (&qos->resource_limits) != DDS_RETCODE_OK));
}
dds_return_t dds_qos_validate_mutable_common (const dds_qos_t *qos)
{
/* FIXME: Check whether immutable QoS are changed should actually incorporate change to current QoS */
@ -123,44 +67,10 @@ dds_return_t dds_qos_validate_mutable_common (const dds_qos_t *qos)
return DDS_RETCODE_OK;
}
static void dds_qos_init_defaults (dds_qos_t * __restrict qos) ddsrt_nonnull_all;
static void dds_qos_init_defaults (dds_qos_t * __restrict qos)
{
assert (qos);
memset (qos, 0, sizeof (*qos));
qos->durability.kind = DDS_DURABILITY_VOLATILE;
qos->deadline.deadline = DDS_INFINITY;
qos->durability_service.service_cleanup_delay = 0;
qos->durability_service.history.kind = DDS_HISTORY_KEEP_LAST;
qos->durability_service.history.depth = 1;
qos->durability_service.resource_limits.max_samples = DDS_LENGTH_UNLIMITED;
qos->durability_service.resource_limits.max_instances = DDS_LENGTH_UNLIMITED;
qos->durability_service.resource_limits.max_samples_per_instance = DDS_LENGTH_UNLIMITED;
qos->presentation.access_scope = DDS_PRESENTATION_INSTANCE;
qos->latency_budget.duration = 0;
qos->ownership.kind = DDS_OWNERSHIP_SHARED;
qos->liveliness.kind = DDS_LIVELINESS_AUTOMATIC;
qos->liveliness.lease_duration = DDS_INFINITY;
qos->time_based_filter.minimum_separation = 0;
qos->reliability.kind = DDS_RELIABILITY_BEST_EFFORT;
qos->reliability.max_blocking_time = DDS_MSECS (100);
qos->lifespan.duration = DDS_INFINITY;
qos->destination_order.kind = DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP;
qos->history.kind = DDS_HISTORY_KEEP_LAST;
qos->history.depth = 1;
qos->resource_limits.max_samples = DDS_LENGTH_UNLIMITED;
qos->resource_limits.max_instances = DDS_LENGTH_UNLIMITED;
qos->resource_limits.max_samples_per_instance = DDS_LENGTH_UNLIMITED;
qos->writer_data_lifecycle.autodispose_unregistered_instances = true;
qos->reader_data_lifecycle.autopurge_nowriter_samples_delay = DDS_INFINITY;
qos->reader_data_lifecycle.autopurge_disposed_samples_delay = DDS_INFINITY;
}
dds_qos_t *dds_create_qos (void)
{
dds_qos_t *qos = dds_alloc (sizeof (dds_qos_t));
dds_qos_init_defaults (qos);
dds_qos_t *qos = ddsrt_malloc (sizeof (dds_qos_t));
nn_xqos_init_empty (qos);
return qos;
}
@ -174,7 +84,7 @@ void dds_reset_qos (dds_qos_t * __restrict qos)
if (qos)
{
nn_xqos_fini (qos);
dds_qos_init_defaults (qos);
nn_xqos_init_empty (qos);
}
}
@ -187,8 +97,8 @@ void dds_delete_qos (dds_qos_t * __restrict qos)
{
if (qos)
{
dds_reset_qos(qos);
dds_free(qos);
nn_xqos_fini (qos);
ddsrt_free (qos);
}
}
@ -214,7 +124,7 @@ void dds_merge_qos (dds_qos_t * __restrict dst, const dds_qos_t * __restrict src
{
/* Copy qos from source to destination unless already set */
if (src != NULL && dst != NULL)
nn_xqos_mergein_missing (dst, src);
nn_xqos_mergein_missing (dst, src, ~(uint64_t)0);
}
void dds_qos_merge (dds_qos_t * __restrict dst, const dds_qos_t * __restrict src)
@ -235,155 +145,140 @@ bool dds_qos_equal (const dds_qos_t * __restrict a, const dds_qos_t * __restrict
void dds_qset_userdata (dds_qos_t * __restrict qos, const void * __restrict value, size_t sz)
{
if (qos != NULL)
{
dds_qos_data_copy_in (&qos->user_data, value, sz);
qos->present |= QP_USER_DATA;
}
if (qos == NULL || (sz > 0 && value == NULL))
return;
dds_qos_data_copy_in (&qos->user_data, value, sz, qos->present & QP_USER_DATA);
qos->present |= QP_USER_DATA;
}
void dds_qset_topicdata (dds_qos_t * __restrict qos, const void * __restrict value, size_t sz)
{
if (qos != NULL)
{
dds_qos_data_copy_in (&qos->topic_data, value, sz);
qos->present |= QP_TOPIC_DATA;
}
if (qos == NULL || (sz > 0 && value == NULL))
return;
dds_qos_data_copy_in (&qos->topic_data, value, sz, qos->present & QP_TOPIC_DATA);
qos->present |= QP_TOPIC_DATA;
}
void dds_qset_groupdata (dds_qos_t * __restrict qos, const void * __restrict value, size_t sz)
{
if (qos != NULL)
{
dds_qos_data_copy_in (&qos->group_data, value, sz);
qos->present |= QP_GROUP_DATA;
}
if (qos == NULL || (sz > 0 && value == NULL))
return;
dds_qos_data_copy_in (&qos->group_data, value, sz, qos->present & QP_GROUP_DATA);
qos->present |= QP_GROUP_DATA;
}
void dds_qset_durability (dds_qos_t * __restrict qos, dds_durability_kind_t kind)
{
if (qos != NULL)
{
qos->durability.kind = kind;
qos->present |= QP_DURABILITY;
}
if (qos == NULL)
return;
qos->durability.kind = kind;
qos->present |= QP_DURABILITY;
}
void dds_qset_history (dds_qos_t * __restrict qos, dds_history_kind_t kind, int32_t depth)
{
if (qos != NULL)
{
qos->history.kind = kind;
qos->history.depth = depth;
qos->present |= QP_HISTORY;
}
if (qos == NULL)
return;
qos->history.kind = kind;
qos->history.depth = depth;
qos->present |= QP_HISTORY;
}
void dds_qset_resource_limits (dds_qos_t * __restrict qos, int32_t max_samples, int32_t max_instances, int32_t max_samples_per_instance)
{
if (qos != NULL)
{
qos->resource_limits.max_samples = max_samples;
qos->resource_limits.max_instances = max_instances;
qos->resource_limits.max_samples_per_instance = max_samples_per_instance;
qos->present |= QP_RESOURCE_LIMITS;
}
if (qos == NULL)
return;
qos->resource_limits.max_samples = max_samples;
qos->resource_limits.max_instances = max_instances;
qos->resource_limits.max_samples_per_instance = max_samples_per_instance;
qos->present |= QP_RESOURCE_LIMITS;
}
void dds_qset_presentation (dds_qos_t * __restrict qos, dds_presentation_access_scope_kind_t access_scope, bool coherent_access, bool ordered_access)
{
if (qos != NULL)
{
qos->presentation.access_scope = access_scope;
qos->presentation.coherent_access = coherent_access;
qos->presentation.ordered_access = ordered_access;
qos->present |= QP_PRESENTATION;
}
if (qos == NULL)
return;
qos->presentation.access_scope = access_scope;
qos->presentation.coherent_access = coherent_access;
qos->presentation.ordered_access = ordered_access;
qos->present |= QP_PRESENTATION;
}
void dds_qset_lifespan (dds_qos_t * __restrict qos, dds_duration_t lifespan)
{
if (qos != NULL)
{
qos->lifespan.duration = lifespan;
qos->present |= QP_LIFESPAN;
}
if (qos == NULL)
return;
qos->lifespan.duration = lifespan;
qos->present |= QP_LIFESPAN;
}
void dds_qset_deadline (dds_qos_t * __restrict qos, dds_duration_t deadline)
{
if (qos != NULL)
{
qos->deadline.deadline = deadline;
qos->present |= QP_DEADLINE;
}
if (qos == NULL)
return;
qos->deadline.deadline = deadline;
qos->present |= QP_DEADLINE;
}
void dds_qset_latency_budget (dds_qos_t * __restrict qos, dds_duration_t duration)
{
if (qos != NULL)
{
qos->latency_budget.duration = duration;
qos->present |= QP_LATENCY_BUDGET;
}
if (qos == NULL)
return;
qos->latency_budget.duration = duration;
qos->present |= QP_LATENCY_BUDGET;
}
void dds_qset_ownership (dds_qos_t * __restrict qos, dds_ownership_kind_t kind)
{
if (qos != NULL)
{
qos->ownership.kind = kind;
qos->present |= QP_OWNERSHIP;
}
if (qos == NULL)
return;
qos->ownership.kind = kind;
qos->present |= QP_OWNERSHIP;
}
void dds_qset_ownership_strength (dds_qos_t * __restrict qos, int32_t value)
{
if (qos != NULL)
{
qos->ownership_strength.value = value;
qos->present |= QP_OWNERSHIP_STRENGTH;
}
if (qos == NULL)
return;
qos->ownership_strength.value = value;
qos->present |= QP_OWNERSHIP_STRENGTH;
}
void dds_qset_liveliness (dds_qos_t * __restrict qos, dds_liveliness_kind_t kind, dds_duration_t lease_duration)
{
if (qos != NULL)
{
qos->liveliness.kind = kind;
qos->liveliness.lease_duration = lease_duration;
qos->present |= QP_LIVELINESS;
}
if (qos == NULL)
return;
qos->liveliness.kind = kind;
qos->liveliness.lease_duration = lease_duration;
qos->present |= QP_LIVELINESS;
}
void dds_qset_time_based_filter (dds_qos_t * __restrict qos, dds_duration_t minimum_separation)
{
if (qos != NULL)
{
qos->time_based_filter.minimum_separation = minimum_separation;
qos->present |= QP_TIME_BASED_FILTER;
}
if (qos == NULL)
return;
qos->time_based_filter.minimum_separation = minimum_separation;
qos->present |= QP_TIME_BASED_FILTER;
}
void dds_qset_partition (dds_qos_t * __restrict qos, uint32_t n, const char ** __restrict ps)
{
if (qos == NULL || (n && ps == NULL))
if (qos == NULL || (n > 0 && ps == NULL))
return;
if (qos->partition.strs != NULL)
if (qos->present & QP_PARTITION)
{
for (uint32_t i = 0; i < qos->partition.n; i++)
dds_free (qos->partition.strs[i]);
dds_free (qos->partition.strs);
qos->partition.strs = NULL;
ddsrt_free (qos->partition.strs[i]);
ddsrt_free (qos->partition.strs);
}
qos->partition.n = n;
if (n > 0)
if (qos->partition.n == 0)
qos->partition.strs = NULL;
else
{
qos->partition.strs = dds_alloc (sizeof (char*) * n);
qos->partition.strs = ddsrt_malloc (n * sizeof (*qos->partition.strs));
for (uint32_t i = 0; i < n; i++)
qos->partition.strs[i] = dds_string_dup (ps[i]);
qos->partition.strs[i] = ddsrt_strdup (ps[i]);
}
qos->present |= QP_PARTITION;
}
@ -398,72 +293,65 @@ void dds_qset_partition1 (dds_qos_t * __restrict qos, const char * __restrict na
void dds_qset_reliability (dds_qos_t * __restrict qos, dds_reliability_kind_t kind, dds_duration_t max_blocking_time)
{
if (qos != NULL)
{
qos->reliability.kind = kind;
qos->reliability.max_blocking_time = max_blocking_time;
qos->present |= QP_RELIABILITY;
}
if (qos == NULL)
return;
qos->reliability.kind = kind;
qos->reliability.max_blocking_time = max_blocking_time;
qos->present |= QP_RELIABILITY;
}
void dds_qset_transport_priority (dds_qos_t * __restrict qos, int32_t value)
{
if (qos != NULL)
{
qos->transport_priority.value = value;
qos->present |= QP_TRANSPORT_PRIORITY;
}
if (qos == NULL)
return;
qos->transport_priority.value = value;
qos->present |= QP_TRANSPORT_PRIORITY;
}
void dds_qset_destination_order (dds_qos_t * __restrict qos, dds_destination_order_kind_t kind)
{
if (qos != NULL)
{
qos->destination_order.kind = kind;
qos->present |= QP_DESTINATION_ORDER;
}
if (qos == NULL)
return;
qos->destination_order.kind = kind;
qos->present |= QP_DESTINATION_ORDER;
}
void dds_qset_writer_data_lifecycle (dds_qos_t * __restrict qos, bool autodispose)
{
if (qos != NULL)
{
qos->writer_data_lifecycle.autodispose_unregistered_instances = autodispose;
qos->present |= QP_PRISMTECH_WRITER_DATA_LIFECYCLE;
}
if (qos == NULL)
return;
qos->writer_data_lifecycle.autodispose_unregistered_instances = autodispose;
qos->present |= QP_PRISMTECH_WRITER_DATA_LIFECYCLE;
}
void dds_qset_reader_data_lifecycle (dds_qos_t * __restrict qos, dds_duration_t autopurge_nowriter_samples_delay, dds_duration_t autopurge_disposed_samples_delay)
{
if (qos != NULL)
{
qos->reader_data_lifecycle.autopurge_nowriter_samples_delay = autopurge_nowriter_samples_delay;
qos->reader_data_lifecycle.autopurge_disposed_samples_delay = autopurge_disposed_samples_delay;
qos->present |= QP_PRISMTECH_READER_DATA_LIFECYCLE;
}
if (qos == NULL)
return;
qos->reader_data_lifecycle.autopurge_nowriter_samples_delay = autopurge_nowriter_samples_delay;
qos->reader_data_lifecycle.autopurge_disposed_samples_delay = autopurge_disposed_samples_delay;
qos->present |= QP_PRISMTECH_READER_DATA_LIFECYCLE;
}
void dds_qset_durability_service (dds_qos_t * __restrict qos, dds_duration_t service_cleanup_delay, dds_history_kind_t history_kind, int32_t history_depth, int32_t max_samples, int32_t max_instances, int32_t max_samples_per_instance)
{
if (qos != NULL)
{
qos->durability_service.service_cleanup_delay = service_cleanup_delay;
qos->durability_service.history.kind = history_kind;
qos->durability_service.history.depth = history_depth;
qos->durability_service.resource_limits.max_samples = max_samples;
qos->durability_service.resource_limits.max_instances = max_instances;
qos->durability_service.resource_limits.max_samples_per_instance = max_samples_per_instance;
qos->present |= QP_DURABILITY_SERVICE;
}
if (qos == NULL)
return;
qos->durability_service.service_cleanup_delay = service_cleanup_delay;
qos->durability_service.history.kind = history_kind;
qos->durability_service.history.depth = history_depth;
qos->durability_service.resource_limits.max_samples = max_samples;
qos->durability_service.resource_limits.max_instances = max_instances;
qos->durability_service.resource_limits.max_samples_per_instance = max_samples_per_instance;
qos->present |= QP_DURABILITY_SERVICE;
}
void dds_qset_ignorelocal (dds_qos_t * __restrict qos, dds_ignorelocal_kind_t ignore)
{
if (qos != NULL)
{
qos->ignorelocal.value = ignore;
qos->present |= QP_CYCLONE_IGNORELOCAL;
}
if (qos == NULL)
return;
qos->ignorelocal.value = ignore;
qos->present |= QP_CYCLONE_IGNORELOCAL;
}
bool dds_qget_userdata (const dds_qos_t * __restrict qos, void **value, size_t *sz)

View file

@ -81,18 +81,9 @@ static dds_return_t dds_reader_qos_validate (const dds_qos_t *qos, bool enabled)
static dds_return_t dds_reader_qos_validate (const dds_qos_t *qos, bool enabled)
{
if (!dds_qos_validate_common (qos))
return DDS_RETCODE_ERROR;
if ((qos->present & QP_USER_DATA) && !validate_octetseq (&qos->user_data))
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_PRISMTECH_READER_DATA_LIFECYCLE) && validate_reader_data_lifecycle (&qos->reader_data_lifecycle) < 0)
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_TIME_BASED_FILTER) && validate_duration (qos->time_based_filter.minimum_separation) < 0)
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_HISTORY) && (qos->present & QP_RESOURCE_LIMITS) && validate_history_and_resource_limits (&qos->history, &qos->resource_limits) < 0)
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_TIME_BASED_FILTER) && (qos->present & QP_DEADLINE) && !validate_deadline_and_timebased_filter (qos->deadline.deadline, qos->time_based_filter.minimum_separation))
return DDS_RETCODE_INCONSISTENT_POLICY;
dds_return_t ret;
if ((ret = nn_xqos_valid (qos)) < 0)
return ret;
return (enabled ? dds_qos_validate_mutable_common (qos) : DDS_RETCODE_OK);
}
@ -372,20 +363,15 @@ dds_entity_t dds_create_reader (dds_entity_t participant_or_subscriber, dds_enti
/* Merge qos from topic and subscriber, dds_copy_qos only fails when it is passed a null
argument, but that isn't the case here */
#define DDS_QOSMASK_READER (QP_USER_DATA | QP_DURABILITY | QP_DEADLINE | QP_LATENCY_BUDGET | QP_OWNERSHIP | QP_LIVELINESS | QP_TIME_BASED_FILTER | QP_RELIABILITY | QP_DESTINATION_ORDER | QP_HISTORY | QP_RESOURCE_LIMITS | QP_PRISMTECH_READER_DATA_LIFECYCLE | QP_CYCLONE_IGNORELOCAL)
rqos = dds_create_qos ();
if (qos)
(void) dds_copy_qos (rqos, qos);
nn_xqos_mergein_missing (rqos, qos, DDS_QOSMASK_READER);
if (sub->m_entity.m_qos)
dds_merge_qos (rqos, sub->m_entity.m_qos);
nn_xqos_mergein_missing (rqos, sub->m_entity.m_qos, ~(uint64_t)0);
if (tp->m_entity.m_qos)
{
dds_merge_qos (rqos, tp->m_entity.m_qos);
/* reset the following qos policies if set during topic qos merge as they aren't applicable for reader */
rqos->present &= ~(QP_DURABILITY_SERVICE | QP_TRANSPORT_PRIORITY | QP_LIFESPAN);
}
nn_xqos_mergein_missing (rqos, &gv.default_xqos_rd);
nn_xqos_mergein_missing (rqos, tp->m_entity.m_qos, ~(uint64_t)0);
nn_xqos_mergein_missing (rqos, &gv.default_xqos_rd, ~(uint64_t)0);
if ((ret = dds_reader_qos_validate (rqos, false)) != DDS_RETCODE_OK)
{
@ -397,7 +383,7 @@ dds_entity_t dds_create_reader (dds_entity_t participant_or_subscriber, dds_enti
/* Additional checks required for built-in topics: we don't want to
run into a resource limit on a built-in topic, it is a needless
complication */
if (internal_topic && !dds__validate_builtin_reader_qos (topic, qos))
if (internal_topic && !dds__validate_builtin_reader_qos (topic, rqos))
{
dds_delete_qos (rqos);
reader = DDS_RETCODE_INCONSISTENT_POLICY;

View file

@ -19,6 +19,7 @@
#include "dds/ddsi/q_bswap.h"
#include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_freelist.h"
#include "dds/ddsi/q_plist.h"
#include "dds__stream.h"
#include "dds__serdata_builtintopic.h"
#include "dds/ddsi/ddsi_tkmap.h"
@ -193,7 +194,7 @@ static dds_qos_t *dds_qos_from_xqos_reuse (dds_qos_t *old, const dds_qos_t *src)
old = ddsrt_malloc (sizeof (*old));
nn_xqos_init_empty (old);
old->present |= QP_TOPIC_NAME | QP_TYPE_NAME;
nn_xqos_mergein_missing (old, src);
nn_xqos_mergein_missing (old, src, ~(uint64_t)0);
old->present &= ~(QP_TOPIC_NAME | QP_TYPE_NAME);
}
else
@ -201,7 +202,7 @@ static dds_qos_t *dds_qos_from_xqos_reuse (dds_qos_t *old, const dds_qos_t *src)
nn_xqos_fini (old);
nn_xqos_init_empty (old);
old->present |= QP_TOPIC_NAME | QP_TYPE_NAME;
nn_xqos_mergein_missing (old, src);
nn_xqos_mergein_missing (old, src, ~(uint64_t)0);
old->present &= ~(QP_TOPIC_NAME | QP_TYPE_NAME);
}
return old;

View file

@ -15,6 +15,7 @@
#include "dds__qos.h"
#include "dds__subscriber.h"
#include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_globals.h"
#include "dds/version.h"
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_subscriber)
@ -36,15 +37,9 @@ static dds_return_t dds__subscriber_qos_validate (const dds_qos_t *qos, bool ena
static dds_return_t dds__subscriber_qos_validate (const dds_qos_t *qos, bool enabled)
{
if ((qos->present & QP_GROUP_DATA) && !validate_octetseq (&qos->group_data))
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_PARTITION) && !validate_stringseq (&qos->partition))
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_PRESENTATION) && validate_presentation_qospolicy (&qos->presentation) < 0)
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy (&qos->entity_factory))
return DDS_RETCODE_INCONSISTENT_POLICY;
/* FIXME: Improve/check immutable check. */
dds_return_t ret;
if ((ret = nn_xqos_valid (qos)) < 0)
return ret;
return (enabled && (qos->present & QP_PRESENTATION)) ? DDS_RETCODE_IMMUTABLE_POLICY : DDS_RETCODE_OK;
}
@ -73,16 +68,15 @@ dds_entity_t dds__create_subscriber_l (dds_participant *participant, const dds_q
dds_return_t ret;
dds_qos_t *new_qos;
/* Validate qos */
if (qos && (ret = dds__subscriber_qos_validate (qos, false)) != DDS_RETCODE_OK)
return ret;
if (qos == NULL)
new_qos = NULL;
else
#define DDS_QOSMASK_SUBSCRIBER (QP_PARTITION | QP_PRESENTATION | QP_GROUP_DATA | QP_PRISMTECH_ENTITY_FACTORY | QP_CYCLONE_IGNORELOCAL)
new_qos = dds_create_qos ();
if (qos)
nn_xqos_mergein_missing (new_qos, qos, DDS_QOSMASK_SUBSCRIBER);
nn_xqos_mergein_missing (new_qos, &gv.default_xqos_sub, ~(uint64_t)0);
if ((ret = dds__subscriber_qos_validate (new_qos, false)) != DDS_RETCODE_OK)
{
new_qos = dds_create_qos ();
(void) dds_copy_qos (new_qos, qos);
dds_delete_qos (new_qos);
return ret;
}
sub = dds_alloc (sizeof (*sub));

View file

@ -14,6 +14,8 @@
#include <ctype.h>
#include "dds/ddsrt/atomics.h"
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/string.h"
#include "dds__topic.h"
#include "dds__listener.h"
#include "dds__qos.h"
@ -27,6 +29,8 @@
#include "dds/ddsi/ddsi_sertopic.h"
#include "dds/ddsi/q_ddsi_discovery.h"
#include "dds/ddsi/ddsi_iid.h"
#include "dds/ddsi/q_plist.h"
#include "dds/ddsi/q_globals.h"
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_topic)
@ -182,17 +186,10 @@ static dds_return_t dds_topic_qos_validate (const dds_qos_t *qos, bool enabled)
static dds_return_t dds_topic_qos_validate (const dds_qos_t *qos, bool enabled)
{
if (!dds_qos_validate_common (qos))
return DDS_RETCODE_BAD_PARAMETER;
if ((qos->present & QP_GROUP_DATA) && !validate_octetseq (&qos->group_data))
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_DURABILITY_SERVICE) && validate_durability_service_qospolicy(&qos->durability_service) < 0)
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_LIFESPAN) && validate_duration(qos->lifespan.duration) < 0)
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_HISTORY) && (qos->present & QP_RESOURCE_LIMITS) && validate_history_and_resource_limits(&qos->history, &qos->resource_limits) < 0)
return DDS_RETCODE_INCONSISTENT_POLICY;
return enabled ? dds_qos_validate_mutable_common(qos) : DDS_RETCODE_OK;
dds_return_t ret;
if ((ret = nn_xqos_valid (qos)) < 0)
return ret;
return enabled ? dds_qos_validate_mutable_common (qos) : DDS_RETCODE_OK;
}
@ -333,8 +330,8 @@ dds_entity_t dds_create_topic (dds_entity_t participant, const dds_topic_descrip
st->c.status_cb = dds_topic_status_cb;
st->c.status_cb_entity = NULL; /* set by dds_create_topic_arbitrary */
st->c.name_type_name = key;
st->c.name = dds_string_dup (name);
st->c.type_name = dds_string_dup (typename);
st->c.name = ddsrt_strdup (name);
st->c.type_name = ddsrt_strdup (typename);
st->c.ops = &ddsi_sertopic_ops_default;
st->c.serdata_ops = desc->m_nkeys ? &ddsi_serdata_ops_cdr : &ddsi_serdata_ops_cdr_nokey;
st->c.serdata_basehash = ddsi_sertopic_compute_serdata_basehash (st->c.serdata_ops);
@ -349,13 +346,15 @@ dds_entity_t dds_create_topic (dds_entity_t participant, const dds_topic_descrip
st->opt_size = dds_stream_check_optimize (desc);
}
#define DDS_QOSMASK_TOPIC (QP_TOPIC_DATA | QP_DURABILITY | QP_DURABILITY_SERVICE | QP_DEADLINE | QP_LATENCY_BUDGET | QP_OWNERSHIP | QP_LIVELINESS | QP_RELIABILITY | QP_TRANSPORT_PRIORITY | QP_LIFESPAN | QP_DESTINATION_ORDER | QP_HISTORY | QP_RESOURCE_LIMITS)
nn_plist_init_empty (&plist);
if (new_qos)
dds_merge_qos (&plist.qos, new_qos);
nn_xqos_mergein_missing (&plist.qos, new_qos, DDS_QOSMASK_TOPIC);
nn_xqos_mergein_missing (&plist.qos, &gv.default_xqos_tp, DDS_QOSMASK_TOPIC);
/* Set Topic meta data (for SEDP publication) */
plist.qos.topic_name = dds_string_dup (st->c.name);
plist.qos.type_name = dds_string_dup (st->c.type_name);
plist.qos.topic_name = ddsrt_strdup (st->c.name);
plist.qos.type_name = ddsrt_strdup (st->c.type_name);
plist.qos.present |= (QP_TOPIC_NAME | QP_TYPE_NAME);
if (desc->m_meta)
{

View file

@ -208,16 +208,9 @@ static dds_return_t dds_writer_delete (dds_entity *e)
static dds_return_t dds_writer_qos_validate (const dds_qos_t *qos, bool enabled)
{
if (!dds_qos_validate_common(qos))
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_USER_DATA) && !validate_octetseq (&qos->user_data))
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_DURABILITY_SERVICE) && validate_durability_service_qospolicy (&qos->durability_service) < 0)
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_LIFESPAN) && validate_duration (qos->lifespan.duration) < 0)
return DDS_RETCODE_INCONSISTENT_POLICY;
if ((qos->present & QP_HISTORY) && (qos->present & QP_RESOURCE_LIMITS) && validate_history_and_resource_limits(&qos->history, &qos->resource_limits) < 0)
return DDS_RETCODE_INCONSISTENT_POLICY;
dds_return_t ret;
if ((ret = nn_xqos_valid (qos)) < 0)
return ret;
return enabled ? dds_qos_validate_mutable_common (qos) : DDS_RETCODE_OK;
}
@ -316,14 +309,15 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
assert (pub->m_entity.m_domain == tp->m_entity.m_domain);
/* Merge Topic & Publisher qos */
#define DDS_QOSMASK_WRITER (QP_USER_DATA | QP_DURABILITY | QP_DURABILITY_SERVICE | QP_DEADLINE | QP_LATENCY_BUDGET | QP_OWNERSHIP | QP_OWNERSHIP_STRENGTH | QP_LIVELINESS | QP_RELIABILITY | QP_TRANSPORT_PRIORITY | QP_LIFESPAN | QP_DESTINATION_ORDER | QP_HISTORY | QP_RESOURCE_LIMITS | QP_PRISMTECH_WRITER_DATA_LIFECYCLE | QP_CYCLONE_IGNORELOCAL)
wqos = dds_create_qos ();
if (qos)
(void) dds_copy_qos (wqos, qos);
nn_xqos_mergein_missing (wqos, qos, DDS_QOSMASK_WRITER);
if (pub->m_entity.m_qos)
dds_merge_qos (wqos, pub->m_entity.m_qos);
nn_xqos_mergein_missing (wqos, pub->m_entity.m_qos, ~(uint64_t)0);
if (tp->m_entity.m_qos)
dds_merge_qos (wqos, tp->m_entity.m_qos);
nn_xqos_mergein_missing (wqos, &gv.default_xqos_wr);
nn_xqos_mergein_missing (wqos, tp->m_entity.m_qos, ~(uint64_t)0);
nn_xqos_mergein_missing (wqos, &gv.default_xqos_wr, ~(uint64_t)0);
if ((rc = dds_writer_qos_validate (wqos, false)) != DDS_RETCODE_OK)
{

View file

@ -241,7 +241,7 @@ CU_Test(ddsc_reader_create, invalid_qos_participant, .init=reader_init, .fini=re
dds_qset_reader_data_lifecycle(qos, DDS_SECS(-1), DDS_SECS(-1));
DDSRT_WARNING_MSVC_ON(28020);
rdr = dds_create_reader(g_participant, g_topic, qos, NULL);
CU_ASSERT_EQUAL_FATAL(rdr, DDS_RETCODE_INCONSISTENT_POLICY);
CU_ASSERT_EQUAL_FATAL(rdr, DDS_RETCODE_BAD_PARAMETER);
dds_delete_qos(qos);
}
/*************************************************************************************************/
@ -256,7 +256,7 @@ CU_Test(ddsc_reader_create, invalid_qos_subscriber, .init=reader_init, .fini=rea
dds_qset_reader_data_lifecycle(qos, DDS_SECS(-1), DDS_SECS(-1));
DDSRT_WARNING_MSVC_ON(28020);
rdr = dds_create_reader(g_subscriber, g_topic, qos, NULL);
CU_ASSERT_EQUAL_FATAL(rdr, DDS_RETCODE_INCONSISTENT_POLICY);
CU_ASSERT_EQUAL_FATAL(rdr, DDS_RETCODE_BAD_PARAMETER);
dds_delete_qos(qos);
}
/*************************************************************************************************/

View file

@ -91,7 +91,7 @@ CU_Test(ddsc_subscriber, create) {
sqos = dds_create_qos();
dds_qset_presentation(sqos, 123, 1, 1); /* Set invalid presentation policy */
subscriber = dds_create_subscriber(participant, sqos, NULL);
CU_ASSERT_EQUAL_FATAL(subscriber, DDS_RETCODE_INCONSISTENT_POLICY);
CU_ASSERT_EQUAL_FATAL(subscriber, DDS_RETCODE_BAD_PARAMETER);
dds_delete_qos(sqos);
/*** Verify listener parameter ***/

View file

@ -105,7 +105,7 @@ CU_Test(ddsc_topic_create, invalid_qos, .init=ddsc_topic_init, .fini=ddsc_topic_
dds_entity_t topic;
dds_qos_t *qos = dds_create_qos();
DDSRT_WARNING_MSVC_OFF(28020); /* Disable SAL warning on intentional misuse of the API */
dds_qset_lifespan(qos, DDS_SECS(-1));
dds_qset_resource_limits(qos, 1, 1, 2);
DDSRT_WARNING_MSVC_OFF(28020);
topic = dds_create_topic(g_participant, &RoundTripModule_DataType_desc, "inconsistent", qos, NULL);
CU_ASSERT_EQUAL_FATAL(topic, DDS_RETCODE_INCONSISTENT_POLICY);
@ -417,7 +417,7 @@ CU_Test(ddsc_topic_set_qos, inconsistent, .init=ddsc_topic_init, .fini=ddsc_topi
dds_qset_lifespan(g_qos, DDS_SECS(-1));
DDSRT_WARNING_MSVC_ON(28020);
ret = dds_set_qos(g_topicRtmDataType, g_qos);
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_INCONSISTENT_POLICY);
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_BAD_PARAMETER);
}
/*************************************************************************************************/

View file

@ -13,7 +13,7 @@
#define DDSI_SERDATA_DEFAULT_H
#include "dds/ddsrt/endian.h"
#include "dds/ddsi/q_plist.h" /* for nn_prismtech_writer_info */
#include "dds/ddsi/q_protocol.h" /* for nn_parameterid_t */
#include "dds/ddsi/q_freelist.h"
#include "dds/ddsrt/avl.h"
#include "dds/ddsi/ddsi_serdata.h"

View file

@ -46,22 +46,16 @@ extern "C" {
#define PP_STATUSINFO ((uint64_t)1 << 22)
#define PP_ORIGINAL_WRITER_INFO ((uint64_t)1 << 23)
#define PP_ENDPOINT_GUID ((uint64_t)1 << 24)
#define PP_PRISMTECH_WRITER_INFO ((uint64_t)1 << 25)
#define PP_PRISMTECH_PARTICIPANT_VERSION_INFO ((uint64_t)1 << 26)
#define PP_PRISMTECH_NODE_NAME ((uint64_t)1 << 27)
#define PP_PRISMTECH_EXEC_NAME ((uint64_t)1 << 28)
#define PP_PRISMTECH_PROCESS_ID ((uint64_t)1 << 29)
#define PP_PRISMTECH_SERVICE_TYPE ((uint64_t)1 << 30)
#define PP_PRISMTECH_WATCHDOG_SCHEDULING ((uint64_t)1 << 31)
#define PP_PRISMTECH_LISTENER_SCHEDULING ((uint64_t)1 << 32)
#define PP_PRISMTECH_BUILTIN_ENDPOINT_SET ((uint64_t)1 << 33)
#define PP_PRISMTECH_TYPE_DESCRIPTION ((uint64_t)1 << 34)
#define PP_COHERENT_SET ((uint64_t)1 << 37)
#define PP_PRISMTECH_EOTINFO ((uint64_t)1 << 38)
#ifdef DDSI_INCLUDE_SSM
#define PP_READER_FAVOURS_SSM ((uint64_t)1 << 39)
#endif
#define PP_RTI_TYPECODE ((uint64_t)1 << 40)
/* Security extensions. */
#define PP_IDENTITY_TOKEN ((uint64_t)1 << 41)
#define PP_PERMISSIONS_TOKEN ((uint64_t)1 << 42)
@ -93,14 +87,14 @@ struct nn_locators_one {
};
typedef struct nn_locators {
int n;
uint32_t n;
struct nn_locators_one *first;
struct nn_locators_one *last;
} nn_locators_t;
typedef unsigned nn_ipv4address_t;
typedef uint32_t nn_ipv4address_t;
typedef unsigned nn_port_t;
typedef uint32_t nn_port_t;
typedef struct nn_keyhash {
unsigned char value[16];
@ -109,15 +103,15 @@ typedef struct nn_keyhash {
#ifdef DDSI_INCLUDE_SSM
typedef struct nn_reader_favours_ssm {
unsigned state; /* default is false */
uint32_t state; /* default is false */
} nn_reader_favours_ssm_t;
#endif
typedef struct nn_prismtech_participant_version_info
{
unsigned version;
unsigned flags;
unsigned unused[3];
uint32_t version;
uint32_t flags;
uint32_t unused[3];
char *internals;
} nn_prismtech_participant_version_info_t;
@ -126,16 +120,9 @@ typedef struct nn_prismtech_eotgroup_tid {
uint32_t transactionId;
} nn_prismtech_eotgroup_tid_t;
typedef struct nn_prismtech_eotinfo {
uint32_t transactionId;
uint32_t n;
nn_prismtech_eotgroup_tid_t *tids;
} nn_prismtech_eotinfo_t;
typedef struct nn_plist {
uint64_t present;
uint64_t aliased;
int unalias_needs_bswap;
dds_qos_t qos;
@ -150,7 +137,7 @@ typedef struct nn_plist {
unsigned char expects_inline_qos;
nn_count_t participant_manual_liveliness_count;
unsigned participant_builtin_endpoints;
uint32_t participant_builtin_endpoints;
dds_duration_t participant_lease_duration;
/* nn_content_filter_property_t content_filter_property; */
nn_guid_t participant_guid;
@ -160,21 +147,18 @@ typedef struct nn_plist {
nn_entityid_t participant_entityid;
nn_entityid_t group_entityid;
#endif
unsigned builtin_endpoint_set;
unsigned prismtech_builtin_endpoint_set;
uint32_t builtin_endpoint_set;
uint32_t prismtech_builtin_endpoint_set;
/* int type_max_size_serialized; */
char *entity_name;
nn_keyhash_t keyhash;
unsigned statusinfo;
uint32_t statusinfo;
nn_prismtech_participant_version_info_t prismtech_participant_version_info;
char *node_name;
char *exec_name;
unsigned char is_service;
unsigned service_type;
unsigned process_id;
uint32_t process_id;
char *type_description;
nn_sequence_number_t coherent_set_seqno;
nn_prismtech_eotinfo_t eotinfo;
#ifdef DDSI_INCLUDE_SSM
nn_reader_favours_ssm_t reader_favours_ssm;
#endif
@ -192,8 +176,9 @@ typedef struct nn_plist_src {
size_t bufsz;
} nn_plist_src_t;
void nn_plist_init_tables (void);
DDS_EXPORT void nn_plist_init_empty (nn_plist_t *dest);
DDS_EXPORT void nn_plist_mergein_missing (nn_plist_t *a, const nn_plist_t *b);
DDS_EXPORT void nn_plist_mergein_missing (nn_plist_t *a, const nn_plist_t *b, uint64_t pmask, uint64_t qmask);
DDS_EXPORT void nn_plist_copy (nn_plist_t *dst, const nn_plist_t *src);
DDS_EXPORT nn_plist_t *nn_plist_dup (const nn_plist_t *src);
@ -234,6 +219,9 @@ DDS_EXPORT nn_plist_t *nn_plist_dup (const nn_plist_t *src);
* @retval DDS_RETCODE_OK
* All parameters valid (or ignored), dest and *nextafterplist have been set
* accordingly.
* @retval DDS_INCONSISTENT_POLICY
* All individual settings are valid, but there are inconsistencies between
* dependent settings.
* @retval DDS_RETCODE_BAD_PARAMETER
* Input contained invalid data; dest is cleared, *nextafterplist is NULL.
* @retval DDS_RETCODE_UNSUPPORTED
@ -245,20 +233,6 @@ DDS_EXPORT void nn_plist_fini (nn_plist_t *ps);
DDS_EXPORT void nn_plist_addtomsg (struct nn_xmsg *m, const nn_plist_t *ps, uint64_t pwanted, uint64_t qwanted);
DDS_EXPORT void nn_plist_init_default_participant (nn_plist_t *plist);
DDS_EXPORT dds_return_t validate_history_qospolicy (const dds_history_qospolicy_t *q);
DDS_EXPORT dds_return_t validate_durability_qospolicy (const dds_durability_qospolicy_t *q);
DDS_EXPORT dds_return_t validate_resource_limits_qospolicy (const dds_resource_limits_qospolicy_t *q);
DDS_EXPORT dds_return_t validate_history_and_resource_limits (const dds_history_qospolicy_t *qh, const dds_resource_limits_qospolicy_t *qr);
DDS_EXPORT dds_return_t validate_durability_service_qospolicy (const dds_durability_service_qospolicy_t *q);
DDS_EXPORT dds_return_t validate_liveliness_qospolicy (const dds_liveliness_qospolicy_t *q);
DDS_EXPORT dds_return_t validate_destination_order_qospolicy (const dds_destination_order_qospolicy_t *q);
DDS_EXPORT dds_return_t validate_ownership_qospolicy (const dds_ownership_qospolicy_t *q);
DDS_EXPORT dds_return_t validate_ownership_strength_qospolicy (const dds_ownership_strength_qospolicy_t *q);
DDS_EXPORT dds_return_t validate_presentation_qospolicy (const dds_presentation_qospolicy_t *q);
DDS_EXPORT dds_return_t validate_transport_priority_qospolicy (const dds_transport_priority_qospolicy_t *q);
DDS_EXPORT dds_return_t validate_reader_data_lifecycle (const dds_reader_data_lifecycle_qospolicy_t *q);
DDS_EXPORT dds_return_t validate_duration (const dds_duration_t d);
struct nn_rmsg;
struct nn_rsample_info;
struct nn_rdata;

View file

@ -390,14 +390,6 @@ typedef struct ParticipantMessageData {
#define PID_IDENTITY_TOKEN 0x1001u
#define PID_PERMISSIONS_TOKEN 0x1002u
#define PID_RTI_TYPECODE (PID_VENDORSPECIFIC_FLAG | 0x4u)
#ifdef DDSI_INCLUDE_SSM
/* To indicate whether a reader favours the use of SSM. Iff the
reader favours SSM, it will use SSM if available. */
#define PID_READER_FAVOURS_SSM 0x72u
#endif
#ifdef DDSI_INCLUDE_SSM
/* To indicate whether a reader favours the use of SSM. Iff the
reader favours SSM, it will use SSM if available. */

View file

@ -20,8 +20,14 @@ struct dds_qos;
int partitions_match_p (const struct dds_qos *a, const struct dds_qos *b);
/* Returns -1 on success, or QoS id of first mismatch (>=0) */
/* perform reader/writer QoS (and topic name, type name, partition) matching;
mask can be used to exclude some of these (including topic name and type
name, so be careful!)
reason will be set to the policy id of one of the mismatching QoS, or to
DDS_INVALID_QOS_POLICY_ID if there is no mismatch or if the mismatch is
in topic or type name (those are not really QoS and don't have a policy id) */
bool qos_match_mask_p (const dds_qos_t *rd, const dds_qos_t *wr, uint64_t mask, dds_qos_policy_id_t *reason) ddsrt_nonnull_all;
bool qos_match_p (const struct dds_qos *rd, const struct dds_qos *wr, dds_qos_policy_id_t *reason) ddsrt_nonnull ((1, 2));
#if defined (__cplusplus)

View file

@ -28,8 +28,6 @@ struct proxy_reader;
struct proxy_writer;
struct nn_prismtech_participant_version_info;
struct nn_prismtech_writer_info;
struct nn_prismtech_eotinfo;
struct nn_xmsgpool;
struct nn_xmsg_data;
struct nn_xmsg;
@ -139,7 +137,6 @@ void nn_xmsg_addpar_reader_data_lifecycle (struct nn_xmsg *m, nn_parameterid_t p
void nn_xmsg_addpar_liveliness (struct nn_xmsg *m, nn_parameterid_t pid, const dds_liveliness_qospolicy_t *rq);
void nn_xmsg_addpar_parvinfo (struct nn_xmsg *m, nn_parameterid_t pid, const struct nn_prismtech_participant_version_info *pvi);
void nn_xmsg_addpar_eotinfo (struct nn_xmsg *m, nn_parameterid_t pid, const struct nn_prismtech_eotinfo *txnid);
void nn_xmsg_addpar_sentinel (struct nn_xmsg *m);
int nn_xmsg_addpar_sentinel_ifparam (struct nn_xmsg *m);

View file

@ -211,7 +211,6 @@ typedef struct dds_ignorelocal_qospolicy {
#define QP_PRISMTECH_READER_LIFESPAN ((uint64_t)1 << 24)
#define QP_PRISMTECH_SUBSCRIPTION_KEYS ((uint64_t)1 << 25)
#define QP_PRISMTECH_ENTITY_FACTORY ((uint64_t)1 << 27)
#define QP_RTI_TYPECODE ((uint64_t)1 << 29)
#define QP_CYCLONE_IGNORELOCAL ((uint64_t)1 << 30)
/* Partition QoS is not RxO according to the specification (DDS 1.2,
@ -264,8 +263,6 @@ struct dds_qos {
/*x xR*/dds_subscription_keys_qospolicy_t subscription_keys;
/*x xR*/dds_reader_lifespan_qospolicy_t reader_lifespan;
/* x */dds_ignorelocal_qospolicy_t ignorelocal;
/* X*/ddsi_octetseq_t rti_typecode;
};
struct nn_xmsg;
@ -280,7 +277,8 @@ DDS_EXPORT void nn_xqos_init_default_topic (dds_qos_t *xqos);
DDS_EXPORT void nn_xqos_copy (dds_qos_t *dst, const dds_qos_t *src);
DDS_EXPORT void nn_xqos_unalias (dds_qos_t *xqos);
DDS_EXPORT void nn_xqos_fini (dds_qos_t *xqos);
DDS_EXPORT void nn_xqos_mergein_missing (dds_qos_t *a, const dds_qos_t *b);
DDS_EXPORT dds_return_t nn_xqos_valid (const dds_qos_t *xqos);
DDS_EXPORT void nn_xqos_mergein_missing (dds_qos_t *a, const dds_qos_t *b, uint64_t mask);
DDS_EXPORT uint64_t nn_xqos_delta (const dds_qos_t *a, const dds_qos_t *b, uint64_t mask);
DDS_EXPORT void nn_xqos_addtomsg (struct nn_xmsg *m, const dds_qos_t *xqos, uint64_t wanted);
DDS_EXPORT void nn_log_xqos (uint32_t cat, const dds_qos_t *xqos);

View file

@ -1085,7 +1085,7 @@ static struct proxy_participant *implicitly_create_proxypp (const nn_guid_t *ppg
tmp_plist = *privpp->plist;
tmp_plist.present = PP_PARTICIPANT_GUID | PP_PRISMTECH_PARTICIPANT_VERSION_INFO;
tmp_plist.participant_guid = *ppguid;
nn_plist_mergein_missing (&pp_plist, &tmp_plist);
nn_plist_mergein_missing (&pp_plist, &tmp_plist, ~(uint64_t)0, ~(uint64_t)0);
ddsrt_mutex_unlock (&privpp->e.lock);
pp_plist.prismtech_participant_version_info.flags &= ~NN_PRISMTECH_FL_PARTICIPANT_IS_DDSI2;
@ -1146,11 +1146,11 @@ static void handle_SEDP_alive (const struct receiver_state *rst, nn_plist_t *dat
xqos = &datap->qos;
is_writer = is_writer_entityid (datap->endpoint_guid.entityid);
if (!is_writer)
nn_xqos_mergein_missing (xqos, &gv.default_xqos_rd);
nn_xqos_mergein_missing (xqos, &gv.default_xqos_rd, ~(uint64_t)0);
else if (vendor_is_eclipse_or_prismtech(vendorid))
nn_xqos_mergein_missing (xqos, &gv.default_xqos_wr);
nn_xqos_mergein_missing (xqos, &gv.default_xqos_wr, ~(uint64_t)0);
else
nn_xqos_mergein_missing (xqos, &gv.default_xqos_wr_nad);
nn_xqos_mergein_missing (xqos, &gv.default_xqos_wr_nad, ~(uint64_t)0);
/* After copy + merge, should have at least the ones present in the
input. Also verify reliability and durability are present,
@ -1434,8 +1434,7 @@ int sedp_write_cm_participant (struct participant *pp, int alive)
{
nn_plist_addtomsg (mpayload, pp->plist,
PP_PRISMTECH_NODE_NAME | PP_PRISMTECH_EXEC_NAME | PP_PRISMTECH_PROCESS_ID |
PP_PRISMTECH_WATCHDOG_SCHEDULING | PP_PRISMTECH_LISTENER_SCHEDULING |
PP_PRISMTECH_SERVICE_TYPE | PP_ENTITY_NAME,
PP_ENTITY_NAME,
QP_PRISMTECH_ENTITY_FACTORY);
}
nn_xmsg_addpar_sentinel (mpayload);

View file

@ -457,7 +457,7 @@ dds_return_t new_participant_guid (const nn_guid_t *ppguid, unsigned flags, cons
pp->lease_duration = config.lease_duration;
pp->plist = ddsrt_malloc (sizeof (*pp->plist));
nn_plist_copy (pp->plist, plist);
nn_plist_mergein_missing (pp->plist, &gv.default_plist_pp);
nn_plist_mergein_missing (pp->plist, &gv.default_plist_pp, ~(uint64_t)0, ~(uint64_t)0);
if (dds_get_log_mask() & DDS_LC_DISCOVERY)
{
@ -2684,7 +2684,7 @@ static void new_writer_guid_common_init (struct writer *wr, const struct ddsi_se
wr->xqos = ddsrt_malloc (sizeof (*wr->xqos));
nn_xqos_copy (wr->xqos, xqos);
nn_xqos_mergein_missing (wr->xqos, &gv.default_xqos_wr);
nn_xqos_mergein_missing (wr->xqos, &gv.default_xqos_wr, ~(uint64_t)0);
assert (wr->xqos->aliased == 0);
set_topic_type_name (wr->xqos, topic);
@ -3222,7 +3222,7 @@ static dds_return_t new_reader_guid
/* Copy QoS, merging in defaults */
rd->xqos = ddsrt_malloc (sizeof (*rd->xqos));
nn_xqos_copy (rd->xqos, xqos);
nn_xqos_mergein_missing (rd->xqos, &gv.default_xqos_rd);
nn_xqos_mergein_missing (rd->xqos, &gv.default_xqos_rd, ~(uint64_t)0);
assert (rd->xqos->aliased == 0);
set_topic_type_name (rd->xqos, topic);
@ -3660,7 +3660,7 @@ int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, co
nn_plist_t *new_plist;
new_plist = nn_plist_dup (datap);
nn_plist_mergein_missing (new_plist, proxypp->plist);
nn_plist_mergein_missing (new_plist, proxypp->plist, ~(uint64_t)0, ~(uint64_t)0);
nn_plist_fini (proxypp->plist);
ddsrt_free (proxypp->plist);
proxypp->plist = new_plist;
@ -3694,8 +3694,7 @@ int update_proxy_participant_plist (struct proxy_participant *proxypp, const str
tmp = *datap;
tmp.present &=
PP_PRISMTECH_NODE_NAME | PP_PRISMTECH_EXEC_NAME | PP_PRISMTECH_PROCESS_ID |
PP_PRISMTECH_WATCHDOG_SCHEDULING | PP_PRISMTECH_LISTENER_SCHEDULING |
PP_PRISMTECH_SERVICE_TYPE | PP_ENTITY_NAME;
PP_ENTITY_NAME;
tmp.qos.present &= QP_PRISMTECH_ENTITY_FACTORY;
update_proxy_participant_plist_locked (proxypp, &tmp, source, timestamp);
break;
@ -3993,7 +3992,7 @@ int new_proxy_group (const struct nn_guid *guid, const char *name, const struct
DDS_LOG(DDS_LC_DISCOVERY, "new_proxy_group("PGUIDFMT"): setting name (%s) and qos\n", PGUID (*guid), name);
pgroup->name = ddsrt_strdup (name);
pgroup->xqos = nn_xqos_dup (xqos);
nn_xqos_mergein_missing (pgroup->xqos, is_sub ? &gv.default_xqos_sub : &gv.default_xqos_pub);
nn_xqos_mergein_missing (pgroup->xqos, is_sub ? &gv.default_xqos_sub : &gv.default_xqos_pub, ~(uint64_t)0);
}
out:
ddsrt_mutex_unlock (&proxypp->e.lock);

View file

@ -850,10 +850,11 @@ int rtps_init (void)
uint32_t port_data_uc = 0;
bool mc_available = true;
gv.tstart = now (); /* wall clock time, used in logs */
ddsi_plugin_init ();
ddsi_iid_init ();
gv.tstart = now (); /* wall clock time, used in logs */
nn_plist_init_tables ();
gv.disc_conn_uc = NULL;
gv.data_conn_uc = NULL;

File diff suppressed because it is too large Load diff

View file

@ -64,66 +64,65 @@ int partitions_match_p (const dds_qos_t *a, const dds_qos_t *b)
}
}
static bool qos_match_internal_p (const dds_qos_t *rd, const dds_qos_t *wr, dds_qos_policy_id_t *reason) ddsrt_nonnull_all;
static bool qos_match_internal_p (const dds_qos_t *rd, const dds_qos_t *wr, dds_qos_policy_id_t *reason)
bool qos_match_mask_p (const dds_qos_t *rd, const dds_qos_t *wr, uint64_t mask, dds_qos_policy_id_t *reason)
{
#ifndef NDEBUG
unsigned musthave = (QP_RXO_MASK | QP_PARTITION | QP_TOPIC_NAME | QP_TYPE_NAME);
unsigned musthave = (QP_RXO_MASK | QP_PARTITION | QP_TOPIC_NAME | QP_TYPE_NAME) & mask;
assert ((rd->present & musthave) == musthave);
assert ((wr->present & musthave) == musthave);
#endif
mask &= rd->present & wr->present;
*reason = DDS_INVALID_QOS_POLICY_ID;
if (strcmp (rd->topic_name, wr->topic_name) != 0)
if ((mask & QP_TOPIC_NAME) && strcmp (rd->topic_name, wr->topic_name) != 0)
return false;
if (strcmp (rd->type_name, wr->type_name) != 0)
if ((mask & QP_TYPE_NAME) && strcmp (rd->type_name, wr->type_name) != 0)
return false;
if (rd->reliability.kind > wr->reliability.kind) {
if ((mask & QP_RELIABILITY) && rd->reliability.kind > wr->reliability.kind) {
*reason = DDS_RELIABILITY_QOS_POLICY_ID;
return false;
}
if (rd->durability.kind > wr->durability.kind) {
if ((mask & QP_DURABILITY) && rd->durability.kind > wr->durability.kind) {
*reason = DDS_DURABILITY_QOS_POLICY_ID;
return false;
}
if (rd->presentation.access_scope > wr->presentation.access_scope) {
if ((mask & QP_PRESENTATION) && rd->presentation.access_scope > wr->presentation.access_scope) {
*reason = DDS_PRESENTATION_QOS_POLICY_ID;
return false;
}
if (rd->presentation.coherent_access > wr->presentation.coherent_access) {
if ((mask & QP_PRESENTATION) && rd->presentation.coherent_access > wr->presentation.coherent_access) {
*reason = DDS_PRESENTATION_QOS_POLICY_ID;
return false;
}
if (rd->presentation.ordered_access > wr->presentation.ordered_access) {
if ((mask & QP_PRESENTATION) && rd->presentation.ordered_access > wr->presentation.ordered_access) {
*reason = DDS_PRESENTATION_QOS_POLICY_ID;
return false;
}
if (rd->deadline.deadline < wr->deadline.deadline) {
if ((mask & QP_DEADLINE) && rd->deadline.deadline < wr->deadline.deadline) {
*reason = DDS_DEADLINE_QOS_POLICY_ID;
return false;
}
if (rd->latency_budget.duration < wr->latency_budget.duration) {
if ((mask & QP_LATENCY_BUDGET) && rd->latency_budget.duration < wr->latency_budget.duration) {
*reason = DDS_LATENCYBUDGET_QOS_POLICY_ID;
return false;
}
if (rd->ownership.kind != wr->ownership.kind) {
if ((mask & QP_OWNERSHIP) && rd->ownership.kind != wr->ownership.kind) {
*reason = DDS_OWNERSHIP_QOS_POLICY_ID;
return false;
}
if (rd->liveliness.kind > wr->liveliness.kind) {
if ((mask & QP_LIVELINESS) && rd->liveliness.kind > wr->liveliness.kind) {
*reason = DDS_LIVELINESS_QOS_POLICY_ID;
return false;
}
if (rd->liveliness.lease_duration < wr->liveliness.lease_duration) {
if ((mask & QP_LIVELINESS) && rd->liveliness.lease_duration < wr->liveliness.lease_duration) {
*reason = DDS_LIVELINESS_QOS_POLICY_ID;
return false;
}
if (rd->destination_order.kind > wr->destination_order.kind) {
if ((mask & QP_DESTINATION_ORDER) && rd->destination_order.kind > wr->destination_order.kind) {
*reason = DDS_DESTINATIONORDER_QOS_POLICY_ID;
return false;
}
if (!partitions_match_p (rd, wr)) {
if ((mask & QP_PARTITION) && !partitions_match_p (rd, wr)) {
*reason = DDS_PARTITION_QOS_POLICY_ID;
return false;
}
@ -133,5 +132,5 @@ static bool qos_match_internal_p (const dds_qos_t *rd, const dds_qos_t *wr, dds_
bool qos_match_p (const dds_qos_t *rd, const dds_qos_t *wr, dds_qos_policy_id_t *reason)
{
dds_qos_policy_id_t dummy;
return qos_match_internal_p (rd, wr, reason ? reason : &dummy);
return qos_match_mask_p (rd, wr, ~(uint64_t)0, reason ? reason : &dummy);
}

View file

@ -1952,7 +1952,7 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st
src.encoding = (msg->smhdr.flags & SMFLAG_ENDIANNESS) ? PL_CDR_LE : PL_CDR_BE;
src.buf = NN_RMSG_PAYLOADOFF (fragchain->rmsg, qos_offset);
src.bufsz = NN_RDATA_PAYLOAD_OFF (fragchain) - qos_offset;
if ((plist_ret = nn_plist_init_frommsg (&qos, NULL, PP_STATUSINFO | PP_KEYHASH | PP_COHERENT_SET | PP_PRISMTECH_EOTINFO, 0, &src)) < 0)
if ((plist_ret = nn_plist_init_frommsg (&qos, NULL, PP_STATUSINFO | PP_KEYHASH | PP_COHERENT_SET, 0, &src)) < 0)
{
if (plist_ret != DDS_RETCODE_UNSUPPORTED)
DDS_WARNING ("data(application, vendor %u.%u): "PGUIDFMT" #%"PRId64": invalid inline qos\n",
@ -1980,9 +1980,7 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st
}
/* Generate the DDS_SampleInfo (which is faked to some extent
because we don't actually have a data reader); also note that
the PRISMTECH_WRITER_INFO thing is completely meaningless to
us */
because we don't actually have a data reader) */
struct ddsi_tkmap_instance * tk;
if ((tk = ddsi_tkmap_lookup_instance_ref(payload)) != NULL)
{

View file

@ -1029,19 +1029,6 @@ void nn_xmsg_addpar_parvinfo (struct nn_xmsg *m, nn_parameterid_t pid, const str
memcpy(ps->contents, pvi->internals, slen);
}
void nn_xmsg_addpar_eotinfo (struct nn_xmsg *m, nn_parameterid_t pid, const struct nn_prismtech_eotinfo *txnid)
{
uint32_t *pu, i;
pu = nn_xmsg_addpar (m, pid, 2 * sizeof (uint32_t) + txnid->n * sizeof (txnid->tids[0]));
pu[0] = txnid->transactionId;
pu[1] = txnid->n;
for (i = 0; i < txnid->n; i++)
{
pu[2*i + 2] = toBE4u (txnid->tids[i].writer_entityid.u);
pu[2*i + 3] = txnid->tids[i].transactionId;
}
}
/* XMSG_CHAIN ----------------------------------------------------------
Xpacks refer to xmsgs and need to release these after having been

View file

@ -147,7 +147,7 @@ static struct proxy_writer *mkwr (bool auto_dispose)
wr_iid = ddsi_iid_gen ();
memset (pwr, 0, sizeof (*pwr));
nn_xqos_init_empty (xqos);
nn_xqos_mergein_missing (xqos, &gv.default_xqos_wr);
nn_xqos_mergein_missing (xqos, &gv.default_xqos_wr, ~(uint64_t)0);
xqos->ownership_strength.value = 0;
xqos->writer_data_lifecycle.autodispose_unregistered_instances = auto_dispose;
pwr->e.iid = wr_iid;
@ -170,7 +170,7 @@ static struct rhc *mkrhc (dds_reader *rd, dds_history_kind_t hk, int32_t hdepth,
rqos.history.kind = hk;
rqos.history.depth = hdepth;
rqos.destination_order.kind = dok;
nn_xqos_mergein_missing (&rqos, &gv.default_xqos_rd);
nn_xqos_mergein_missing (&rqos, &gv.default_xqos_rd, ~(uint64_t)0);
thread_state_awake (lookup_thread_state ());
rhc = dds_rhc_new (rd, mdtopic);
dds_rhc_set_qos(rhc, &rqos);

View file

@ -105,4 +105,10 @@
# define ddsrt_attribute_assume_aligned(params)
#endif
#if ddsrt_has_attribute(packed)
# define ddsrt_attribute_packed __attribute__ ((__packed__))
#else
# define ddsrt_attribute_packed
#endif
#endif /* DDSRT_ATTRIBUTES_H */

View file

@ -16,4 +16,4 @@ if(MPT_ENABLE_SELFTEST)
endif()
add_subdirectory(basic)
add_subdirectory(qosmatch)

View file

@ -0,0 +1,23 @@
#
# Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
# v. 1.0 which is available at
# http://www.eclipse.org/org/documents/edl-v10.php.
#
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#
include(${MPT_CMAKE})
set(sources
"procs/rw.c"
"qosmatch.c")
add_compile_options("-I${PROJECT_SOURCE_DIR}/core/ddsi/include")
add_mpt_executable(mpt_qosmatch ${sources})
idlc_generate(mpt_qosmatch_rwdata_lib "procs/rwdata.idl")
target_link_libraries(mpt_qosmatch PRIVATE mpt_qosmatch_rwdata_lib)

View file

@ -0,0 +1,376 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "mpt/mpt.h"
#include "dds/dds.h"
#include "rwdata.h"
#include "dds/ddsrt/time.h"
#include "dds/ddsrt/process.h"
#include "dds/ddsrt/sockets.h"
#include "dds/ddsrt/heap.h"
#include "dds/ddsi/q_xqos.h"
#define NPUB 10
#define NWR_PUB 2
void rw_init (void)
{
}
void rw_fini (void)
{
}
static void setqos (dds_qos_t *q, size_t i, bool isrd, bool create)
{
size_t psi = i - (i % NWR_PUB);
/* Participant, publisher & topic get created with i == 0,
so make sure those have some crazy data set. The writers
should inherit the topic and group data, but the user data
should be updated for each writer */
if (create)
{
if (psi == 1)
{
dds_qset_userdata (q, NULL, 0);
dds_qset_topicdata (q, NULL, 0);
dds_qset_groupdata (q, NULL, 0);
}
else
{
char buf[20];
snprintf (buf, sizeof (buf), "ud%zu%c", i, isrd ? 'r' : 'w');
dds_qset_userdata (q, buf, strlen (buf));
snprintf (buf, sizeof (buf), "td%zu", i);
dds_qset_topicdata (q, buf, strlen (buf));
snprintf (buf, sizeof (buf), "gd%zu", psi);
dds_qset_groupdata (q, buf, strlen (buf));
}
}
else
{
if (psi == 1)
{
dds_qset_userdata (q, NULL, 0);
dds_qset_topicdata (q, NULL, 0);
dds_qset_groupdata (q, NULL, 0);
}
else
{
char buf[20];
snprintf (buf, sizeof (buf), "ud%zu%c", i, isrd ? 'r' : 'w');
dds_qset_userdata (q, buf, strlen (buf));
snprintf (buf, sizeof (buf), "td%zu", (size_t) 0);
dds_qset_topicdata (q, buf, strlen (buf));
snprintf (buf, sizeof (buf), "gd%zu", psi);
dds_qset_groupdata (q, buf, strlen (buf));
}
}
/* Cyclone's accepting unimplemented QoS settings is a bug, but it does allow
us to feed it all kinds of nonsense and see whether discovery manages it */
/* this makes topic transient-local, keep-last 1 */
dds_qset_durability (q, (dds_durability_kind_t) ((i + 1) % 4));
dds_qset_history (q, (dds_history_kind_t) ((i + 1) % 2), (int32_t) (i + 1));
dds_qset_resource_limits (q, (int32_t) i + 3, (int32_t) i + 2, (int32_t) i + 1);
dds_qset_presentation (q, (dds_presentation_access_scope_kind_t) ((psi + 1) % 3), 1, 1);
dds_qset_lifespan (q, INT64_C (23456789012345678) + (int32_t) i);
dds_qset_deadline (q, INT64_C (67890123456789012) + (int32_t) i);
dds_qset_latency_budget (q, INT64_C (45678901234567890) + (int32_t) i);
dds_qset_ownership (q, (dds_ownership_kind_t) ((i + 1) % 2));
dds_qset_ownership_strength (q, 0x12345670 + (int32_t) i);
dds_qset_liveliness (q, (dds_liveliness_kind_t) ((i + i) % 2), INT64_C (456789012345678901) + (int32_t) i);
dds_qset_time_based_filter (q, INT64_C (34567890123456789) + (int32_t) i); /* must be <= deadline */
if (psi == 0)
dds_qset_partition1 (q, "p");
else if (psi == 1)
dds_qset_partition (q, 0, NULL);
else
{
char **ps = ddsrt_malloc (psi * sizeof (*ps));
for (size_t j = 0; j < psi; j++)
{
const size_t n = 40;
ps[j] = ddsrt_malloc (n);
snprintf (ps[j], n, "p%zu_%zu", psi, isrd ? (psi-j-1) : j);
}
dds_qset_partition (q, (uint32_t) psi, (const char **) ps);
for (size_t j = 0; j < psi; j++)
ddsrt_free (ps[j]);
ddsrt_free (ps);
}
dds_qset_reliability (q, (dds_reliability_kind_t) ((i + 1) % 2), INT64_C (890123456789012345) + (int32_t) i);
dds_qset_transport_priority (q, 0x23456701 + (int32_t) i);
dds_qset_destination_order (q, (dds_destination_order_kind_t) ((i + 1) % 2));
dds_qset_writer_data_lifecycle (q, ((i + 1) % 2) != 0);
dds_qset_reader_data_lifecycle (q, INT64_C (41234567890123456) + (int32_t) i, INT64_C (912345678901234567) + (int32_t) i);
dds_qset_durability_service (q, INT64_C (123456789012345678) + (int32_t) i, (dds_history_kind_t) ((i + 1) % 2), (int32_t) (i + 1), (int32_t) i + 3, (int32_t) i + 2, (int32_t) i + 1);
}
static bool pubsub_qos_eq_h (const dds_qos_t *a, dds_entity_t ent)
{
dds_qos_t *b = dds_create_qos ();
dds_get_qos (ent, b);
/* internal interface is more luxurious that a simple compare for equality, and
using that here saves us a ton of code */
uint64_t delta = nn_xqos_delta (a, b, QP_GROUP_DATA | QP_PRESENTATION | QP_PARTITION);
if (delta)
{
DDS_LOG (DDS_LC_ERROR, "pub/sub: delta = %"PRIx64"\n", delta);
nn_log_xqos (DDS_LC_ERROR, a); DDS_LOG (DDS_LC_ERROR, "\n");
nn_log_xqos (DDS_LC_ERROR, b); DDS_LOG (DDS_LC_ERROR, "\n");
}
dds_delete_qos (b);
return delta == 0;
}
static uint64_t reader_qos_delta (const dds_qos_t *a, const dds_qos_t *b)
{
return nn_xqos_delta (a, b, QP_USER_DATA | QP_TOPIC_DATA | QP_GROUP_DATA | QP_DURABILITY | QP_HISTORY | QP_RESOURCE_LIMITS | QP_PRESENTATION | QP_DEADLINE | QP_LATENCY_BUDGET | QP_OWNERSHIP | QP_LIVELINESS | QP_TIME_BASED_FILTER | QP_PARTITION | QP_RELIABILITY | QP_DESTINATION_ORDER | QP_PRISMTECH_READER_DATA_LIFECYCLE);
}
static bool reader_qos_eq_h (const dds_qos_t *a, dds_entity_t ent)
{
dds_qos_t *b = dds_create_qos ();
dds_get_qos (ent, b);
uint64_t delta = reader_qos_delta (a, b);
if (delta)
{
DDS_LOG (DDS_LC_ERROR, "reader: delta = %"PRIx64"\n", delta);
nn_log_xqos (DDS_LC_ERROR, a); DDS_LOG (DDS_LC_ERROR, "\n");
nn_log_xqos (DDS_LC_ERROR, b); DDS_LOG (DDS_LC_ERROR, "\n");
}
dds_delete_qos (b);
return delta == 0;
}
static uint64_t writer_qos_delta (const dds_qos_t *a, const dds_qos_t *b)
{
return nn_xqos_delta (a, b, QP_USER_DATA | QP_TOPIC_DATA | QP_GROUP_DATA | QP_DURABILITY | QP_HISTORY | QP_RESOURCE_LIMITS | QP_PRESENTATION | QP_LIFESPAN | QP_DEADLINE | QP_LATENCY_BUDGET | QP_OWNERSHIP | QP_OWNERSHIP_STRENGTH | QP_LIVELINESS | QP_PARTITION | QP_RELIABILITY | QP_DESTINATION_ORDER | QP_PRISMTECH_WRITER_DATA_LIFECYCLE);
}
static bool writer_qos_eq_h (const dds_qos_t *a, dds_entity_t ent)
{
dds_qos_t *b = dds_create_qos ();
dds_get_qos (ent, b);
uint64_t delta = writer_qos_delta (a, b);
if (delta)
{
DDS_LOG (DDS_LC_ERROR, "writer: delta = %"PRIx64"\n", delta);
nn_log_xqos (DDS_LC_ERROR, a); DDS_LOG (DDS_LC_ERROR, "\n");
nn_log_xqos (DDS_LC_ERROR, b); DDS_LOG (DDS_LC_ERROR, "\n");
}
dds_delete_qos (b);
return delta == 0;
}
MPT_ProcessEntry (rw_publisher,
MPT_Args (dds_domainid_t domainid,
const char *topic_name))
{
dds_entity_t dp;
dds_entity_t tp;
dds_entity_t pub[NPUB];
dds_entity_t wr[NPUB][NWR_PUB];
bool chk[NPUB][NWR_PUB] = { { false } };
dds_return_t rc;
dds_qos_t *qos;
int id = (int) ddsrt_getpid ();
printf ("=== [Publisher(%d)] Start(%d) ...\n", id, (int) domainid);
qos = dds_create_qos ();
setqos (qos, 0, false, true);
dp = dds_create_participant (domainid, NULL, NULL);
MPT_ASSERT_FATAL_GT (dp, 0, "Could not create participant: %s\n", dds_strretcode (dp));
tp = dds_create_topic (dp, &RWData_Msg_desc, topic_name, qos, NULL);
MPT_ASSERT_FATAL_GT (tp, 0, "Could not create topic: %s\n", dds_strretcode (tp));
for (size_t i = 0; i < NPUB; i++)
{
setqos (qos, i * NWR_PUB, false, true);
pub[i] = dds_create_publisher (dp, qos, NULL);
MPT_ASSERT_FATAL_GT (pub[i], 0, "Could not create publisher %zu: %s\n", i, dds_strretcode (pub[i]));
for (size_t j = 0; j < NWR_PUB; j++)
{
setqos (qos, i * NWR_PUB + j, false, true);
wr[i][j] = dds_create_writer (pub[i], tp, qos, NULL);
MPT_ASSERT_FATAL_GT (wr[i][j], 0, "Could not create writer %zu %zu: %s\n", i, j, dds_strretcode (wr[i][j]));
}
}
for (size_t i = 0; i < NPUB; i++)
{
setqos (qos, i * NWR_PUB, false, false);
MPT_ASSERT (pubsub_qos_eq_h (qos, pub[i]), "publisher %zu QoS mismatch\n", i);
for (size_t j = 0; j < NWR_PUB; j++)
{
setqos (qos, i * NWR_PUB + j, false, false);
MPT_ASSERT (writer_qos_eq_h (qos, wr[i][j]), "writer %zu %zu QoS mismatch\n", i, j);
}
}
/* Each writer should match exactly one reader */
uint32_t nchk = 0;
while (nchk != NPUB * NWR_PUB)
{
for (size_t i = 0; i < NPUB; i++)
{
for (size_t j = 0; j < NWR_PUB; j++)
{
if (chk[i][j])
continue;
dds_instance_handle_t ih;
dds_builtintopic_endpoint_t *ep;
rc = dds_get_matched_subscriptions (wr[i][j], &ih, 1);
MPT_ASSERT (rc == 0 || rc == 1, "Unexpected return from get_matched_subscriptions for writer %zu %zu: %s\n",
i, j, dds_strretcode (rc));
if (rc == 1)
{
ep = dds_get_matched_subscription_data (wr[i][j], ih);
MPT_ASSERT (ep != NULL, "Failed to retrieve matched subscription data for writer %zu %zu\n", i, j);
setqos (qos, i * NWR_PUB + j, true, false);
uint64_t delta = reader_qos_delta (qos, ep->qos);
if (delta)
{
DDS_LOG (DDS_LC_ERROR, "matched reader: delta = %"PRIx64"\n", delta);
nn_log_xqos (DDS_LC_ERROR, qos); DDS_LOG (DDS_LC_ERROR, "\n");
nn_log_xqos (DDS_LC_ERROR, ep->qos); DDS_LOG (DDS_LC_ERROR, "\n");
}
MPT_ASSERT (delta == 0, "writer %zu %zu matched reader QoS mismatch\n", i, j);
dds_delete_qos (ep->qos);
dds_free (ep->topic_name);
dds_free (ep->type_name);
dds_free (ep);
chk[i][j] = true;
nchk++;
}
}
}
dds_sleepfor (DDS_MSECS (100));
}
/* Wait until subscribers terminate */
while (true)
{
for (size_t i = 0; i < NPUB; i++)
{
for (size_t j = 0; j < NWR_PUB; j++)
{
dds_publication_matched_status_t st;
rc = dds_get_publication_matched_status (wr[i][j], &st);
MPT_ASSERT_FATAL_EQ (rc, DDS_RETCODE_OK, "dds_get_matched_publication_status failed for writer %zu %zu: %s\n",
i, j, dds_strretcode (rc));
if (st.current_count)
goto have_matches;
}
}
break;
have_matches:
;
}
dds_delete_qos (qos);
rc = dds_delete (dp);
MPT_ASSERT_EQ (rc, DDS_RETCODE_OK, "teardown failed\n");
printf ("=== [Publisher(%d)] Done\n", id);
}
MPT_ProcessEntry (rw_subscriber,
MPT_Args (dds_domainid_t domainid,
const char *topic_name))
{
dds_entity_t dp;
dds_entity_t tp;
dds_entity_t sub[NPUB];
dds_entity_t rd[NPUB][NWR_PUB];
bool chk[NPUB][NWR_PUB] = { { false } };
dds_return_t rc;
dds_qos_t *qos;
int id = (int) ddsrt_getpid ();
printf ("=== [Subscriber(%d)] Start(%d) ...\n", id, (int) domainid);
qos = dds_create_qos ();
setqos (qos, 0, true, true);
dp = dds_create_participant (domainid, NULL, NULL);
MPT_ASSERT_FATAL_GT (dp, 0, "Could not create participant: %s\n", dds_strretcode (dp));
tp = dds_create_topic (dp, &RWData_Msg_desc, topic_name, qos, NULL);
MPT_ASSERT_FATAL_GT (tp, 0, "Could not create topic: %s\n", dds_strretcode (tp));
for (size_t i = 0; i < NPUB; i++)
{
setqos (qos, i * NWR_PUB, true, true);
sub[i] = dds_create_subscriber (dp, qos, NULL);
MPT_ASSERT_FATAL_GT (sub[i], 0, "Could not create subscriber %zu: %s\n", i, dds_strretcode (sub[i]));
for (size_t j = 0; j < NWR_PUB; j++)
{
setqos (qos, i * NWR_PUB + j, true, true);
rd[i][j] = dds_create_reader (sub[i], tp, qos, NULL);
MPT_ASSERT_FATAL_GT (rd[i][j], 0, "Could not create reader %zu %zu: %s\n", i, j, dds_strretcode (rd[i][j]));
}
}
for (size_t i = 0; i < NPUB; i++)
{
setqos (qos, i * NWR_PUB, true, false);
MPT_ASSERT (pubsub_qos_eq_h (qos, sub[i]), "subscriber %zu QoS mismatch\n", i);
for (size_t j = 0; j < NWR_PUB; j++)
{
setqos (qos, i * NWR_PUB + j, true, false);
MPT_ASSERT (reader_qos_eq_h (qos, rd[i][j]), "reader %zu %zu QoS mismatch\n", i, j);
}
}
/* Each writer should match exactly one reader */
uint32_t nchk = 0;
while (nchk != NPUB * NWR_PUB)
{
for (size_t i = 0; i < NPUB; i++)
{
for (size_t j = 0; j < NWR_PUB; j++)
{
if (chk[i][j])
continue;
dds_instance_handle_t ih;
dds_builtintopic_endpoint_t *ep;
rc = dds_get_matched_publications (rd[i][j], &ih, 1);
MPT_ASSERT (rc == 0 || rc == 1, "Unexpected return from get_matched_publications for writer %zu %zu: %s\n",
i, j, dds_strretcode (rc));
if (rc == 1)
{
ep = dds_get_matched_publication_data (rd[i][j], ih);
MPT_ASSERT (ep != NULL, "Failed to retrieve matched publication data for writer %zu %zu\n", i, j);
setqos (qos, i * NWR_PUB + j, false, false);
uint64_t delta = writer_qos_delta (qos, ep->qos);
if (delta)
{
DDS_LOG (DDS_LC_ERROR, "matched writer: delta = %"PRIx64"\n", delta);
nn_log_xqos (DDS_LC_ERROR, qos); DDS_LOG (DDS_LC_ERROR, "\n");
nn_log_xqos (DDS_LC_ERROR, ep->qos); DDS_LOG (DDS_LC_ERROR, "\n");
}
MPT_ASSERT (delta == 0, "reader %zu %zu matched writer QoS mismatch\n", i, j);
dds_delete_qos (ep->qos);
dds_free (ep->topic_name);
dds_free (ep->type_name);
dds_free (ep);
chk[i][j] = true;
nchk++;
}
}
}
dds_sleepfor (DDS_MSECS (100));
}
dds_delete_qos (qos);
rc = dds_delete (dp);
MPT_ASSERT_EQ (rc, DDS_RETCODE_OK, "teardown failed\n");
printf ("=== [Subscriber(%d)] Done\n", id);
}

View file

@ -0,0 +1,41 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#ifndef MPT_QOSMATCH_PROCS_RW_H
#define MPT_QOSMATCH_PROCS_RW_H
#include <stdio.h>
#include <string.h>
#include "dds/dds.h"
#include "mpt/mpt.h"
#if defined (__cplusplus)
extern "C" {
#endif
void rw_init (void);
void rw_fini (void);
MPT_ProcessEntry (rw_publisher,
MPT_Args (dds_domainid_t domainid,
const char *topic_name));
MPT_ProcessEntry (rw_subscriber,
MPT_Args (dds_domainid_t domainid,
const char *topic_name));
#if defined (__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,8 @@
module RWData
{
struct Msg
{
long k;
};
#pragma keylist Msg k
};

View file

@ -0,0 +1,20 @@
#include "mpt/mpt.h"
#include "procs/rw.h"
/*
* Tests to check communication between multiple publisher(s) and subscriber(s).
*/
/*
* The publisher expects 2 publication matched.
* The subscribers expect 1 sample each.
*/
#define TEST_PUB_ARGS MPT_ArgValues(DDS_DOMAIN_DEFAULT, "multi_qosmatch")
#define TEST_SUB_ARGS MPT_ArgValues(DDS_DOMAIN_DEFAULT, "multi_qosmatch")
MPT_TestProcess(qosmatch, qosmatch, pub, rw_publisher, TEST_PUB_ARGS);
MPT_TestProcess(qosmatch, qosmatch, sub, rw_subscriber, TEST_SUB_ARGS);
MPT_Test(qosmatch, qosmatch, .init=rw_init, .fini=rw_fini);
#undef TEST_SUB_ARGS
#undef TEST_PUB_ARGS