Added property policy.

Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>
This commit is contained in:
Martin Bremmer 2019-09-16 17:00:22 +02:00 committed by Erik Boasson
parent 527a59f82f
commit 9f1ddb0b38
4 changed files with 115 additions and 19 deletions

View file

@ -243,6 +243,9 @@ struct nn_rdata;
DDS_EXPORT unsigned char *nn_plist_quickscan (struct nn_rsample_info *dest, const struct nn_rmsg *rmsg, const nn_plist_src_t *src); DDS_EXPORT unsigned char *nn_plist_quickscan (struct nn_rsample_info *dest, const struct nn_rmsg *rmsg, const nn_plist_src_t *src);
DDS_EXPORT const unsigned char *nn_plist_findparam_native_unchecked (const void *src, nn_parameterid_t pid); DDS_EXPORT const unsigned char *nn_plist_findparam_native_unchecked (const void *src, nn_parameterid_t pid);
DDS_EXPORT void nn_free_property_policy (dds_property_qospolicy_t *property);
DDS_EXPORT void nn_duplicate_property (dds_property_t *dest, const dds_property_t *src);
#if defined (__cplusplus) #if defined (__cplusplus)
} }
#endif #endif

View file

@ -32,6 +32,39 @@ typedef ddsi_octetseq_t dds_userdata_qospolicy_t;
typedef ddsi_octetseq_t dds_topicdata_qospolicy_t; typedef ddsi_octetseq_t dds_topicdata_qospolicy_t;
typedef ddsi_octetseq_t dds_groupdata_qospolicy_t; typedef ddsi_octetseq_t dds_groupdata_qospolicy_t;
typedef struct dds_property {
/* The propagate boolean will not be send over the wire.
* When the value is 'false', the complete struct shouldn't be send.
* It has to be the first variable within the structure. */
unsigned char propagate;
char *name;
char *value;
} dds_property_t;
typedef struct dds_propertyseq {
uint32_t n;
dds_property_t *props;
} dds_propertyseq_t;
typedef struct dds_binaryproperty {
/* The propagate boolean will not be send over the wire.
* When the value is 'false', the complete struct shouldn't be send.
* It has to be the first variable within the structure. */
unsigned char propagate;
char *name;
ddsi_octetseq_t value;
} dds_binaryproperty_t;
typedef struct dds_binarypropertyseq {
uint32_t n;
dds_binaryproperty_t *props;
} dds_binarypropertyseq_t;
typedef struct dds_property_qospolicy {
dds_propertyseq_t value;
dds_binarypropertyseq_t binary_value;
} dds_property_qospolicy_t;
typedef struct dds_durability_qospolicy { typedef struct dds_durability_qospolicy {
dds_durability_kind_t kind; dds_durability_kind_t kind;
} dds_durability_qospolicy_t; } dds_durability_qospolicy_t;
@ -212,6 +245,7 @@ typedef struct dds_ignorelocal_qospolicy {
#define QP_PRISMTECH_SUBSCRIPTION_KEYS ((uint64_t)1 << 25) #define QP_PRISMTECH_SUBSCRIPTION_KEYS ((uint64_t)1 << 25)
#define QP_PRISMTECH_ENTITY_FACTORY ((uint64_t)1 << 27) #define QP_PRISMTECH_ENTITY_FACTORY ((uint64_t)1 << 27)
#define QP_CYCLONE_IGNORELOCAL ((uint64_t)1 << 30) #define QP_CYCLONE_IGNORELOCAL ((uint64_t)1 << 30)
#define QP_PROPERTY_LIST ((uint64_t)1 << 31)
/* Partition QoS is not RxO according to the specification (DDS 1.2, /* Partition QoS is not RxO according to the specification (DDS 1.2,
section 7.1.3), but communication will not take place unless it section 7.1.3), but communication will not take place unless it
@ -263,6 +297,7 @@ struct dds_qos {
/*x xR*/dds_subscription_keys_qospolicy_t subscription_keys; /*x xR*/dds_subscription_keys_qospolicy_t subscription_keys;
/*x xR*/dds_reader_lifespan_qospolicy_t reader_lifespan; /*x xR*/dds_reader_lifespan_qospolicy_t reader_lifespan;
/* x */dds_ignorelocal_qospolicy_t ignorelocal; /* x */dds_ignorelocal_qospolicy_t ignorelocal;
/*xxx */dds_property_qospolicy_t property;
}; };
struct nn_xmsg; struct nn_xmsg;

View file

@ -453,6 +453,7 @@ static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi
#ifndef NDEBUG #ifndef NDEBUG
size_t keysize; size_t keysize;
#endif #endif
assert(rawkey);
switch (sample->keyparam) switch (sample->keyparam)
{ {
case PID_PARTICIPANT_GUID: case PID_PARTICIPANT_GUID:

View file

@ -115,10 +115,10 @@ struct piddesc {
size_t plist_offset; /* offset from start of nn_plist_t */ size_t plist_offset; /* offset from start of nn_plist_t */
size_t size; /* in-memory size for copying */ size_t size; /* in-memory size for copying */
union { union {
/* descriptor for generic code: 4 is enough for the current set of /* descriptor for generic code: 11 is enough for the current set of
parameters, compiler will warn if one ever tries to use more than parameters, compiler will warn if one ever tries to use more than
will fit; on non-GCC/Clang and 32-bits machines */ will fit; on non-GCC/Clang and 32-bits machines */
const enum pserop desc[5]; const enum pserop desc[11];
struct { struct {
dds_return_t (*deser) (void * __restrict dst, size_t * __restrict dstoff, struct flagset *flagset, uint64_t flag, const struct dd * __restrict dd, size_t * __restrict srcoff); dds_return_t (*deser) (void * __restrict dst, size_t * __restrict dstoff, struct flagset *flagset, uint64_t flag, const struct dd * __restrict dd, size_t * __restrict srcoff);
dds_return_t (*ser) (struct nn_xmsg *xmsg, nn_parameterid_t pid, const void *src, size_t srcoff); dds_return_t (*ser) (struct nn_xmsg *xmsg, nn_parameterid_t pid, const void *src, size_t srcoff);
@ -357,7 +357,6 @@ static size_t ser_generic_srcsize (const enum pserop * __restrict desc)
desc++; desc++;
} }
#undef SIMPLE #undef SIMPLE
#undef COMPLEX
} }
static void fini_generic_partial (void * __restrict dst, size_t * __restrict dstoff, const enum pserop *desc, const enum pserop * const desc_end, bool aliased) static void fini_generic_partial (void * __restrict dst, size_t * __restrict dstoff, const enum pserop *desc, const enum pserop * const desc_end, bool aliased)
@ -393,9 +392,8 @@ static void fini_generic_partial (void * __restrict dst, size_t * __restrict dst
/* non-nested, so never a need to deallocate only some of the entries and no complications /* non-nested, so never a need to deallocate only some of the entries and no complications
in locating the end of the sequence element description */ in locating the end of the sequence element description */
COMPLEX (XQ, ddsi_octetseq_t, { COMPLEX (XQ, ddsi_octetseq_t, {
const size_t elem_size = ser_generic_srcsize (desc + 1); size_t elem_off = 0;
for (uint32_t i = 0; i < x->length; i++) { for (uint32_t i = 0; i < x->length; i++) {
size_t elem_off = i * elem_size;
fini_generic_partial (x->value, &elem_off, desc + 1, desc_end, aliased); fini_generic_partial (x->value, &elem_off, desc + 1, desc_end, aliased);
} }
}, ddsrt_free (x->value)); }, ddsrt_free (x->value));
@ -542,10 +540,10 @@ static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict ds
if (deser_uint32 (&x->length, dd, srcoff) < 0 || x->length > dd->bufsz - *srcoff) if (deser_uint32 (&x->length, dd, srcoff) < 0 || x->length > dd->bufsz - *srcoff)
goto fail; goto fail;
const size_t elem_size = ser_generic_srcsize (desc + 1); const size_t elem_size = ser_generic_srcsize (desc + 1);
size_t elem_off = 0;
x->value = x->length ? ddsrt_malloc (x->length * elem_size) : NULL; x->value = x->length ? ddsrt_malloc (x->length * elem_size) : NULL;
for (uint32_t i = 0; i < x->length; i++) for (uint32_t i = 0; i < x->length; i++)
{ {
size_t elem_off = i * elem_size;
if (deser_generic (x->value, &elem_off, flagset, flag, dd, srcoff, desc + 1) < 0) if (deser_generic (x->value, &elem_off, flagset, flag, dd, srcoff, desc + 1) < 0)
goto fail; goto fail;
} }
@ -564,7 +562,7 @@ fail:
return DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
} }
static void ser_generic_size1 (size_t *dstoff, const void *src, size_t srcoff, const enum pserop * __restrict desc) static void ser_generic_size_partial (size_t *dstoff, const void *src, size_t srcoff, const enum pserop * __restrict desc)
{ {
bool suppressed = false; bool suppressed = false;
#define COMPLEX(basecase_, type_, dstoff_update_) do { \ #define COMPLEX(basecase_, type_, dstoff_update_) do { \
@ -598,19 +596,20 @@ static void ser_generic_size1 (size_t *dstoff, const void *src, size_t srcoff, c
const size_t elem_size = ser_generic_srcsize (desc + 1); const size_t elem_size = ser_generic_srcsize (desc + 1);
*dstoff = align4size (*dstoff) + 4; *dstoff = align4size (*dstoff) + 4;
for (uint32_t i = 0; i < x->length; i++) for (uint32_t i = 0; i < x->length; i++)
ser_generic_size1 (dstoff, x->value, i * elem_size, desc + 1); ser_generic_size_partial (dstoff, x->value, i * elem_size, desc + 1);
}); while (*++desc != XSTOP) { } break; }); while (*++desc != XSTOP) { } break;
} }
desc++; desc++;
} }
#undef SIMPLE #undef SIMPLE4
#undef SIMPLE1
#undef COMPLEX #undef COMPLEX
} }
static size_t ser_generic_size (const void *src, size_t srcoff, const enum pserop * __restrict desc) static size_t ser_generic_size (const void *src, size_t srcoff, const enum pserop * __restrict desc)
{ {
size_t dstoff = 0; size_t dstoff = 0;
ser_generic_size1 (&dstoff, src, srcoff, desc); ser_generic_size_partial (&dstoff, src, srcoff, desc);
return dstoff; return dstoff;
} }
@ -629,7 +628,7 @@ static uint32_t ser_generic_count (const ddsi_octetseq_t *src, size_t elem_size,
return count; return count;
} }
static dds_return_t ser_generic1 (char * const data, size_t *dstoff, const void *src, size_t srcoff, const enum pserop * __restrict desc) static dds_return_t ser_generic_partial (char * const data, size_t *dstoff, const void *src, size_t srcoff, const enum pserop * __restrict desc)
{ {
while (true) while (true)
{ {
@ -750,7 +749,7 @@ static dds_return_t ser_generic1 (char * const data, size_t *dstoff, const void
const size_t elem_size = ser_generic_srcsize (desc + 1); const size_t elem_size = ser_generic_srcsize (desc + 1);
*((uint32_t *) p) = ser_generic_count (x, elem_size, desc + 1); *((uint32_t *) p) = ser_generic_count (x, elem_size, desc + 1);
for (uint32_t i = 0; i < x->length; i++) for (uint32_t i = 0; i < x->length; i++)
ser_generic1 (data, dstoff, x->value, i * elem_size, desc + 1); ser_generic_partial (data, dstoff, x->value, i * elem_size, desc + 1);
} }
srcoff += sizeof (*x); srcoff += sizeof (*x);
while (*++desc != XSTOP) { } while (*++desc != XSTOP) { }
@ -765,7 +764,7 @@ static dds_return_t ser_generic (struct nn_xmsg *xmsg, nn_parameterid_t pid, con
{ {
char * const data = nn_xmsg_addpar (xmsg, pid, ser_generic_size (src, srcoff, desc)); char * const data = nn_xmsg_addpar (xmsg, pid, ser_generic_size (src, srcoff, desc));
size_t dstoff = 0; size_t dstoff = 0;
return ser_generic1 (data, &dstoff, src, srcoff, desc); return ser_generic_partial (data, &dstoff, src, srcoff, desc);
} }
static dds_return_t unalias_generic (void * __restrict dst, size_t * __restrict dstoff, const enum pserop * __restrict desc) static dds_return_t unalias_generic (void * __restrict dst, size_t * __restrict dstoff, const enum pserop * __restrict desc)
@ -796,10 +795,9 @@ static dds_return_t unalias_generic (void * __restrict dst, size_t * __restrict
case XG: SIMPLE (XG, ddsi_guid_t); break; case XG: SIMPLE (XG, ddsi_guid_t); break;
case XK: SIMPLE (XK, nn_keyhash_t); break; case XK: SIMPLE (XK, nn_keyhash_t); break;
case XQ: COMPLEX (XQ, ddsi_octetseq_t, if (x->length) { case XQ: COMPLEX (XQ, ddsi_octetseq_t, if (x->length) {
const size_t elem_size = ser_generic_srcsize (desc + 1); size_t elem_off = 0;
x->value = ddsrt_memdup (x->value, x->length * elem_size); x->value = ddsrt_memdup (x->value, x->length * ser_generic_srcsize(desc + 1));
for (uint32_t i = 0; i < x->length; i++) { for (uint32_t i = 0; i < x->length; i++) {
size_t elem_off = i * elem_size;
unalias_generic (x->value, &elem_off, desc + 1); unalias_generic (x->value, &elem_off, desc + 1);
} }
}); while (*++desc != XSTOP) { } break; }); while (*++desc != XSTOP) { } break;
@ -1029,6 +1027,15 @@ static dds_return_t dvx_reader_favours_ssm (void * __restrict dst, const struct
} }
#endif #endif
/* pserop representation of dds_propertyseq_t. */
#define PROPERTYSEQ_PSEROP XQ, XbPROP, XS, XS, XSTOP
/* pserop representation of dds_binarypropertyseq_t. */
#define BINPROPERTYSEQ_PSEROP XQ, XbPROP, XS, XO, XSTOP
/* pserop representation of dds_property_qospolicy_t. */
#define PROPERTY_POLICY_PSEROP PROPERTYSEQ_PSEROP, BINPROPERTYSEQ_PSEROP
/* Standardized parameters -- QoS _MUST_ come first (nn_plist_init_tables verifies this) because /* Standardized parameters -- QoS _MUST_ come first (nn_plist_init_tables verifies this) because
it allows early-out when processing a dds_qos_t instead of an nn_plist_t */ it allows early-out when processing a dds_qos_t instead of an nn_plist_t */
static const struct piddesc piddesc_omg[] = { static const struct piddesc piddesc_omg[] = {
@ -1044,6 +1051,7 @@ static const struct piddesc piddesc_omg[] = {
QP (DEADLINE, deadline, XD), QP (DEADLINE, deadline, XD),
QP (LATENCY_BUDGET, latency_budget, XD), QP (LATENCY_BUDGET, latency_budget, XD),
QP (LIVELINESS, liveliness, XE2, XD), QP (LIVELINESS, liveliness, XE2, XD),
QP (PROPERTY_LIST, property, PROPERTY_POLICY_PSEROP),
/* Reliability encoding does not follow the rules (best-effort/reliable map to 1/2 instead of 0/1 */ /* Reliability encoding does not follow the rules (best-effort/reliable map to 1/2 instead of 0/1 */
{ PID_RELIABILITY, PDF_QOS | PDF_FUNCTION, QP_RELIABILITY, "RELIABILITY", { PID_RELIABILITY, PDF_QOS | PDF_FUNCTION, QP_RELIABILITY, "RELIABILITY",
offsetof (struct nn_plist, qos.reliability), membersize (struct nn_plist, qos.reliability), offsetof (struct nn_plist, qos.reliability), membersize (struct nn_plist, qos.reliability),
@ -1219,8 +1227,8 @@ static const struct piddesc_index piddesc_vendor_index[] = {
/* List of entries that require unalias, fini processing; /* List of entries that require unalias, fini processing;
initialized by nn_plist_init_tables; will assert when initialized by nn_plist_init_tables; will assert when
table too small or too large */ table too small or too large */
static const struct piddesc *piddesc_unalias[18]; static const struct piddesc *piddesc_unalias[19];
static const struct piddesc *piddesc_fini[18]; static const struct piddesc *piddesc_fini[19];
static ddsrt_once_t table_init_control = DDSRT_ONCE_INIT; static ddsrt_once_t table_init_control = DDSRT_ONCE_INIT;
static nn_parameterid_t pid_without_flags (nn_parameterid_t pid) static nn_parameterid_t pid_without_flags (nn_parameterid_t pid)
@ -2306,7 +2314,7 @@ const unsigned char *nn_plist_findparam_native_unchecked (const void *src, nn_pa
const nn_parameter_t *par = src; const nn_parameter_t *par = src;
while (par->parameterid != pid) while (par->parameterid != pid)
{ {
if (pid == PID_SENTINEL) if (par->parameterid == PID_SENTINEL)
return NULL; return NULL;
par = (const nn_parameter_t *) ((const char *) (par + 1) + par->length); par = (const nn_parameter_t *) ((const char *) (par + 1) + par->length);
} }
@ -2841,6 +2849,29 @@ void nn_log_xqos (uint32_t cat, const struct ddsrt_log_cfg *logcfg, const dds_qo
}); });
DO (PRISMTECH_ENTITY_FACTORY, { LOGB1 ("entity_factory=%u", xqos->entity_factory.autoenable_created_entities); }); DO (PRISMTECH_ENTITY_FACTORY, { LOGB1 ("entity_factory=%u", xqos->entity_factory.autoenable_created_entities); });
DO (CYCLONE_IGNORELOCAL, { LOGB1 ("ignorelocal=%u", xqos->ignorelocal.value); }); DO (CYCLONE_IGNORELOCAL, { LOGB1 ("ignorelocal=%u", xqos->ignorelocal.value); });
DO (PROPERTY_LIST, {
LOGB0 ("property_list={");
DDS_CLOG (cat, logcfg, "value={");
for (uint32_t i = 0; i < xqos->property.value.n; i++) {
DDS_CLOG (cat, logcfg, "%s{%s,%s,%u}",
(i == 0) ? "" : ",",
xqos->property.value.props[i].name,
xqos->property.value.props[i].value,
xqos->property.value.props[i].propagate);
}
DDS_CLOG (cat, logcfg, "}");
DDS_CLOG (cat, logcfg, "binary_value={");
for (uint32_t i = 0; i < xqos->property.binary_value.n; i++) {
DDS_CLOG (cat, logcfg, "%s{%s,(%u,%p),%u}",
(i == 0) ? "" : ",",
xqos->property.binary_value.props[i].name,
xqos->property.binary_value.props[i].value.length,
xqos->property.binary_value.props[i].value.value,
xqos->property.binary_value.props[i].propagate);
}
DDS_CLOG (cat, logcfg, "}");
DDS_CLOG (cat, logcfg, "}");
});
#undef PRINTARG_DUR #undef PRINTARG_DUR
#undef FMT_DUR #undef FMT_DUR
@ -2852,3 +2883,29 @@ void nn_log_xqos (uint32_t cat, const struct ddsrt_log_cfg *logcfg, const dds_qo
#undef LOGB1 #undef LOGB1
#undef LOGB0 #undef LOGB0
} }
void nn_free_property_policy(dds_property_qospolicy_t *property)
{
const struct piddesc_index *index = &piddesc_vendor_index[0];
const struct piddesc *entry = index->index[PID_PROPERTY_LIST];
size_t niloff = 0;
fini_generic_partial ((void*)property, &niloff, entry->op.desc, NULL, true);
}
void nn_duplicate_property (dds_property_t *dest, const dds_property_t *src)
{
const struct piddesc_index *index = &piddesc_vendor_index[0];
const struct piddesc *entry = index->index[PID_PROPERTY_LIST];
dds_property_qospolicy_t policy;
size_t niloff = 0;
/* First, do a shallow copy. */
*dest = *src;
/* Unalias the shallow copy to get a deep copy. */
policy.value.n = 1;
policy.value.props = dest;
policy.binary_value.n = 0;
policy.binary_value.props = NULL;
(void)unalias_generic(&policy, &niloff, entry->op.desc);
/* Shallow copy the deep copy. */
*dest = *policy.value.props;
}