Participant generic message (#273)

* Extended DDSI (de)serializer.

Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>

* Added security Participant Generic Message.

Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>

* Updated Participant Generic Message.

Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>

* Updated generic ddsi (de)serializer.

Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>

* Changed macros for functions.

Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>
This commit is contained in:
martinbremmer 2019-10-18 19:05:13 +02:00 committed by eboasson
parent 7c1e47218d
commit 64cc631137
10 changed files with 881 additions and 94 deletions

View file

@ -123,6 +123,17 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
target_sources(ddsc
PRIVATE ${srcs_ddsi} ${hdrs_private_ddsi})
if(ENABLE_SECURITY)
PREPEND(security_srcs "${CMAKE_CURRENT_LIST_DIR}/src"
ddsi_security_msg.c)
PREPEND(security_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
ddsi_security_msg.h)
target_sources(ddsc
PRIVATE ${security_srcs} ${security_hdrs})
endif()
target_include_directories(ddsc
PRIVATE "${CMAKE_CURRENT_LIST_DIR}/include")

View file

@ -34,6 +34,7 @@ enum pserop {
Xi, Xix2, Xix3, Xix4, /* int32_t, 1 .. 4 in a row */
Xu, Xux2, Xux3, Xux4, Xux5, /* uint32_t, 1 .. 5 in a row */
XD, XDx2, /* duration, 1 .. 2 in a row */
Xl, /* int64_t */
Xo, Xox2, /* octet, 1 .. 2 in a row */
Xb, Xbx2, /* boolean, 1 .. 2 in a row */
XbCOND, /* boolean: compare to ignore remainder if false (for use_... flags) */
@ -44,15 +45,6 @@ enum pserop {
Xopt, /* remainder is optional on deser, 0-init if not present */
} ddsrt_attribute_packed;
inline bool pserop_seralign_is_1 (enum pserop op) {
/* NB: XbPROP is never serialized, so its alignment is irrelevant. If ever there
is a need to allow calling this function when op = XbPROP, it needs to be changed
to taking the address of the pserop, and in that case inspect the following
operator */
assert (op != XbPROP && op != Xopt && op != XSTOP);
return (op >= Xo && op <= XK);
}
DDS_EXPORT void plist_fini_generic (void * __restrict dst, const enum pserop *desc, bool aliased);
DDS_EXPORT dds_return_t plist_deser_generic (void * __restrict dst, const void * __restrict src, size_t srcsize, bool bswap, const enum pserop * __restrict desc);
DDS_EXPORT dds_return_t plist_ser_generic (void **dst, size_t *dstsize, const void *src, const enum pserop * __restrict desc);

View file

@ -0,0 +1,91 @@
/*
* 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 DDSI_SECURITY_MSG_H
#define DDSI_SECURITY_MSG_H
#include "dds/ddsi/q_plist.h"
#include "dds/ddsi/ddsi_guid.h"
#include "dds/ddsrt/retcode.h"
#include "dds/ddsi/ddsi_plist_generic.h"
#if defined (__cplusplus)
extern "C" {
#endif
#define GMCLASSID_SECURITY_AUTH_REQUEST "dds.sec.auth_request"
#define GMCLASSID_SECURITY_AUTH_HANDSHAKE "dds.sec.auth"
typedef struct nn_message_identity {
ddsi_guid_t source_guid;
int64_t sequence_number;
} nn_message_identity_t;
typedef struct nn_participant_generic_message {
nn_message_identity_t message_identity;
nn_message_identity_t related_message_identity;
ddsi_guid_t destinaton_participant_guid;
ddsi_guid_t destination_endpoint_guid;
ddsi_guid_t source_endpoint_guid;
const char *message_class_id;
nn_dataholderseq_t message_data;
} nn_participant_generic_message_t;
/*
* The arguments are aliased in the resulting message structure.
* This means that the lifecycle of the arguments should be longer
* then that of the message.
*/
DDS_EXPORT void
nn_participant_generic_message_init(
nn_participant_generic_message_t *msg,
const ddsi_guid_t *wrguid,
int64_t wrseq,
const ddsi_guid_t *dstpguid,
const ddsi_guid_t *dsteguid,
const ddsi_guid_t *srceguid,
const char *classid,
const nn_dataholderseq_t *mdata,
const nn_message_identity_t *rmid);
/*
* Aliased struct variables will not be freed.
*/
DDS_EXPORT void
nn_participant_generic_message_deinit(
nn_participant_generic_message_t *msg);
/*
* Some struct variables are aliased to the given buffer.
* This means that the lifecycle of the data buffer should be
* longer then that of the message.
*/
DDS_EXPORT dds_return_t
nn_participant_generic_message_deseralize(
nn_participant_generic_message_t *msg,
const unsigned char *data,
size_t len,
bool bswap);
DDS_EXPORT dds_return_t
nn_participant_generic_message_serialize(
const nn_participant_generic_message_t *msg,
unsigned char **data,
size_t *len);
DDS_EXPORT extern const enum pserop pserop_participant_generic_message[];
#if defined (__cplusplus)
}
#endif
#endif /* DDSI_SECURITY_MSG_H */

View file

@ -134,6 +134,11 @@ typedef struct nn_dataholder
dds_binarypropertyseq_t binary_properties;
} nn_dataholder_t;
typedef struct nn_dataholderseq {
uint32_t n;
nn_dataholder_t *tags;
} nn_dataholderseq_t;
typedef nn_dataholder_t nn_token_t;
/* Used for both nn_participant_security_info and nn_endpoint_security_info. */

View file

@ -0,0 +1,149 @@
/*
* 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 <stddef.h>
#include <string.h>
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/string.h"
#include "dds/ddsi/q_bswap.h"
#include "dds/ddsi/ddsi_security_msg.h"
#include "dds/ddsi/ddsi_plist_generic.h"
const enum pserop pserop_participant_generic_message[] =
{
/* nn_participant_generic_message */
XG, Xl, /* nn_message_identity_t message_identity */
XG, Xl, /* nn_message_identity_t related_message_identity */
XG, /* ddsi_guid_t destinaton_participant_guid */
XG, /* ddsi_guid_t destination_endpoint_guid */
XG, /* ddsi_guid_t source_endpoint_guid */
XS, /* char* message_class_id */
XQ, /* nn_dataholderseq_t message_data */
/* nn_dataholder_t */
XS, /* char* class_id */
XQ, /* dds_propertyseq_t properties */
XbPROP, XS, XS, /* dds_property_t */
XSTOP,
XQ, /* dds_binarypropertyseq_t binary_properties */
XbPROP, XS, XO, /* dds_binaryproperty_t */
XSTOP,
XSTOP,
XSTOP /* end */
};
static void
alias_simple_sequence(ddsi_octetseq_t *dst, const ddsi_octetseq_t *src, size_t elem_size)
{
dst->length = src->length;
if (src->length > 0)
{
/* Even when aliased, sequence buffers are not shared. */
dst->value = ddsrt_memdup(src->value, src->length * elem_size);
}
}
static void
alias_dataholder(nn_dataholder_t *dst, const nn_dataholder_t *src)
{
dst->class_id = src->class_id;
alias_simple_sequence((ddsi_octetseq_t*)&dst->properties,
(const ddsi_octetseq_t*)&src->properties,
sizeof(dds_property_t));
alias_simple_sequence((ddsi_octetseq_t*)&dst->binary_properties,
(const ddsi_octetseq_t*)&src->binary_properties,
sizeof(dds_binaryproperty_t));
}
static void
alias_dataholderseq(nn_dataholderseq_t *dst, const nn_dataholderseq_t *src)
{
dst->n = src->n;
if (src->n > 0)
{
/* Even when aliased, sequence buffers are not shared. */
dst->tags = ddsrt_malloc(src->n * sizeof(nn_dataholder_t));
for (uint32_t i = 0; i < src->n; i++)
{
alias_dataholder(&(dst->tags[i]), &(src->tags[i]));
}
}
}
void
nn_participant_generic_message_init(
nn_participant_generic_message_t *msg,
const ddsi_guid_t *wrguid,
int64_t wrseq,
const ddsi_guid_t *dstpguid,
const ddsi_guid_t *dsteguid,
const ddsi_guid_t *srceguid,
const char *classid,
const nn_dataholderseq_t *mdata,
const nn_message_identity_t *rmid)
{
assert(msg);
assert(wrguid);
assert(classid);
memset(msg, 0, sizeof(*msg));
msg->message_identity.source_guid = *wrguid;
msg->message_identity.sequence_number = wrseq;
if (rmid)
{
msg->related_message_identity.source_guid = rmid->source_guid;
msg->related_message_identity.sequence_number = rmid->sequence_number;
}
if (dstpguid)
msg->destinaton_participant_guid = *dstpguid;
if (dsteguid)
msg->destination_endpoint_guid = *dsteguid;
if (srceguid)
msg->source_endpoint_guid = *srceguid;
msg->message_class_id = classid;
if (mdata)
alias_dataholderseq(&msg->message_data, mdata);
}
void
nn_participant_generic_message_deinit(
nn_participant_generic_message_t *msg)
{
assert(msg);
plist_fini_generic(msg, pserop_participant_generic_message, true);
}
dds_return_t
nn_participant_generic_message_serialize(
const nn_participant_generic_message_t *msg,
unsigned char **data,
size_t *len)
{
return plist_ser_generic ((void**)data, len, (void*)msg, pserop_participant_generic_message);
}
dds_return_t
nn_participant_generic_message_deseralize(
nn_participant_generic_message_t *msg,
const unsigned char *data,
size_t len,
bool bswap)
{
assert(sizeof(nn_participant_generic_message_t) == plist_memsize_generic(pserop_participant_generic_message));
return plist_deser_generic (msg, data, len, bswap, pserop_participant_generic_message);
}

View file

@ -114,8 +114,6 @@ struct piddesc {
dds_return_t (*deser_validate_xform) (void * __restrict dst, const struct dd * __restrict dd);
};
extern inline bool pserop_seralign_is_1 (enum pserop op);
static void log_octetseq (uint32_t cat, const struct ddsrt_log_cfg *logcfg, uint32_t n, const unsigned char *xs);
static dds_return_t validate_history_qospolicy (const dds_history_qospolicy_t *q);
static dds_return_t validate_resource_limits_qospolicy (const dds_resource_limits_qospolicy_t *q);
@ -127,26 +125,70 @@ static dds_return_t final_validation_qos (const dds_qos_t *dest, nn_protocol_ver
static int partitions_equal (const dds_partition_qospolicy_t *a, const dds_partition_qospolicy_t *b);
static dds_return_t nn_xqos_valid_strictness (const struct ddsrt_log_cfg *logcfg, const dds_qos_t *xqos, bool strict);
static size_t align4size (size_t x)
static size_t pserop_seralign(enum pserop op)
{
return (x + 3) & ~(size_t)3;
switch(op)
{
case XSTOP:
case XbPROP:
case Xopt:
/* NB: XbPROP is never serialized, so its alignment is irrelevant. If ever there
is a need to allow calling this function when op = XbPROP, it needs to be changed
to taking the address of the pserop, and in that case inspect the following
operator */
assert(false);
return 1;
case Xo: case Xox2:
case Xb: case Xbx2:
case XbCOND:
case XG:
case XK:
return 1;
case XO:
case XS:
case XE1: case XE2: case XE3:
case Xi: case Xix2: case Xix3: case Xix4:
case Xu: case Xux2: case Xux3: case Xux4: case Xux5:
case XD: case XDx2:
case XQ:
return 4;
case Xl:
return 8;
}
assert(false);
return 1;
}
static void *deser_generic_dst (void * __restrict dst, size_t *dstoff, size_t align)
static size_t alignN(const size_t off, const size_t align)
{
*dstoff = (*dstoff + align - 1) & ~(align - 1);
return (off + align - 1) & ~(align - 1);
}
static size_t align4(const size_t off)
{
return alignN(off, 4);
}
static size_t align8(const size_t off)
{
return alignN(off, 8);
}
static void *deser_generic_dst (void * __restrict dst, size_t *dstoff, const size_t align)
{
*dstoff = alignN(*dstoff, align);
return (char *) dst + *dstoff;
}
static const void *deser_generic_src (const void * __restrict src, size_t *srcoff, size_t align)
static const void *deser_generic_src (const void * __restrict src, size_t *srcoff, const size_t align)
{
*srcoff = (*srcoff + align - 1) & ~(align - 1);
*srcoff = alignN(*srcoff, align);
return (const char *) src + *srcoff;
}
static void *ser_generic_align4 (char * __restrict p, size_t * __restrict off)
static void *ser_generic_aligned (char * __restrict p, size_t * __restrict off, const size_t align)
{
const size_t off1 = align4size (*off);
const size_t off1 = alignN(*off, align);
size_t pad = off1 - *off;
char *dst = p + *off;
*off = off1;
@ -155,6 +197,16 @@ static void *ser_generic_align4 (char * __restrict p, size_t * __restrict off)
return dst;
}
static void *ser_generic_align4(char * __restrict p, size_t * __restrict off)
{
return ser_generic_aligned(p, off, 4);
}
static void *ser_generic_align8(char * __restrict p, size_t * __restrict off)
{
return ser_generic_aligned(p, off, 8);
}
static dds_return_t deser_uint32 (uint32_t *dst, const struct dd * __restrict dd, size_t * __restrict off)
{
size_t off1 = (*off + 3) & ~(size_t)3;
@ -169,6 +221,20 @@ static dds_return_t deser_uint32 (uint32_t *dst, const struct dd * __restrict dd
return 0;
}
static dds_return_t deser_int64 (int64_t *dst, const struct dd * __restrict dd, size_t * __restrict off)
{
size_t off1 = (*off + 7) & ~(size_t)7;
int64_t tmp;
if (off1 + 8 > dd->bufsz)
return DDS_RETCODE_BAD_PARAMETER;
tmp = *((int64_t *) (dd->buf + off1));
if (dd->bswap)
tmp = bswap8 (tmp);
*dst = tmp;
*off = off1 + 8;
return 0;
}
#define alignof(type_) offsetof (struct { char c; type_ d; }, d)
static dds_return_t deser_reliability (void * __restrict dst, size_t * __restrict dstoff, struct flagset *flagset, uint64_t flag, const struct dd * __restrict dd, size_t * __restrict srcoff)
@ -310,6 +376,28 @@ static dds_return_t fini_locator (void * __restrict dst, size_t * __restrict dst
return 0;
}
static const enum pserop* pserop_advance (const enum pserop * __restrict desc)
{
/* Should not start on an end. */
assert(*desc != XSTOP);
/* If not a sequence, return next. */
if (*desc != XQ) return (desc + 1);
/* Jump over this sequence (ignoring nested ones). */
int scope = 1;
do
{
desc++;
if (*desc == XQ) scope++;
if (*desc == XSTOP) scope--;
}
while (scope != 0);
/* We're on the stop, return next. */
return (desc + 1);
}
static size_t ser_generic_srcsize (const enum pserop * __restrict desc)
{
size_t srcoff = 0, srcalign = 0;
@ -330,6 +418,7 @@ static size_t ser_generic_srcsize (const enum pserop * __restrict desc)
case XE1: case XE2: case XE3: SIMPLE (*desc, unsigned); break;
case Xi: case Xix2: case Xix3: case Xix4: SIMPLE (Xi, int32_t); break;
case Xu: case Xux2: case Xux3: case Xux4: case Xux5: SIMPLE (Xu, uint32_t); break;
case Xl: SIMPLE (Xl, int64_t); break;
case XD: case XDx2: SIMPLE (XD, dds_duration_t); break;
case Xo: case Xox2: SIMPLE (Xo, unsigned char); break;
case Xb: case Xbx2: SIMPLE (Xb, unsigned char); break;
@ -337,10 +426,10 @@ static size_t ser_generic_srcsize (const enum pserop * __restrict desc)
case XG: SIMPLE (XG, ddsi_guid_t); break;
case XK: SIMPLE (XK, nn_keyhash_t); break;
case XbPROP: SIMPLE (XbPROP, unsigned char); break;
case XQ: SIMPLE (XQ, ddsi_octetseq_t); while (*++desc != XSTOP) { } break;
case XQ: SIMPLE (XQ, ddsi_octetseq_t); break;
case Xopt: break;
}
desc++;
desc = pserop_advance(desc);
}
#undef SIMPLE
}
@ -350,8 +439,9 @@ size_t plist_memsize_generic (const enum pserop * __restrict desc)
return ser_generic_srcsize (desc);
}
static void fini_generic_embeddable (void * __restrict dst, size_t * __restrict dstoff, const enum pserop *desc, const enum pserop * const desc_end, bool aliased)
static bool fini_generic_embeddable (void * __restrict dst, size_t * __restrict dstoff, const enum pserop *desc, const enum pserop * const desc_end, bool aliased)
{
bool freed = false;
#define COMPLEX(basecase_, type_, cleanup_unaliased_, cleanup_always_) do { \
type_ *x = deser_generic_dst (dst, dstoff, alignof (type_)); \
const uint32_t cnt = 1 + (uint32_t) (*desc - (basecase_)); \
@ -362,16 +452,17 @@ static void fini_generic_embeddable (void * __restrict dst, size_t * __restrict
*dstoff += cnt * sizeof (*x); \
} while (0)
#define SIMPLE(basecase_, type_) COMPLEX (basecase_, type_, (void) 0, (void) 0)
while (desc != desc_end)
while ((desc_end == NULL) || (desc < desc_end))
{
switch (*desc)
{
case XSTOP: return;
case XO: COMPLEX (XO, ddsi_octetseq_t, ddsrt_free (x->value), (void) 0); break;
case XS: COMPLEX (XS, char *, ddsrt_free (*x), (void) 0); break;
case XSTOP: return freed;
case XO: COMPLEX (XO, ddsi_octetseq_t, { ddsrt_free (x->value); freed = true; }, (void) 0); break;
case XS: COMPLEX (XS, char *, { ddsrt_free (*x); freed = true; }, (void) 0); break;
case XE1: case XE2: case XE3: COMPLEX (*desc, unsigned, (void) 0, (void) 0); break;
case Xi: case Xix2: case Xix3: case Xix4: SIMPLE (Xi, int32_t); break;
case Xu: case Xux2: case Xux3: case Xux4: case Xux5: SIMPLE (Xu, uint32_t); break;
case Xl: SIMPLE (Xl, int64_t); break;
case XD: case XDx2: SIMPLE (XD, dds_duration_t); break;
case Xo: case Xox2: SIMPLE (Xo, unsigned char); break;
case Xb: case Xbx2: SIMPLE (Xb, unsigned char); break;
@ -380,23 +471,27 @@ static void fini_generic_embeddable (void * __restrict dst, size_t * __restrict
case XK: SIMPLE (XK, nn_keyhash_t); break;
case XbPROP: SIMPLE (XbPROP, unsigned char); break;
case XQ:
/* 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 */
COMPLEX (XQ, ddsi_octetseq_t, {
{
ddsi_octetseq_t *x = deser_generic_dst (dst, dstoff, alignof (ddsi_octetseq_t));
const size_t elem_size = ser_generic_srcsize (desc + 1);
for (uint32_t i = 0; i < x->length; i++) {
bool elem_freed = true;
for (uint32_t i = 0; (i < x->length) && elem_freed; i++)
{
size_t elem_off = i * elem_size;
fini_generic_embeddable (x->value, &elem_off, desc + 1, desc_end, aliased);
elem_freed = fini_generic_embeddable (x->value, &elem_off, desc + 1, desc_end, aliased);
}
ddsrt_free (x->value);
freed = true;
*dstoff += sizeof (ddsi_octetseq_t);
}
}, ddsrt_free (x->value));
while (desc + 1 != desc_end && *++desc != XSTOP) { }
break;
case Xopt: break;
}
desc++;
desc = pserop_advance(desc);
}
#undef SIMPLE
#undef COMPLEX
return freed;
}
static size_t pserop_memalign (enum pserop op)
@ -413,13 +508,14 @@ static size_t pserop_memalign (enum pserop op)
case XE1: case XE2: case XE3: return sizeof (uint32_t);
case Xi: case Xix2: case Xix3: case Xix4: return sizeof (int32_t);
case Xu: case Xux2: case Xux3: case Xux4: case Xux5: return sizeof (uint32_t);
case Xl: return alignof (int64_t);
case XD: case XDx2: return alignof (dds_duration_t);
case XSTOP: case Xopt: assert (0);
}
return 0;
}
static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict dstoff, struct flagset *flagset, uint64_t flag, const struct dd * __restrict dd, size_t * __restrict srcoff, const enum pserop * __restrict desc)
static dds_return_t deser_generic_r (void * __restrict dst, size_t * __restrict dstoff, struct flagset *flagset, uint64_t flag, const struct dd * __restrict dd, size_t * __restrict srcoff, const enum pserop * __restrict desc)
{
enum pserop const * const desc_in = desc;
size_t dstoff_in = *dstoff;
@ -448,7 +544,7 @@ static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict ds
char ** const x = deser_generic_dst (dst, dstoff, alignof (char *));
ddsi_octetseq_t tmp;
size_t tmpoff = 0;
if (deser_generic (&tmp, &tmpoff, flagset, flag, dd, srcoff, (enum pserop []) { XO, XSTOP }) < 0)
if (deser_generic_r (&tmp, &tmpoff, flagset, flag, dd, srcoff, (enum pserop []) { XO, XSTOP }) < 0)
goto fail;
if (tmp.length < 1 || tmp.value[tmp.length - 1] != 0)
goto fail;
@ -484,6 +580,13 @@ static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict ds
*dstoff += cnt * sizeof (*x);
break;
}
case Xl: { /* int64_t */
int64_t * const x = deser_generic_dst (dst, dstoff, alignof (int64_t));
if (deser_int64(x, dd, srcoff) < 0)
goto fail;
*dstoff += sizeof (*x);
break;
}
case XD: case XDx2: { /* duration(s): int64_t <=> int32_t.uint32_t (seconds.fraction) */
dds_duration_t * const x = deser_generic_dst (dst, dstoff, alignof (dds_duration_t));
const uint32_t cnt = 1 + (uint32_t) (*desc - XD);
@ -547,7 +650,7 @@ static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict ds
*dstoff += sizeof (*x);
break;
}
case XQ: { /* non-nested but otherwise arbitrary sequence, so no nested mallocs */
case XQ: { /* arbitrary sequence */
ddsi_octetseq_t * const x = deser_generic_dst (dst, dstoff, alignof (ddsi_octetseq_t));
if (deser_uint32 (&x->length, dd, srcoff) < 0 || x->length > dd->bufsz - *srcoff)
goto fail;
@ -556,25 +659,26 @@ static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict ds
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_r (x->value, &elem_off, flagset, flag, dd, srcoff, desc + 1) < 0)
{
bool elem_freed = true;
for (uint32_t f = 0; (f < i) && (elem_freed); f++)
{
size_t free_off = f * elem_size;
elem_freed = fini_generic_embeddable (x->value, &free_off, desc + 1, NULL, *flagset->aliased & flag);
}
ddsrt_free (x->value);
goto fail;
}
}
*dstoff += sizeof (*x);
while (*++desc != XSTOP) { }
break;
}
case Xopt: { /* remainder is optional; alignment is very nearly always 4 */
bool end_of_input;
if (pserop_seralign_is_1 (desc[1]))
end_of_input = (*srcoff + 1 > dd->bufsz);
else
{
*srcoff = (*srcoff + 3) & ~(size_t)3;
end_of_input = (*srcoff + 4 > dd->bufsz);
}
size_t align = pserop_seralign(desc[1]);
*srcoff = alignN(*srcoff, align);
end_of_input = (*srcoff + align > dd->bufsz);
if (end_of_input)
{
void * const x = deser_generic_dst (dst, dstoff, pserop_memalign (desc[1]));
@ -584,17 +688,27 @@ static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict ds
}
}
}
desc++;
desc = pserop_advance(desc);
}
success:
*flagset->present |= flag;
return 0;
fail:
fini_generic_embeddable (dst, &dstoff_in, desc_in, desc, *flagset->aliased & flag);
(void)fini_generic_embeddable (dst, &dstoff_in, desc_in, desc, *flagset->aliased & flag);
return DDS_RETCODE_BAD_PARAMETER;
}
static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict dstoff, struct flagset *flagset, uint64_t flag, const struct dd * __restrict dd, size_t * __restrict srcoff, const enum pserop * __restrict desc)
{
dds_return_t ret;
ret = deser_generic_r (dst, dstoff, flagset, flag, dd, srcoff, desc);
if (ret != 0)
{
*flagset->present &= ~flag;
*flagset->aliased &= ~flag;
return DDS_RETCODE_BAD_PARAMETER;
}
return ret;
}
dds_return_t plist_deser_generic (void * __restrict dst, const void * __restrict src, size_t srcsize, bool bswap, const enum pserop * __restrict desc)
@ -622,17 +736,19 @@ static void ser_generic_size_embeddable (size_t *dstoff, const void *src, size_t
srcoff += cnt * sizeof (*x); \
} while (0)
#define SIMPLE1(basecase_, type_) COMPLEX (basecase_, type_, *dstoff = *dstoff + sizeof (*x))
#define SIMPLE4(basecase_, type_) COMPLEX (basecase_, type_, *dstoff = align4size (*dstoff) + sizeof (*x))
#define SIMPLE4(basecase_, type_) COMPLEX (basecase_, type_, *dstoff = align4 (*dstoff) + sizeof (*x))
#define SIMPLE8(basecase_, type_) COMPLEX (basecase_, type_, *dstoff = align8 (*dstoff) + sizeof (*x))
while (true)
{
switch (*desc)
{
case XSTOP: return;
case XO: COMPLEX (XO, ddsi_octetseq_t, *dstoff = align4size (*dstoff) + 4 + x->length); break;
case XS: COMPLEX (XS, const char *, *dstoff = align4size (*dstoff) + 4 + strlen (*x) + 1); break;
case XE1: case XE2: case XE3: COMPLEX (*desc, unsigned, *dstoff = align4size (*dstoff) + 4); break;
case XO: COMPLEX (XO, ddsi_octetseq_t, *dstoff = align4 (*dstoff) + 4 + x->length); break;
case XS: COMPLEX (XS, const char *, *dstoff = align4 (*dstoff) + 4 + strlen (*x) + 1); break;
case XE1: case XE2: case XE3: COMPLEX (*desc, unsigned, *dstoff = align4 (*dstoff) + 4); break;
case Xi: case Xix2: case Xix3: case Xix4: SIMPLE4 (Xi, int32_t); break;
case Xu: case Xux2: case Xux3: case Xux4: case Xux5: SIMPLE4 (Xu, uint32_t); break;
case Xl: SIMPLE8 (Xl, int64_t); break;
case XD: case XDx2: SIMPLE4 (XD, dds_duration_t); break;
case Xo: case Xox2: SIMPLE1 (Xo, unsigned char); break;
case Xb: case Xbx2: SIMPLE1 (Xb, unsigned char); break;
@ -643,14 +759,15 @@ static void ser_generic_size_embeddable (size_t *dstoff, const void *src, size_t
COMPLEX (XbPROP, unsigned char, if (! *x) return); break;
case XQ: COMPLEX (XQ, ddsi_octetseq_t, {
const size_t elem_size = ser_generic_srcsize (desc + 1);
*dstoff = align4size (*dstoff) + 4;
*dstoff = align4 (*dstoff) + 4;
for (uint32_t i = 0; i < x->length; i++)
ser_generic_size_embeddable (dstoff, x->value, i * elem_size, desc + 1);
}); while (*++desc != XSTOP) { } break;
}); break;
case Xopt: break;
}
desc++;
desc = pserop_advance(desc);
}
#undef SIMPLE8
#undef SIMPLE4
#undef SIMPLE1
#undef COMPLEX
@ -733,6 +850,14 @@ static dds_return_t ser_generic_embeddable (char * const data, size_t *dstoff, c
srcoff += cnt * sizeof (*x);
break;
}
case Xl: { /* int64_t */
int64_t const * const x = deser_generic_src (src, &srcoff, alignof (int64_t));
int64_t * const p = ser_generic_align8 (data, dstoff);
*p = *x;
*dstoff += sizeof (*x);
srcoff += sizeof (*x);
break;
}
case XD: case XDx2: { /* duration(s): int64_t <=> int32_t.uint32_t (seconds.fraction) */
dds_duration_t const * const x = deser_generic_src (src, &srcoff, alignof (dds_duration_t));
const uint32_t cnt = 1 + (uint32_t) (*desc - XD);
@ -788,7 +913,7 @@ static dds_return_t ser_generic_embeddable (char * const data, size_t *dstoff, c
srcoff += sizeof (*x);
break;
}
case XQ: {
case XQ: { /* arbitrary sequence */
ddsi_octetseq_t const * const x = deser_generic_src (src, &srcoff, alignof (ddsi_octetseq_t));
char * const p = ser_generic_align4 (data, dstoff);
*dstoff += 4;
@ -802,13 +927,12 @@ static dds_return_t ser_generic_embeddable (char * const data, size_t *dstoff, c
ser_generic_embeddable (data, dstoff, x->value, i * elem_size, desc + 1);
}
srcoff += sizeof (*x);
while (*++desc != XSTOP) { }
break;
}
case Xopt:
break;
}
desc++;
desc = pserop_advance(desc);
}
}
@ -852,6 +976,7 @@ static dds_return_t unalias_generic (void * __restrict dst, size_t * __restrict
case XE1: case XE2: case XE3: COMPLEX (*desc, unsigned, (void) 0); break;
case Xi: case Xix2: case Xix3: case Xix4: SIMPLE (Xi, int32_t); break;
case Xu: case Xux2: case Xux3: case Xux4: case Xux5: SIMPLE (Xu, uint32_t); break;
case Xl: SIMPLE(Xl, int64_t); break;
case XD: case XDx2: SIMPLE (XD, dds_duration_t); break;
case Xo: case Xox2: SIMPLE (Xo, unsigned char); break;
case Xb: case Xbx2: SIMPLE (Xb, unsigned char); break;
@ -877,10 +1002,10 @@ static dds_return_t unalias_generic (void * __restrict dst, size_t * __restrict
size_t elem_off = i * elem_size;
unalias_generic (x->value, &elem_off, gen_seq_aliased, desc + 1);
}
}); while (*++desc != XSTOP) { } break;
}); break;
case Xopt: break;
}
desc++;
desc = pserop_advance(desc);
}
#undef SIMPLE
#undef COMPLEX
@ -915,14 +1040,14 @@ static bool fini_generic_required (const enum pserop * __restrict desc)
static dds_return_t fini_generic (void * __restrict dst, size_t * __restrict dstoff, struct flagset *flagset, uint64_t flag, const enum pserop * __restrict desc)
{
fini_generic_embeddable (dst, dstoff, desc, NULL, *flagset->aliased & flag);
(void)fini_generic_embeddable (dst, dstoff, desc, NULL, *flagset->aliased & flag);
return 0;
}
void plist_fini_generic (void * __restrict dst, const enum pserop *desc, bool aliased)
{
size_t dstoff = 0;
fini_generic_embeddable (dst, &dstoff, desc, NULL, aliased);
(void)fini_generic_embeddable (dst, &dstoff, desc, NULL, aliased);
}
static dds_return_t valid_generic (const void *src, size_t srcoff, const enum pserop * __restrict desc)
@ -945,6 +1070,7 @@ static dds_return_t valid_generic (const void *src, size_t srcoff, const enum ps
case XE1: case XE2: case XE3: SIMPLE (*desc, unsigned, *x <= 1 + (unsigned) *desc - XE1); break;
case Xi: case Xix2: case Xix3: case Xix4: TRIVIAL (Xi, int32_t); break;
case Xu: case Xux2: case Xux3: case Xux4: case Xux5: TRIVIAL (Xu, uint32_t); break;
case Xl: TRIVIAL(Xl, int64_t); break;
case XD: case XDx2: SIMPLE (XD, dds_duration_t, *x >= 0); break;
case Xo: case Xox2: TRIVIAL (Xo, unsigned char); break;
case Xb: case Xbx2: SIMPLE (Xb, unsigned char, *x == 0 || *x == 1); break;
@ -963,10 +1089,10 @@ static dds_return_t valid_generic (const void *src, size_t srcoff, const enum ps
return ret;
}
}
}); while (*++desc != XSTOP) { } break;
}); break;
case Xopt: break;
}
desc++;
desc = pserop_advance(desc);
}
#undef TRIVIAL
#undef SIMPLE
@ -1001,6 +1127,7 @@ static bool equal_generic (const void *srcx, const void *srcy, size_t srcoff, co
case XE1: case XE2: case XE3: TRIVIAL (*desc, unsigned); break;
case Xi: case Xix2: case Xix3: case Xix4: TRIVIAL (Xi, int32_t); break;
case Xu: case Xux2: case Xux3: case Xux4: case Xux5: TRIVIAL (Xu, uint32_t); break;
case Xl: TRIVIAL (Xl, int64_t); break;
case XD: case XDx2: TRIVIAL (XD, dds_duration_t); break;
case Xo: case Xox2: TRIVIAL (Xo, unsigned char); break;
case Xb: case Xbx2: TRIVIAL (Xb, unsigned char); break;
@ -1025,10 +1152,10 @@ static bool equal_generic (const void *srcx, const void *srcy, size_t srcoff, co
return false;
}
}
}); while (*++desc != XSTOP) { } break;
}); break;
case Xopt: break;
}
desc++;
desc = pserop_advance(desc);
}
#undef TRIVIAL
#undef SIMPLE

View file

@ -13,7 +13,12 @@ include(CUnit)
set(ddsi_test_sources
"plist_generic.c"
"plist.c")
"plist.c"
"mem_ser.h")
if(ENABLE_SECURITY)
set(ddsi_test_sources ${ddsi_test_sources} "security_msg.c")
endif()
add_cunit_executable(cunit_ddsi ${ddsi_test_sources})
target_include_directories(

View file

@ -0,0 +1,55 @@
/*
* Copyright(c) 2019 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#ifndef DDSI_TEST_MEM_SER_H
#define DDSI_TEST_MEM_SER_H
#include "dds/ddsrt/endian.h"
#if DDSRT_ENDIAN == DDSRT_BIG_ENDIAN
#define SER32(v) \
(unsigned char)( (uint32_t)(v) >> 24 ), \
(unsigned char)(((uint32_t)(v) >> 16) & 0xff), \
(unsigned char)(((uint32_t)(v) >> 8) & 0xff), \
(unsigned char)( (uint32_t)(v) & 0xff)
#define SER32BE(v) SER32(v)
#define SER64(v) \
(unsigned char)( (uint32_t)(v) >> 56), \
(unsigned char)(((uint32_t)(v) >> 48) & 0xff), \
(unsigned char)(((uint32_t)(v) >> 40) & 0xff), \
(unsigned char)(((uint32_t)(v) >> 32) & 0xff), \
(unsigned char)(((uint32_t)(v) >> 24) & 0xff), \
(unsigned char)(((uint32_t)(v) >> 16) & 0xff), \
(unsigned char)(((uint32_t)(v) >> 8) & 0xff), \
(unsigned char)( (uint32_t)(v) & 0xff)
#else
#define SER32(v) \
(unsigned char)( (uint32_t)(v) & 0xff), \
(unsigned char)(((uint32_t)(v) >> 8) & 0xff), \
(unsigned char)(((uint32_t)(v) >> 16) & 0xff), \
(unsigned char)( (uint32_t)(v) >> 24 )
#define SER32BE(v) \
(unsigned char)( (uint32_t)(v) >> 24 ), \
(unsigned char)(((uint32_t)(v) >> 16) & 0xff), \
(unsigned char)(((uint32_t)(v) >> 8) & 0xff), \
(unsigned char)( (uint32_t)(v) & 0xff)
#define SER64(v) \
(unsigned char)( (uint64_t)(v) & 0xff), \
(unsigned char)(((uint64_t)(v) >> 8) & 0xff), \
(unsigned char)(((uint64_t)(v) >> 16) & 0xff), \
(unsigned char)(((uint64_t)(v) >> 24) & 0xff), \
(unsigned char)(((uint64_t)(v) >> 32) & 0xff), \
(unsigned char)(((uint64_t)(v) >> 40) & 0xff), \
(unsigned char)(((uint64_t)(v) >> 48) & 0xff), \
(unsigned char)( (uint64_t)(v) >> 56)
#endif
#endif /* DDSI_TEST_MEM_SER_H */

View file

@ -15,6 +15,7 @@
#include "dds/ddsrt/endian.h"
#include "dds/ddsi/q_xqos.h"
#include "dds/ddsi/ddsi_plist_generic.h"
#include "mem_ser.h"
struct desc {
const enum pserop desc[20];
@ -33,28 +34,9 @@ struct desc_invalid {
const unsigned char *ser;
};
#if DDSRT_ENDIAN == DDSRT_BIG_ENDIAN
#define SER32(v) \
(unsigned char)((uint32_t)(v) >> 24), \
(unsigned char)(((uint32_t)(v) >> 16) & 0xff), \
(unsigned char)(((uint32_t)(v) >> 8) & 0xff), \
(unsigned char)((uint32_t)(v) & 0xff)
#define SER32BE(v) SER32(v)
#else
#define SER32(v) \
(unsigned char)((uint32_t)(v) & 0xff), \
(unsigned char)(((uint32_t)(v) >> 8) & 0xff), \
(unsigned char)(((uint32_t)(v) >> 16) & 0xff), \
(unsigned char)((uint32_t)(v) >> 24)
#define SER32BE(v) \
(unsigned char)((uint32_t)(v) >> 24), \
(unsigned char)(((uint32_t)(v) >> 16) & 0xff), \
(unsigned char)(((uint32_t)(v) >> 8) & 0xff), \
(unsigned char)((uint32_t)(v) & 0xff)
#endif
typedef unsigned char raw[];
typedef uint32_t raw32[];
typedef uint64_t raw64[];
typedef ddsi_octetseq_t oseq;
struct desc descs[] = {
@ -75,6 +57,7 @@ struct desc descs[] = {
{ {Xux3,XSTOP}, (raw32){4,5,6}, 12, (raw){SER32(4), SER32(5), SER32(6)} },
{ {Xux4,XSTOP}, (raw32){7,8,9,10}, 16, (raw){SER32(7), SER32(8), SER32(9), SER32(10)} },
{ {Xux5,XSTOP}, (raw32){7,8,9,10,11}, 20, (raw){SER32(7), SER32(8), SER32(9), SER32(10), SER32(11)} },
{ {Xl,XSTOP}, (raw64){123456789}, 8, (raw){SER64(123456789)} },
{ {XD,XSTOP}, (uint64_t[]){314159265358979324},
/* note: fractional part depends on rounding rule used for converting nanoseconds to NTP time
Cyclone currently rounds up, so we have to do that too */
@ -94,6 +77,46 @@ struct desc descs[] = {
7, (raw){SER32(3), 1,2,3} },
{ {XQ,XS,XSTOP,XSTOP}, &(ddsi_stringseq_t){2, (char*[]){"tree","flower"}},
27, (raw){SER32(2), SER32(5),'t','r','e','e',0, 0,0,0, SER32(7), 'f','l','o','w','e','r',0} },
{ {Xo,Xl,Xo,Xu,Xo,XSTOP},
&(struct{unsigned char a;int64_t b;unsigned char c;uint32_t d;unsigned char e;}){ 1, 2, 3, 4, 5 },
25, (raw){1,0,0,0,0,0,0,0,SER64(2),3,0,0,0,SER32(4),5} },
{ {Xo,XQ,Xo,Xu,Xo,XSTOP,Xo,XSTOP},
&(struct{uint8_t b; oseq seq; uint8_t c;})
{1, {2, (unsigned char *)(struct{uint8_t a; uint32_t b; uint8_t c;}[])
{ {0x10, 0x11, 0x12},
{0x21, 0x22, 0x23} },
}, 0x42 },
26,
(raw){1, /* pad */0,0,0, SER32(2),
0x10, /* pad */0,0,0, SER32(0x11), 0x12,
0x21, /* pad */0,0, SER32(0x22), 0x23,
0x42}
},
{ {Xo,XQ,Xo,Xl,Xo,XSTOP,Xo,XSTOP},
&(struct{uint8_t b; oseq seq; uint8_t c;})
{1, {2, (unsigned char *)(struct{uint8_t a; int64_t b; uint8_t c;}[])
{ {0x10, 0x11, 0x12},
{0x21, 0x22, 0x23} },
}, 0x42 },
42,
(raw){1, /* pad */0,0,0, SER32(2),
0x10, /* pad */0,0,0,0,0,0,0, SER64(0x11), 0x12,
0x21, /* pad */0,0,0,0,0,0, SER64(0x22), 0x23,
0x42}
},
{ {Xo,XQ,Xo,Xo,XQ,Xo,XSTOP,XSTOP,Xo,XSTOP},
&(struct{uint8_t b; oseq seq; uint8_t c;})
{1, {2, (unsigned char *)(struct{uint8_t a; uint8_t b; oseq seq;}[])
{ {0x10, 0x11, { 3, (unsigned char *)(struct{uint8_t a;}[]){ {'a'}, {'b'}, {'c'}}}},
{0x21, 0x22, { 2, (unsigned char *)(struct{uint8_t a;}[]){ {'o'}, {'p'}}}}
},
}, 0x42 },
31,
(raw){1, /* pad */0,0,0, SER32(2),
0x10, 0x11, /* pad */0,0, SER32(3), 'a','b','c',
0x21, 0x22, /* pad */0,0,0, SER32(2), 'o','p',
0x42}
},
{ {Xb,XQ,XbPROP,XS,Xo,XSTOP,XSTOP},
&(struct{char b; oseq seq;}){1, {5, (unsigned char *)(struct{char b;char *s;uint8_t o;}[]){
{0,"apple",1}, {1,"orange",2}, {0,"cherry",3}, {1,"fig",4}, {1,"prune",5}}}},
@ -240,7 +263,8 @@ struct desc_invalid descs_invalid[] = {
SER32(7), 'o','r','a','n','g','e',0, 2,
SER32(4), 'f','i','g',0, 4, 0,0,0,
SER32(7), 'p','r','u','n','e',0, 5 // string not terminated
} }
} },
{ {XQ,XQ,Xu,XSTOP,XSTOP}, 16, (raw){SER32(2),SER32(1),SER32(31415),SER32(3)} } // nested sequence failure
};
CU_Test (ddsi_plist_generic, invalid_input)

View file

@ -0,0 +1,328 @@
/*
* Copyright(c) 2019 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include "CUnit/Theory.h"
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/string.h"
#include "dds/ddsi/ddsi_security_msg.h"
#include "mem_ser.h"
static nn_participant_generic_message_t test_msg_in =
{
.message_identity = { {{.u={1,2,3}},{4}}, 5 },
.related_message_identity = { {{.u={5,4,3}},{2}}, 1 },
.destinaton_participant_guid = { {.u={2,3,4}},{5} },
.destination_endpoint_guid = { {.u={3,4,5}},{6} },
.source_endpoint_guid = { {.u={4,5,6}},{7} },
.message_class_id = "testing message",
.message_data = {
.n = 4,
.tags = (nn_dataholder_t[]) {
{
.class_id = "holder0",
.properties = {
.n = 3,
.props = (dds_property_t[]) {
{
.propagate = false,
.name = "holder0::prop0name",
.value = "holder0::prop0value",
},
{
.propagate = true,
.name = "holder0::prop1name",
.value = "holder0::prop1value",
},
{
.propagate = false,
.name = "holder0::prop2name",
.value = "holder0::prop2value",
},
}
},
.binary_properties = {
.n = 1,
.props = (dds_binaryproperty_t[]) {
{
.propagate = false,
.name = "holder0::bprop0name",
.value = { 2, (unsigned char[]){ 1, 2 } },
},
}
},
},
{
.class_id = "holder1",
.properties = {
.n = 1,
.props = (dds_property_t[]) {
{
.propagate = true,
.name = "holder1::prop0name",
.value = "holder1::prop0value",
},
}
},
.binary_properties = {
.n = 1,
.props = (dds_binaryproperty_t[]) {
{
.propagate = true,
.name = "holder1::bprop0name",
.value = { 3, (unsigned char[]){ 1, 2, 3 } },
},
}
},
},
{
.class_id = "holder2",
.properties = {
.n = 1,
.props = (dds_property_t[]) {
{
.propagate = false,
.name = "holder2::prop0name",
.value = "holder2::prop0value",
},
}
},
.binary_properties = {
.n = 3,
.props = (dds_binaryproperty_t[]) {
{
.propagate = true,
.name = "holder2::bprop0name",
.value = { 3, (unsigned char[]){ 1, 2, 3 } },
},
{
.propagate = false,
.name = "holder2::bprop1name",
.value = { 4, (unsigned char[]){ 1, 2, 3, 4 } },
},
{
.propagate = true,
.name = "holder2::bprop2name",
.value = { 5, (unsigned char[]){ 1, 2, 3, 4, 5 } },
},
}
},
},
{
.class_id = "holder3",
.properties = {
.n = 1,
.props = (dds_property_t[]) {
{
.propagate = false,
.name = "holder3::prop0name",
.value = "holder3::prop0value",
},
}
},
.binary_properties = {
.n = 1,
.props = (dds_binaryproperty_t[]) {
{
.propagate = false,
.name = "holder3::bprop0name",
.value = { 3, (unsigned char[]){ 1, 2, 3 } },
},
}
},
},
},
},
};
/* Same as test_msg_in, excluding the non-propagated properties. */
static nn_participant_generic_message_t test_msg_out =
{
.message_identity = { {{.u={1,2,3}},{4}}, 5 },
.related_message_identity = { {{.u={5,4,3}},{2}}, 1 },
.destinaton_participant_guid = { {.u={2,3,4}},{5} },
.destination_endpoint_guid = { {.u={3,4,5}},{6} },
.source_endpoint_guid = { {.u={4,5,6}},{7} },
.message_class_id = "testing message",
.message_data = {
.n = 4,
.tags = (nn_dataholder_t[]) {
{
.class_id = "holder0",
.properties = {
.n = 1,
.props = (dds_property_t[]) {
{
.propagate = true,
.name = "holder0::prop1name",
.value = "holder0::prop1value",
},
}
},
.binary_properties = {
.n = 0,
.props = NULL
},
},
{
.class_id = "holder1",
.properties = {
.n = 1,
.props = (dds_property_t[]) {
{
.propagate = true,
.name = "holder1::prop0name",
.value = "holder1::prop0value",
},
}
},
.binary_properties = {
.n = 1,
.props = (dds_binaryproperty_t[]) {
{
.propagate = true,
.name = "holder1::bprop0name",
.value = { 3, (unsigned char[]){ 1, 2, 3 } },
},
}
},
},
{
.class_id = "holder2",
.properties = {
.n = 0,
.props = NULL,
},
.binary_properties = {
.n = 2,
.props = (dds_binaryproperty_t[]) {
{
.propagate = true,
.name = "holder2::bprop0name",
.value = { 3, (unsigned char[]){ 1, 2, 3 } },
},
{
.propagate = true,
.name = "holder2::bprop2name",
.value = { 5, (unsigned char[]){ 1, 2, 3, 4, 5 } },
},
}
},
},
{
.class_id = "holder3",
.properties = {
.n = 0,
.props = NULL,
},
.binary_properties = {
.n = 0,
.props = NULL,
},
},
},
},
};
/* The cdr of test_msg_out. */
static unsigned char test_msg_ser[] = {
SER32BE(1), SER32BE(2), SER32BE(3), SER32BE(4), SER64(5),
SER32BE(5), SER32BE(4), SER32BE(3), SER32BE(2), SER64(1),
SER32BE(2), SER32BE(3), SER32BE(4), SER32BE(5),
SER32BE(3), SER32BE(4), SER32BE(5), SER32BE(6),
SER32BE(4), SER32BE(5), SER32BE(6), SER32BE(7),
SER32(16), 't','e','s','t','i','n','g',' ','m','e','s','s','a','g','e',0,
SER32(4),
/* dataholder 0 */
SER32(8), 'h','o','l','d','e','r','0',0,
SER32(1),
SER32(19), 'h','o','l','d','e','r','0',':',':','p','r','o','p','1','n','a','m','e',0,/* pad */0,
SER32(20), 'h','o','l','d','e','r','0',':',':','p','r','o','p','1','v','a','l','u','e',0,
SER32(0),
/* dataholder 1 */
SER32(8), 'h','o','l','d','e','r','1',0,
SER32(1),
SER32(19), 'h','o','l','d','e','r','1',':',':','p','r','o','p','0','n','a','m','e',0,/* pad */0,
SER32(20), 'h','o','l','d','e','r','1',':',':','p','r','o','p','0','v','a','l','u','e',0,
SER32(1),
SER32(20), 'h','o','l','d','e','r','1',':',':','b','p','r','o','p','0','n','a','m','e',0,
SER32(3), 1,2,3, /* pad */0,
/* dataholder 2 */
SER32(8), 'h','o','l','d','e','r','2',0,
SER32(0),
SER32(2),
SER32(20), 'h','o','l','d','e','r','2',':',':','b','p','r','o','p','0','n','a','m','e',0,
SER32(3), 1,2,3, /* pad */0,
SER32(20), 'h','o','l','d','e','r','2',':',':','b','p','r','o','p','2','n','a','m','e',0,
SER32(5), 1,2,3,4,5, /* pad */0,0,0,
/* dataholder 2 */
SER32(8), 'h','o','l','d','e','r','3',0,
SER32(0),
SER32(0)
};
CU_Test (ddsi_security_msg, serializer)
{
nn_participant_generic_message_t msg_in;
nn_participant_generic_message_t msg_ser;
unsigned char *data = NULL;
dds_return_t ret;
size_t len;
bool equal;
/* Create the message (normally with various arguments). */
nn_participant_generic_message_init(
&msg_in,
&test_msg_in.message_identity.source_guid,
test_msg_in.message_identity.sequence_number,
&test_msg_in.destinaton_participant_guid,
&test_msg_in.destination_endpoint_guid,
&test_msg_in.source_endpoint_guid,
test_msg_in.message_class_id,
&test_msg_in.message_data,
&test_msg_in.related_message_identity);
/* Check creation result. */
equal = plist_equal_generic(&msg_in, &test_msg_in, pserop_participant_generic_message);
CU_ASSERT_FATAL(equal == true);
/* Serialize the message. */
ret = nn_participant_generic_message_serialize(&msg_in, &data, &len);
CU_ASSERT_FATAL (ret == DDS_RETCODE_OK);
CU_ASSERT_PTR_NOT_NULL_FATAL(data);
CU_ASSERT(len > 0);
/* Check serialization result. */
size_t cmpsize = (len < sizeof(test_msg_ser)) ? len : sizeof(test_msg_ser);
if (memcmp (data, test_msg_ser, cmpsize) != 0)
{
printf ("memcmp(%d)\n", (int)cmpsize);
for (size_t k = 0; k < cmpsize; k++)
printf (" %3zu %02x %02x (%c) %s\n", k, data[k], test_msg_ser[k],
((test_msg_ser[k] >= '0') && (test_msg_ser[k] <= 'z')) ? test_msg_ser[k] : ' ',
(data[k] == test_msg_ser[k]) ? "" : "<--");
CU_ASSERT (!(bool)"memcmp");
}
CU_ASSERT_FATAL (len == sizeof(test_msg_ser));
/* Deserialize the message. */
ret = nn_participant_generic_message_deseralize(&msg_ser, data, len, false);
CU_ASSERT_FATAL (ret == DDS_RETCODE_OK);
/* Check deserialization result. */
equal = plist_equal_generic(&msg_ser, &test_msg_out, pserop_participant_generic_message);
CU_ASSERT_FATAL(equal == true);
/* Cleanup. */
nn_participant_generic_message_deinit(&msg_in);
nn_participant_generic_message_deinit(&msg_ser);
ddsrt_free(data);
}