Initial contribution
This commit is contained in:
parent
7b5cc4fa59
commit
11d9ce37aa
580 changed files with 155133 additions and 162 deletions
32
src/core/ddsc/.fileids
Normal file
32
src/core/ddsc/.fileids
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# ddsc sources
|
||||
40 src/dds_alloc.c
|
||||
41 src/dds_coherent.c
|
||||
42 src/dds_iid.c
|
||||
43 src/dds_participant.c
|
||||
44 src/dds_reader.c
|
||||
45 src/dds_thread.c
|
||||
46 src/dds_writer.c
|
||||
47 src/dds_init.c
|
||||
48 src/dds_publisher.c
|
||||
49 src/dds_rhc.c
|
||||
50 src/dds_time.c
|
||||
51 src/q_osplser.c
|
||||
52 src/dds_domain.c
|
||||
53 src/dds_instance.c
|
||||
54 src/dds_qos.c
|
||||
55 src/dds_tkmap.c
|
||||
56 src/dds_entity.c
|
||||
57 src/dds_key.c
|
||||
58 src/dds_querycond.c
|
||||
59 src/dds_topic.c
|
||||
60 src/dds_err.c
|
||||
61 src/dds_listener.c
|
||||
62 src/dds_read.c
|
||||
63 src/dds_stream.c
|
||||
64 src/dds_waitset.c
|
||||
65 src/dds_log.c
|
||||
66 src/dds_readcond.c
|
||||
67 src/dds_subscriber.c
|
||||
68 src/dds_write.c
|
||||
69 src/dds_report.c
|
||||
70 src/dds_builtin.c
|
||||
146
src/core/ddsc/CMakeLists.txt
Normal file
146
src/core/ddsc/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
#
|
||||
# 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
|
||||
#
|
||||
PREPEND(srcs_ddsc "${CMAKE_CURRENT_LIST_DIR}/src"
|
||||
dds_alloc.c
|
||||
dds_builtin.c
|
||||
dds_coherent.c
|
||||
dds_iid.c
|
||||
dds_participant.c
|
||||
dds_reader.c
|
||||
dds_writer.c
|
||||
dds_init.c
|
||||
dds_publisher.c
|
||||
dds_rhc.c
|
||||
dds_time.c
|
||||
q_osplser.c
|
||||
dds_domain.c
|
||||
dds_instance.c
|
||||
dds_qos.c
|
||||
dds_tkmap.c
|
||||
dds_entity.c
|
||||
dds_key.c
|
||||
dds_querycond.c
|
||||
dds_topic.c
|
||||
dds_report.c
|
||||
dds_err.c
|
||||
dds_listener.c
|
||||
dds_read.c
|
||||
dds_stream.c
|
||||
dds_waitset.c
|
||||
dds_log.c
|
||||
dds_readcond.c
|
||||
dds_subscriber.c
|
||||
dds_write.c
|
||||
)
|
||||
|
||||
PREPEND(hdrs_public_ddsc "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include/ddsc>$<INSTALL_INTERFACE:include/ddsc>"
|
||||
dds.h
|
||||
dds_public_error.h
|
||||
dds_public_impl.h
|
||||
dds_public_listener.h
|
||||
dds_public_log.h
|
||||
dds_public_qos.h
|
||||
dds_public_status.h
|
||||
dds_public_stream.h
|
||||
dds_public_time.h
|
||||
)
|
||||
|
||||
PREPEND(hdrs_private_ddsc "${CMAKE_CURRENT_LIST_DIR}/src"
|
||||
dds__alloc.h
|
||||
dds__builtin.h
|
||||
dds__domain.h
|
||||
dds__entity.h
|
||||
dds__iid.h
|
||||
dds__init.h
|
||||
dds__key.h
|
||||
dds__listener.h
|
||||
dds__participant.h
|
||||
dds__publisher.h
|
||||
dds__qos.h
|
||||
dds__querycond.h
|
||||
dds__readcond.h
|
||||
dds__reader.h
|
||||
dds__report.h
|
||||
dds__rhc.h
|
||||
dds__stream.h
|
||||
dds__subscriber.h
|
||||
dds__tkmap.h
|
||||
dds__topic.h
|
||||
dds__types.h
|
||||
dds__write.h
|
||||
dds__writer.h
|
||||
q__osplser.h
|
||||
)
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake/ddsc_project.h.in"
|
||||
"include/ddsc/ddsc_project.h")
|
||||
|
||||
generate_export_header(
|
||||
ddsc
|
||||
BASE_NAME DDS
|
||||
EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/include/ddsc/dds_export.h"
|
||||
)
|
||||
|
||||
target_include_directories(ddsc
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>")
|
||||
|
||||
# Generate builtin-topic sources
|
||||
set(IDLC_ARGS "-dll" "FOO,ddsc/dds_export.h")
|
||||
idlc_generate(BuiltinTypes ddsc/src/dds_dcps_builtintopics.idl ddsc/src/dds_builtinTopics.idl)
|
||||
set(IDLC_ARGS)
|
||||
target_link_libraries(ddsc PRIVATE BuiltinTypes)
|
||||
|
||||
target_include_directories(ddsc
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")
|
||||
|
||||
target_sources(ddsc
|
||||
PRIVATE
|
||||
${srcs_ddsc}
|
||||
${hdrs_private_ddsc}
|
||||
"include/ddsc/ddsc_project.h"
|
||||
PUBLIC
|
||||
${hdrs_public_ddsc}
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>$<INSTALL_INTERFACE:include>/ddsc/dds_export.h"
|
||||
)
|
||||
|
||||
target_include_directories(ddsc
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/../security/include>"
|
||||
PRIVATE
|
||||
"${CMAKE_CURRENT_LIST_DIR}/src")
|
||||
|
||||
install(
|
||||
DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/include/ddsc"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
COMPONENT dev)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/include/ddsc/dds_export.h"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/ddsc"
|
||||
COMPONENT dev)
|
||||
|
||||
install(
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/dds_dcps_builtintopics.h"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/dds_builtinTopics.h"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/ddsc"
|
||||
COMPONENT dev)
|
||||
|
||||
# TODO: improve test inclusion.
|
||||
if((BUILD_TESTING) AND ((NOT DEFINED MSVC_VERSION) OR (MSVC_VERSION GREATER "1800")))
|
||||
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/tests")
|
||||
endif()
|
||||
|
||||
25
src/core/ddsc/cmake/ddsc_project.h.in
Normal file
25
src/core/ddsc/cmake/ddsc_project.h.in
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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 DDSC_PROJECT_H
|
||||
#define DDSC_PROJECT_H
|
||||
|
||||
#define DDSC_VERSION "@CycloneDDS_VERSION@"
|
||||
#define DDSC_VERSION_MAJOR @CycloneDDS_VERSION_MAJOR@
|
||||
#define DDSC_VERSION_MINOR @CycloneDDS_VERSION_MINOR@
|
||||
#define DDSC_VERSION_PATCH @CycloneDDS_VERSION_PATCH@
|
||||
#define DDSC_VERSION_TWEAK @CycloneDDS_VERSION_TWEAK@
|
||||
#define DDSC_PROJECT_NAME_NOSPACE_CAPS "@CMAKE_PROJECT_NAME_CAPS@"
|
||||
#define DDSC_PROJECT_NAME_NOSPACE_SMALL "@CMAKE_PROJECT_NAME_SMALL@"
|
||||
#define DDSC_PROJECT_NAME_NOSPACE "@CMAKE_PROJECT_NAME@"
|
||||
#define DDSC_PROJECT_NAME "@CMAKE_PROJECT_NAME@"
|
||||
|
||||
#endif /* DDSC_PROJECT_H */
|
||||
3144
src/core/ddsc/include/ddsc/dds.h
Normal file
3144
src/core/ddsc/include/ddsc/dds.h
Normal file
File diff suppressed because it is too large
Load diff
87
src/core/ddsc/include/ddsc/dds_public_alloc.h
Normal file
87
src/core/ddsc/include/ddsc/dds_public_alloc.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
/* TODO: do we really need to expose this as an API? */
|
||||
|
||||
/** @file
|
||||
*
|
||||
* @brief DDS C Allocation API
|
||||
*
|
||||
* This header file defines the public API of allocation convenience functions
|
||||
* in the CycloneDDS C language binding.
|
||||
*/
|
||||
#ifndef DDS_ALLOC_H
|
||||
#define DDS_ALLOC_H
|
||||
|
||||
#include "os/os_public.h"
|
||||
#include "ddsc/dds_export.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct dds_topic_descriptor;
|
||||
struct dds_sequence;
|
||||
|
||||
#define DDS_FREE_KEY_BIT 0x01
|
||||
#define DDS_FREE_CONTENTS_BIT 0x02
|
||||
#define DDS_FREE_ALL_BIT 0x04
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DDS_FREE_ALL = DDS_FREE_KEY_BIT | DDS_FREE_CONTENTS_BIT | DDS_FREE_ALL_BIT,
|
||||
DDS_FREE_CONTENTS = DDS_FREE_KEY_BIT | DDS_FREE_CONTENTS_BIT,
|
||||
DDS_FREE_KEY = DDS_FREE_KEY_BIT
|
||||
}
|
||||
dds_free_op_t;
|
||||
|
||||
typedef struct dds_allocator
|
||||
{
|
||||
/* Behaviour as C library malloc, realloc and free */
|
||||
|
||||
void * (*malloc) (size_t size);
|
||||
void * (*realloc) (void *ptr, size_t size); /* if needed */
|
||||
void (*free) (void *ptr);
|
||||
}
|
||||
dds_allocator_t;
|
||||
|
||||
DDS_EXPORT void dds_set_allocator (const dds_allocator_t * __restrict n, dds_allocator_t * __restrict o);
|
||||
|
||||
typedef struct dds_aligned_allocator
|
||||
{
|
||||
/* size is a multiple of align, align is a power of 2 no less than
|
||||
the machine's page size, returned pointer MUST be aligned to at
|
||||
least align. */
|
||||
void * (*alloc) (size_t size, size_t align);
|
||||
void (*free) (size_t size, void *ptr);
|
||||
}
|
||||
dds_aligned_allocator_t;
|
||||
|
||||
DDS_EXPORT void dds_set_aligned_allocator (const dds_aligned_allocator_t * __restrict n, dds_aligned_allocator_t * __restrict o);
|
||||
|
||||
DDS_EXPORT void * dds_alloc (size_t size);
|
||||
DDS_EXPORT void * dds_realloc (void * ptr, size_t size);
|
||||
DDS_EXPORT void * dds_realloc_zero (void * ptr, size_t size);
|
||||
DDS_EXPORT void dds_free (void * ptr);
|
||||
|
||||
typedef void * (*dds_alloc_fn_t) (size_t);
|
||||
typedef void * (*dds_realloc_fn_t) (void *, size_t);
|
||||
typedef void (*dds_free_fn_t) (void *);
|
||||
|
||||
DDS_EXPORT char * dds_string_alloc (size_t size);
|
||||
DDS_EXPORT char * dds_string_dup (const char * str);
|
||||
DDS_EXPORT void dds_string_free (char * str);
|
||||
DDS_EXPORT void dds_sample_free (void * sample, const struct dds_topic_descriptor * desc, dds_free_op_t op);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
155
src/core/ddsc/include/ddsc/dds_public_error.h
Normal file
155
src/core/ddsc/include/ddsc/dds_public_error.h
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/** @file
|
||||
*
|
||||
* @brief DDS C Error API
|
||||
*
|
||||
* This header file defines the public API of error values and convenience
|
||||
* functions in the CycloneDDS C language binding.
|
||||
*/
|
||||
#ifndef DDS_ERROR_H
|
||||
#define DDS_ERROR_H
|
||||
|
||||
#include "os/os_public.h"
|
||||
#include "ddsc/dds_export.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Error masks for returned status values */
|
||||
|
||||
#define DDS_ERR_NR_MASK 0x000000ff
|
||||
#define DDS_ERR_LINE_MASK 0x003fff00
|
||||
#define DDS_ERR_FILE_ID_MASK 0x7fc00000
|
||||
|
||||
|
||||
/*
|
||||
State is unchanged following a function call returning an error
|
||||
other than UNSPECIFIED, OUT_OF_RESOURCES and ALREADY_DELETED.
|
||||
|
||||
Error handling functions. Three components to returned int status value.
|
||||
|
||||
1 - The DDS_ERR_xxx error number
|
||||
2 - The file identifier
|
||||
3 - The line number
|
||||
|
||||
All functions return >= 0 on success, < 0 on error
|
||||
*/
|
||||
/** @name Return codes
|
||||
@{**/
|
||||
#define DDS_RETCODE_OK 0 /**< Success */
|
||||
#define DDS_RETCODE_ERROR 1 /**< Non specific error */
|
||||
#define DDS_RETCODE_UNSUPPORTED 2 /**< Feature unsupported */
|
||||
#define DDS_RETCODE_BAD_PARAMETER 3 /**< Bad parameter value */
|
||||
#define DDS_RETCODE_PRECONDITION_NOT_MET 4 /**< Precondition for operation not met */
|
||||
#define DDS_RETCODE_OUT_OF_RESOURCES 5 /**< When an operation fails because of a lack of resources */
|
||||
#define DDS_RETCODE_NOT_ENABLED 6 /**< When a configurable feature is not enabled */
|
||||
#define DDS_RETCODE_IMMUTABLE_POLICY 7 /**< When an attempt is made to modify an immutable policy */
|
||||
#define DDS_RETCODE_INCONSISTENT_POLICY 8 /**< When a policy is used with inconsistent values */
|
||||
#define DDS_RETCODE_ALREADY_DELETED 9 /**< When an attempt is made to delete something more than once */
|
||||
#define DDS_RETCODE_TIMEOUT 10 /**< When a timeout has occurred */
|
||||
#define DDS_RETCODE_NO_DATA 11 /**< When expected data is not provided */
|
||||
#define DDS_RETCODE_ILLEGAL_OPERATION 12 /**< When a function is called when it should not be */
|
||||
#define DDS_RETCODE_NOT_ALLOWED_BY_SECURITY 13 /**< When credentials are not enough to use the function */
|
||||
|
||||
|
||||
/** @}*/
|
||||
|
||||
/* For backwards compatability */
|
||||
|
||||
#define DDS_SUCCESS DDS_RETCODE_OK
|
||||
|
||||
/** @name DDS_Error_Type
|
||||
@{**/
|
||||
#define DDS_CHECK_REPORT 0x01
|
||||
#define DDS_CHECK_FAIL 0x02
|
||||
#define DDS_CHECK_EXIT 0x04
|
||||
/** @}*/
|
||||
|
||||
/* Error code handling functions */
|
||||
|
||||
/** @name Macros for error handling
|
||||
@{**/
|
||||
#define DDS_TO_STRING(n) #n
|
||||
#define DDS_INT_TO_STRING(n) DDS_TO_STRING(n)
|
||||
/** @}*/
|
||||
|
||||
/** Macro to extract error number */
|
||||
#define dds_err_nr(e) ((-(e)) & DDS_ERR_NR_MASK)
|
||||
|
||||
/** Macro to extract line number */
|
||||
#define dds_err_line(e) (((-(e)) & DDS_ERR_LINE_MASK) >> 8)
|
||||
|
||||
/** Macro to extract file identifier */
|
||||
#define dds_err_file_id(e) (((-(e)) & DDS_ERR_FILE_ID_MASK) >> 22)
|
||||
|
||||
/**
|
||||
* @brief Takes the error value and outputs a string corresponding to it.
|
||||
*
|
||||
* @param[in] err Error value to be converted to a string
|
||||
* @returns String corresponding to the error value
|
||||
*/
|
||||
DDS_EXPORT const char * dds_err_str (dds_return_t err);
|
||||
|
||||
/**
|
||||
* @brief Takes the error number, error type and filename and line number and formats it to
|
||||
* a string which can be used for debugging.
|
||||
*
|
||||
* @param[in] err Error value
|
||||
* @param[in] flags Indicates Fail, Exit or Report
|
||||
* @param[in] where File and line number
|
||||
* @returns true - True
|
||||
* @returns false - False
|
||||
*/
|
||||
|
||||
DDS_EXPORT bool dds_err_check (dds_return_t err, unsigned flags, const char * where);
|
||||
|
||||
/** Macro that defines dds_err_check function */
|
||||
#define DDS_ERR_CHECK(e, f) (dds_err_check ((e), (f), __FILE__ ":" DDS_INT_TO_STRING(__LINE__)))
|
||||
|
||||
/* Failure handling */
|
||||
|
||||
/** Failure handler */
|
||||
typedef void (*dds_fail_fn) (const char *, const char *);
|
||||
|
||||
/** Macro that defines dds_fail function */
|
||||
#define DDS_FAIL(m) (dds_fail (m, __FILE__ ":" DDS_INT_TO_STRING (__LINE__)))
|
||||
|
||||
/**
|
||||
* @brief Set the failure function
|
||||
*
|
||||
* @param[in] fn Function to invoke on failure
|
||||
*/
|
||||
DDS_EXPORT void dds_fail_set (dds_fail_fn fn);
|
||||
|
||||
/**
|
||||
* @brief Get the failure function
|
||||
*
|
||||
* @returns Failure function
|
||||
*/
|
||||
DDS_EXPORT dds_fail_fn dds_fail_get (void);
|
||||
|
||||
/**
|
||||
* @brief Handles failure through an installed failure handler
|
||||
*
|
||||
* @params[in] msg String containing failure message
|
||||
* @params[in] where String containing file and location
|
||||
*/
|
||||
DDS_EXPORT void dds_fail (const char * msg, const char * where);
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
210
src/core/ddsc/include/ddsc/dds_public_impl.h
Normal file
210
src/core/ddsc/include/ddsc/dds_public_impl.h
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
/* TODO: do we really need to expose all of this as an API? maybe some, but all? */
|
||||
|
||||
/** @file
|
||||
*
|
||||
* @brief DDS C Implementation API
|
||||
*
|
||||
* This header file defines the public API for all kinds of things in the
|
||||
* CycloneDDS C language binding.
|
||||
*/
|
||||
#ifndef DDS_IMPL_H
|
||||
#define DDS_IMPL_H
|
||||
|
||||
#include "ddsc/dds_public_alloc.h"
|
||||
#include "ddsc/dds_public_stream.h"
|
||||
#include "os/os_public.h"
|
||||
#include "ddsc/dds_export.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct dds_sequence
|
||||
{
|
||||
uint32_t _maximum;
|
||||
uint32_t _length;
|
||||
uint8_t * _buffer;
|
||||
bool _release;
|
||||
}
|
||||
dds_sequence_t;
|
||||
|
||||
#define DDS_LENGTH_UNLIMITED -1
|
||||
|
||||
typedef struct dds_key_descriptor
|
||||
{
|
||||
const char * m_name;
|
||||
uint32_t m_index;
|
||||
}
|
||||
dds_key_descriptor_t;
|
||||
|
||||
/*
|
||||
Topic definitions are output by a preprocessor and have an
|
||||
implementation-private definition. The only thing exposed on the
|
||||
API is a pointer to the "topic_descriptor_t" struct type.
|
||||
*/
|
||||
|
||||
typedef struct dds_topic_descriptor
|
||||
{
|
||||
const size_t m_size; /* Size of topic type */
|
||||
const uint32_t m_align; /* Alignment of topic type */
|
||||
const uint32_t m_flagset; /* Flags */
|
||||
const uint32_t m_nkeys; /* Number of keys (can be 0) */
|
||||
const char * m_typename; /* Type name */
|
||||
const dds_key_descriptor_t * m_keys; /* Key descriptors (NULL iff m_nkeys 0) */
|
||||
const uint32_t m_nops; /* Number of ops in m_ops */
|
||||
const uint32_t * m_ops; /* Marshalling meta data */
|
||||
const char * m_meta; /* XML topic description meta data */
|
||||
}
|
||||
dds_topic_descriptor_t;
|
||||
|
||||
/* Topic descriptor flag values */
|
||||
|
||||
#define DDS_TOPIC_NO_OPTIMIZE 0x0001
|
||||
#define DDS_TOPIC_FIXED_KEY 0x0002
|
||||
|
||||
/*
|
||||
Masks for read condition, read, take: there is only one mask here,
|
||||
which combines the sample, view and instance states.
|
||||
*/
|
||||
|
||||
#define DDS_READ_SAMPLE_STATE 1u
|
||||
#define DDS_NOT_READ_SAMPLE_STATE 2u
|
||||
#define DDS_ANY_SAMPLE_STATE (1u | 2u)
|
||||
|
||||
#define DDS_NEW_VIEW_STATE 4u
|
||||
#define DDS_NOT_NEW_VIEW_STATE 8u
|
||||
#define DDS_ANY_VIEW_STATE (4u | 8u)
|
||||
|
||||
#define DDS_ALIVE_INSTANCE_STATE 16u
|
||||
#define DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE 32u
|
||||
#define DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE 64u
|
||||
#define DDS_ANY_INSTANCE_STATE (16u | 32u | 64u)
|
||||
|
||||
#define DDS_ANY_STATE (DDS_ANY_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE)
|
||||
|
||||
#define DDS_DOMAIN_DEFAULT -1
|
||||
#define DDS_HANDLE_NIL 0
|
||||
#define DDS_ENTITY_NIL 0
|
||||
|
||||
#define DDS_ENTITY_KIND_MASK (0x7F000000) /* Should be same as UT_HANDLE_KIND_MASK. */
|
||||
typedef enum dds_entity_kind
|
||||
{
|
||||
DDS_KIND_DONTCARE = 0x00000000,
|
||||
DDS_KIND_TOPIC = 0x01000000,
|
||||
DDS_KIND_PARTICIPANT = 0x02000000,
|
||||
DDS_KIND_READER = 0x03000000,
|
||||
DDS_KIND_WRITER = 0x04000000,
|
||||
DDS_KIND_SUBSCRIBER = 0x05000000,
|
||||
DDS_KIND_PUBLISHER = 0x06000000,
|
||||
DDS_KIND_COND_READ = 0x07000000,
|
||||
DDS_KIND_COND_QUERY = 0x08000000,
|
||||
DDS_KIND_WAITSET = 0x09000000,
|
||||
DDS_KIND_INTERNAL = 0x0A000000,
|
||||
}
|
||||
dds_entity_kind_t;
|
||||
|
||||
/* Handles are opaque pointers to implementation types */
|
||||
typedef uint64_t dds_instance_handle_t;
|
||||
typedef int32_t dds_domainid_t;
|
||||
|
||||
|
||||
/* Topic encoding instruction types */
|
||||
|
||||
#define DDS_OP_RTS 0x00000000
|
||||
#define DDS_OP_ADR 0x01000000
|
||||
#define DDS_OP_JSR 0x02000000
|
||||
#define DDS_OP_JEQ 0x03000000
|
||||
|
||||
/* Core type flags
|
||||
|
||||
1BY : One byte simple type
|
||||
2BY : Two byte simple type
|
||||
4BY : Four byte simple type
|
||||
8BY : Eight byte simple type
|
||||
STR : String
|
||||
BST : Bounded string
|
||||
SEQ : Sequence
|
||||
ARR : Array
|
||||
UNI : Union
|
||||
STU : Struct
|
||||
*/
|
||||
|
||||
#define DDS_OP_VAL_1BY 0x01
|
||||
#define DDS_OP_VAL_2BY 0x02
|
||||
#define DDS_OP_VAL_4BY 0x03
|
||||
#define DDS_OP_VAL_8BY 0x04
|
||||
#define DDS_OP_VAL_STR 0x05
|
||||
#define DDS_OP_VAL_BST 0x06
|
||||
#define DDS_OP_VAL_SEQ 0x07
|
||||
#define DDS_OP_VAL_ARR 0x08
|
||||
#define DDS_OP_VAL_UNI 0x09
|
||||
#define DDS_OP_VAL_STU 0x0a
|
||||
|
||||
#define DDS_OP_TYPE_1BY (DDS_OP_VAL_1BY << 16)
|
||||
#define DDS_OP_TYPE_2BY (DDS_OP_VAL_2BY << 16)
|
||||
#define DDS_OP_TYPE_4BY (DDS_OP_VAL_4BY << 16)
|
||||
#define DDS_OP_TYPE_8BY (DDS_OP_VAL_8BY << 16)
|
||||
#define DDS_OP_TYPE_STR (DDS_OP_VAL_STR << 16)
|
||||
#define DDS_OP_TYPE_SEQ (DDS_OP_VAL_SEQ << 16)
|
||||
#define DDS_OP_TYPE_ARR (DDS_OP_VAL_ARR << 16)
|
||||
#define DDS_OP_TYPE_UNI (DDS_OP_VAL_UNI << 16)
|
||||
#define DDS_OP_TYPE_STU (DDS_OP_VAL_STU << 16)
|
||||
#define DDS_OP_TYPE_BST (DDS_OP_VAL_BST << 16)
|
||||
|
||||
#define DDS_OP_TYPE_BOO DDS_OP_TYPE_1BY
|
||||
#define DDS_OP_SUBTYPE_BOO DDS_OP_SUBTYPE_1BY
|
||||
|
||||
#define DDS_OP_SUBTYPE_1BY (DDS_OP_VAL_1BY << 8)
|
||||
#define DDS_OP_SUBTYPE_2BY (DDS_OP_VAL_2BY << 8)
|
||||
#define DDS_OP_SUBTYPE_4BY (DDS_OP_VAL_4BY << 8)
|
||||
#define DDS_OP_SUBTYPE_8BY (DDS_OP_VAL_8BY << 8)
|
||||
#define DDS_OP_SUBTYPE_STR (DDS_OP_VAL_STR << 8)
|
||||
#define DDS_OP_SUBTYPE_SEQ (DDS_OP_VAL_SEQ << 8)
|
||||
#define DDS_OP_SUBTYPE_ARR (DDS_OP_VAL_ARR << 8)
|
||||
#define DDS_OP_SUBTYPE_UNI (DDS_OP_VAL_UNI << 8)
|
||||
#define DDS_OP_SUBTYPE_STU (DDS_OP_VAL_STU << 8)
|
||||
#define DDS_OP_SUBTYPE_BST (DDS_OP_VAL_BST << 8)
|
||||
|
||||
#define DDS_OP_FLAG_KEY 0x01
|
||||
#define DDS_OP_FLAG_DEF 0x02
|
||||
|
||||
/**
|
||||
* Description : Enable or disable write batching. Overrides default configuration
|
||||
* setting for write batching (DDSI2E/Internal/WriteBatch).
|
||||
*
|
||||
* Arguments :
|
||||
* -# enable Enables or disables write batching for all writers.
|
||||
*/
|
||||
DDS_EXPORT void dds_write_set_batch (bool enable);
|
||||
|
||||
/**
|
||||
* Description : Install tcp/ssl and encryption support. Depends on openssl.
|
||||
*
|
||||
* Arguments :
|
||||
* -# None
|
||||
*/
|
||||
DDS_EXPORT void dds_ssl_plugin (void);
|
||||
|
||||
/**
|
||||
* Description : Install client durability support. Depends on OSPL server.
|
||||
*
|
||||
* Arguments :
|
||||
* -# None
|
||||
*/
|
||||
DDS_EXPORT void dds_durability_plugin (void);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
323
src/core/ddsc/include/ddsc/dds_public_listener.h
Normal file
323
src/core/ddsc/include/ddsc/dds_public_listener.h
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/** @file
|
||||
*
|
||||
* @brief DDS C Listener API
|
||||
*
|
||||
* This header file defines the public API of listeners in the
|
||||
* CycloneDDS C language binding.
|
||||
*/
|
||||
#ifndef _DDS_PUBLIC_LISTENER_H_
|
||||
#define _DDS_PUBLIC_LISTENER_H_
|
||||
|
||||
#include "ddsc/dds_export.h"
|
||||
#include "ddsc/dds_public_impl.h"
|
||||
#include "ddsc/dds_public_status.h"
|
||||
#include "os/os_public.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Listener callbacks */
|
||||
typedef void (*dds_on_inconsistent_topic_fn) (dds_entity_t topic, const dds_inconsistent_topic_status_t status, void* arg);
|
||||
typedef void (*dds_on_liveliness_lost_fn) (dds_entity_t writer, const dds_liveliness_lost_status_t status, void* arg);
|
||||
typedef void (*dds_on_offered_deadline_missed_fn) (dds_entity_t writer, const dds_offered_deadline_missed_status_t status, void* arg);
|
||||
typedef void (*dds_on_offered_incompatible_qos_fn) (dds_entity_t writer, const dds_offered_incompatible_qos_status_t status, void* arg);
|
||||
typedef void (*dds_on_data_on_readers_fn) (dds_entity_t subscriber, void* arg);
|
||||
typedef void (*dds_on_sample_lost_fn) (dds_entity_t reader, const dds_sample_lost_status_t status, void* arg);
|
||||
typedef void (*dds_on_data_available_fn) (dds_entity_t reader, void* arg);
|
||||
typedef void (*dds_on_sample_rejected_fn) (dds_entity_t reader, const dds_sample_rejected_status_t status, void* arg);
|
||||
typedef void (*dds_on_liveliness_changed_fn) (dds_entity_t reader, const dds_liveliness_changed_status_t status, void* arg);
|
||||
typedef void (*dds_on_requested_deadline_missed_fn) (dds_entity_t reader, const dds_requested_deadline_missed_status_t status, void* arg);
|
||||
typedef void (*dds_on_requested_incompatible_qos_fn) (dds_entity_t reader, const dds_requested_incompatible_qos_status_t status, void* arg);
|
||||
typedef void (*dds_on_publication_matched_fn) (dds_entity_t writer, const dds_publication_matched_status_t status, void* arg);
|
||||
typedef void (*dds_on_subscription_matched_fn) (dds_entity_t reader, const dds_subscription_matched_status_t status, void* arg);
|
||||
|
||||
#if 0
|
||||
/* TODO: Why use (*dds_on_any_fn) (); and DDS_LUNSET? Why not just set the callbacks to NULL? */
|
||||
typedef void (*dds_on_any_fn) (); /**< Empty parameter list on purpose; should be assignable without cast to all of the above. @todo check with an actual compiler; I'm a sloppy compiler */
|
||||
#define DDS_LUNSET ((dds_on_any_fn)1) /**< Callback indicating a callback isn't set */
|
||||
#else
|
||||
#define DDS_LUNSET (NULL)
|
||||
#endif
|
||||
|
||||
struct c_listener;
|
||||
typedef struct c_listener dds_listener_t;
|
||||
|
||||
/**
|
||||
* @brief Allocate memory and initializes to default values (::DDS_LUNSET) of a listener
|
||||
*
|
||||
* @param[in] arg optional pointer that will be passed on to the listener callbacks
|
||||
*
|
||||
* @return Returns a pointer to the allocated memory for dds_listener_t structure.
|
||||
*/
|
||||
_Ret_notnull_
|
||||
DDS_EXPORT dds_listener_t* dds_listener_create (_In_opt_ void* arg);
|
||||
|
||||
/**
|
||||
* @brief Delete the memory allocated to listener structure
|
||||
*
|
||||
* @param[in] listener pointer to the listener struct to delete
|
||||
*/
|
||||
DDS_EXPORT void dds_listener_delete (_In_ _Post_invalid_ dds_listener_t * __restrict listener);
|
||||
|
||||
/**
|
||||
* @brief Reset the listener structure contents to ::DDS_LUNSET
|
||||
*
|
||||
* @param[in,out] listener pointer to the listener struct to reset
|
||||
*/
|
||||
DDS_EXPORT void dds_listener_reset (_Out_ dds_listener_t * __restrict listener);
|
||||
|
||||
/**
|
||||
* @brief Copy the listener callbacks from source to destination
|
||||
*
|
||||
* @param[in,out] dst The pointer to the destination listener structure, where the content is to copied
|
||||
* @param[in] src The pointer to the source listener structure to be copied
|
||||
*/
|
||||
DDS_EXPORT void dds_listener_copy (_Out_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src);
|
||||
|
||||
/**
|
||||
* @brief Copy the listener callbacks from source to destination, unless already set
|
||||
*
|
||||
* Any listener callbacks already set in @p dst (including NULL) are skipped, only
|
||||
* those set to DDS_LUNSET are copied from @p src.
|
||||
*
|
||||
* @param[in,out] dst The pointer to the destination listener structure, where the content is merged
|
||||
* @param[in] src The pointer to the source listener structure to be copied
|
||||
*/
|
||||
DDS_EXPORT void dds_listener_merge (_Inout_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src);
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* Setters
|
||||
************************************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Set the inconsistent_topic callback in the listener structure.
|
||||
*
|
||||
* @param listener The pointer to the listener structure, where the callback will be set
|
||||
* @param callback The callback to set in the listener, can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lset_inconsistent_topic (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_inconsistent_topic_fn callback);
|
||||
|
||||
/**
|
||||
* @brief Set the liveliness_lost callback in the listener structure.
|
||||
*
|
||||
* @param[out] listener The pointer to the listener structure, where the callback will be set
|
||||
* @param[in] callback The callback to set in the listener, can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lset_liveliness_lost (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_liveliness_lost_fn callback);
|
||||
|
||||
/**
|
||||
* @brief Set the offered_deadline_missed callback in the listener structure.
|
||||
*
|
||||
* @param[in,out] listener The pointer to the listener structure, where the callback will be set
|
||||
* @param[in] callback The callback to set in the listener, can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lset_offered_deadline_missed (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_offered_deadline_missed_fn callback);
|
||||
|
||||
/**
|
||||
* @brief Set the offered_incompatible_qos callback in the listener structure.
|
||||
*
|
||||
* @param[in,out] listener The pointer to the listener structure, where the callback will be set
|
||||
* @param[in] callback The callback to set in the listener, can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lset_offered_incompatible_qos (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_offered_incompatible_qos_fn callback);
|
||||
|
||||
/**
|
||||
* @brief Set the data_on_readers callback in the listener structure.
|
||||
*
|
||||
* @param[in,out] listener The pointer to the listener structure, where the callback will be set
|
||||
* @param[in] callback The callback to set in the listener, can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lset_data_on_readers (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_data_on_readers_fn callback);
|
||||
|
||||
/**
|
||||
* @brief Set the sample_lost callback in the listener structure.
|
||||
*
|
||||
* @param[in,out] listener The pointer to the listener structure, where the callback will be set
|
||||
* @param[in] callback The callback to set in the listener, can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lset_sample_lost (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_sample_lost_fn callback);
|
||||
|
||||
/**
|
||||
* @brief Set the data_available callback in the listener structure.
|
||||
*
|
||||
* @param[in,out] listener The pointer to the listener structure, where the callback will be set
|
||||
* @param[in] callback The callback to set in the listener, can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lset_data_available (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_data_available_fn callback);
|
||||
|
||||
/**
|
||||
* @brief Set the sample_rejected callback in the listener structure.
|
||||
*
|
||||
* @param[in,out] listener The pointer to the listener structure, where the callback will be set
|
||||
* @param[in] callback The callback to set in the listener, can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lset_sample_rejected (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_sample_rejected_fn callback);
|
||||
|
||||
/**
|
||||
* @brief Set the liveliness_changed callback in the listener structure.
|
||||
*
|
||||
* @param[in,out] listener The pointer to the listener structure, where the callback will be set
|
||||
* @param[in] callback The callback to set in the listener, can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lset_liveliness_changed (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_liveliness_changed_fn callback);
|
||||
|
||||
/**
|
||||
* @brief Set the requested_deadline_missed callback in the listener structure.
|
||||
*
|
||||
* @param[in,out] listener The pointer to the listener structure, where the callback will be set
|
||||
* @param[in] callback The callback to set in the listener, can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lset_requested_deadline_missed (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_requested_deadline_missed_fn callback);
|
||||
|
||||
/**
|
||||
* @brief Set the requested_incompatible_qos callback in the listener structure.
|
||||
*
|
||||
* @param[in,out] listener The pointer to the listener structure, where the callback will be set
|
||||
* @param[in] callback The callback to set in the listener, can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lset_requested_incompatible_qos (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_requested_incompatible_qos_fn callback);
|
||||
|
||||
/**
|
||||
* @brief Set the publication_matched callback in the listener structure.
|
||||
*
|
||||
* @param[in,out] listener The pointer to the listener structure, where the callback will be set
|
||||
* @param[in] callback The callback to set in the listener, can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lset_publication_matched (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_publication_matched_fn callback);
|
||||
|
||||
/**
|
||||
* @brief Set the subscription_matched callback in the listener structure.
|
||||
*
|
||||
* @param[in,out] listener The pointer to the listener structure, where the callback will be set
|
||||
* @param[in] callback The callback to set in the listener, can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lset_subscription_matched (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_subscription_matched_fn callback);
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* Getters
|
||||
************************************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Get the inconsistent_topic callback from the listener structure.
|
||||
*
|
||||
* @param[in] listener The pointer to the listener structure, where the callback will be retrieved from
|
||||
* @param[in,out] callback Pointer where the retrieved callback can be stored; can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lget_inconsistent_topic (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_inconsistent_topic_fn *callback);
|
||||
|
||||
/**
|
||||
* @brief Get the liveliness_lost callback from the listener structure.
|
||||
*
|
||||
* @param[in] listener The pointer to the listener structure, where the callback will be retrieved from
|
||||
* @param[in,out] callback Pointer where the retrieved callback can be stored; can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lget_liveliness_lost (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_liveliness_lost_fn *callback);
|
||||
|
||||
/**
|
||||
* @brief Get the offered_deadline_missed callback from the listener structure.
|
||||
*
|
||||
* @param[in] listener The pointer to the listener structure, where the callback will be retrieved from
|
||||
* @param[in,out] callback Pointer where the retrieved callback can be stored; can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lget_offered_deadline_missed (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_offered_deadline_missed_fn *callback);
|
||||
|
||||
/**
|
||||
* @brief Get the offered_incompatible_qos callback from the listener structure.
|
||||
*
|
||||
* @param[in] listener The pointer to the listener structure, where the callback will be retrieved from
|
||||
* @param[in,out] callback Pointer where the retrieved callback can be stored; can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lget_offered_incompatible_qos (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_offered_incompatible_qos_fn *callback);
|
||||
|
||||
/**
|
||||
* @brief Get the data_on_readers callback from the listener structure.
|
||||
*
|
||||
* @param[in] listener The pointer to the listener structure, where the callback will be retrieved from
|
||||
* @param[in,out] callback Pointer where the retrieved callback can be stored; can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lget_data_on_readers (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_data_on_readers_fn *callback);
|
||||
|
||||
/**
|
||||
* @brief Get the sample_lost callback from the listener structure.
|
||||
*
|
||||
* @param[in] listener The pointer to the listener structure, where the callback will be retrieved from
|
||||
* @param[in,out] callback Pointer where the retrieved callback can be stored; can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lget_sample_lost (_In_ const dds_listener_t *__restrict listener, _Outptr_result_maybenull_ dds_on_sample_lost_fn *callback);
|
||||
|
||||
/**
|
||||
* @brief Get the data_available callback from the listener structure.
|
||||
*
|
||||
* @param[in] listener The pointer to the listener structure, where the callback will be retrieved from
|
||||
* @param[in,out] callback Pointer where the retrieved callback can be stored; can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lget_data_available (_In_ const dds_listener_t *__restrict listener, _Outptr_result_maybenull_ dds_on_data_available_fn *callback);
|
||||
|
||||
/**
|
||||
* @brief Get the sample_rejected callback from the listener structure.
|
||||
*
|
||||
* @param[in] listener The pointer to the listener structure, where the callback will be retrieved from
|
||||
* @param[in,out] callback Pointer where the retrieved callback can be stored; can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lget_sample_rejected (_In_ const dds_listener_t *__restrict listener, _Outptr_result_maybenull_ dds_on_sample_rejected_fn *callback);
|
||||
|
||||
/**
|
||||
* @brief Get the liveliness_changed callback from the listener structure.
|
||||
*
|
||||
* @param[in] listener The pointer to the listener structure, where the callback will be retrieved from
|
||||
* @param[in,out] callback Pointer where the retrieved callback can be stored; can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lget_liveliness_changed (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_liveliness_changed_fn *callback);
|
||||
|
||||
/**
|
||||
* @brief Get the requested_deadline_missed callback from the listener structure.
|
||||
*
|
||||
* @param[in] listener The pointer to the listener structure, where the callback will be retrieved from
|
||||
* @param[in,out] callback Pointer where the retrieved callback can be stored; can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lget_requested_deadline_missed (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_requested_deadline_missed_fn *callback);
|
||||
|
||||
/**
|
||||
* @brief Get the requested_incompatible_qos callback from the listener structure.
|
||||
*
|
||||
* @param[in] listener The pointer to the listener structure, where the callback will be retrieved from
|
||||
* @param[in,out] callback Pointer where the retrieved callback can be stored; can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lget_requested_incompatible_qos (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_requested_incompatible_qos_fn *callback);
|
||||
|
||||
/**
|
||||
* @brief Get the publication_matched callback from the listener structure.
|
||||
*
|
||||
* @param[in] listener The pointer to the listener structure, where the callback will be retrieved from
|
||||
* @param[in,out] callback Pointer where the retrieved callback can be stored; can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
*/
|
||||
DDS_EXPORT void dds_lget_publication_matched (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_publication_matched_fn *callback);
|
||||
|
||||
/**
|
||||
* @brief Get the subscription_matched callback from the listener structure.
|
||||
*
|
||||
* @param[in] callback Pointer where the retrieved callback can be stored; can be NULL, ::DDS_LUNSET or a valid callback pointer
|
||||
* @param[in,out] listener The pointer to the listener structure, where the callback will be retrieved from
|
||||
*/
|
||||
DDS_EXPORT void dds_lget_subscription_matched (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_subscription_matched_fn *callback);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_DDS_PUBLIC_LISTENER_H_*/
|
||||
39
src/core/ddsc/include/ddsc/dds_public_log.h
Normal file
39
src/core/ddsc/include/ddsc/dds_public_log.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
/* TODO: do we really need to expose this as an API? */
|
||||
|
||||
/** @file
|
||||
*
|
||||
* @brief DDS C Logging API
|
||||
*
|
||||
* This header file defines the public API for logging in the
|
||||
* CycloneDDS C language binding.
|
||||
*/
|
||||
#ifndef DDS_LOG_H
|
||||
#define DDS_LOG_H
|
||||
|
||||
#include "os/os_public.h"
|
||||
#include "ddsc/dds_export.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
DDS_EXPORT void dds_log_info (const char * fmt, ...);
|
||||
DDS_EXPORT void dds_log_warn (const char * fmt, ...);
|
||||
DDS_EXPORT void dds_log_error (const char * fmt, ...);
|
||||
DDS_EXPORT void dds_log_fatal (const char * fmt, ...);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
815
src/core/ddsc/include/ddsc/dds_public_qos.h
Normal file
815
src/core/ddsc/include/ddsc/dds_public_qos.h
Normal file
|
|
@ -0,0 +1,815 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/** @file
|
||||
*
|
||||
* @brief DDS C QoS API
|
||||
*
|
||||
* This header file defines the public API of QoS and Policies in the
|
||||
* CycloneDDS C language binding.
|
||||
*/
|
||||
#ifndef DDS_QOS_H
|
||||
#define DDS_QOS_H
|
||||
|
||||
#include "os/os_public.h"
|
||||
#include "ddsc/dds_export.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* QoS identifiers */
|
||||
/** @name QoS identifiers
|
||||
@{**/
|
||||
#define DDS_INVALID_QOS_POLICY_ID 0
|
||||
#define DDS_USERDATA_QOS_POLICY_ID 1
|
||||
#define DDS_DURABILITY_QOS_POLICY_ID 2
|
||||
#define DDS_PRESENTATION_QOS_POLICY_ID 3
|
||||
#define DDS_DEADLINE_QOS_POLICY_ID 4
|
||||
#define DDS_LATENCYBUDGET_QOS_POLICY_ID 5
|
||||
#define DDS_OWNERSHIP_QOS_POLICY_ID 6
|
||||
#define DDS_OWNERSHIPSTRENGTH_QOS_POLICY_ID 7
|
||||
#define DDS_LIVELINESS_QOS_POLICY_ID 8
|
||||
#define DDS_TIMEBASEDFILTER_QOS_POLICY_ID 9
|
||||
#define DDS_PARTITION_QOS_POLICY_ID 10
|
||||
#define DDS_RELIABILITY_QOS_POLICY_ID 11
|
||||
#define DDS_DESTINATIONORDER_QOS_POLICY_ID 12
|
||||
#define DDS_HISTORY_QOS_POLICY_ID 13
|
||||
#define DDS_RESOURCELIMITS_QOS_POLICY_ID 14
|
||||
#define DDS_ENTITYFACTORY_QOS_POLICY_ID 15
|
||||
#define DDS_WRITERDATALIFECYCLE_QOS_POLICY_ID 16
|
||||
#define DDS_READERDATALIFECYCLE_QOS_POLICY_ID 17
|
||||
#define DDS_TOPICDATA_QOS_POLICY_ID 18
|
||||
#define DDS_GROUPDATA_QOS_POLICY_ID 19
|
||||
#define DDS_TRANSPORTPRIORITY_QOS_POLICY_ID 20
|
||||
#define DDS_LIFESPAN_QOS_POLICY_ID 21
|
||||
#define DDS_DURABILITYSERVICE_QOS_POLICY_ID 22
|
||||
/** @}*/
|
||||
|
||||
|
||||
/* QoS structure is opaque */
|
||||
/** QoS structure */
|
||||
typedef struct nn_xqos dds_qos_t;
|
||||
|
||||
/** Durability QoS: Applies to Topic, DataReader, DataWriter */
|
||||
typedef enum dds_durability_kind
|
||||
{
|
||||
DDS_DURABILITY_VOLATILE,
|
||||
DDS_DURABILITY_TRANSIENT_LOCAL,
|
||||
DDS_DURABILITY_TRANSIENT,
|
||||
DDS_DURABILITY_PERSISTENT
|
||||
}
|
||||
dds_durability_kind_t;
|
||||
|
||||
/** History QoS: Applies to Topic, DataReader, DataWriter */
|
||||
typedef enum dds_history_kind
|
||||
{
|
||||
DDS_HISTORY_KEEP_LAST,
|
||||
DDS_HISTORY_KEEP_ALL
|
||||
}
|
||||
dds_history_kind_t;
|
||||
|
||||
/** Ownership QoS: Applies to Topic, DataReader, DataWriter */
|
||||
typedef enum dds_ownership_kind
|
||||
{
|
||||
DDS_OWNERSHIP_SHARED,
|
||||
DDS_OWNERSHIP_EXCLUSIVE
|
||||
}
|
||||
dds_ownership_kind_t;
|
||||
|
||||
/** Liveliness QoS: Applies to Topic, DataReader, DataWriter */
|
||||
typedef enum dds_liveliness_kind
|
||||
{
|
||||
DDS_LIVELINESS_AUTOMATIC,
|
||||
DDS_LIVELINESS_MANUAL_BY_PARTICIPANT,
|
||||
DDS_LIVELINESS_MANUAL_BY_TOPIC
|
||||
}
|
||||
dds_liveliness_kind_t;
|
||||
|
||||
/** Reliability QoS: Applies to Topic, DataReader, DataWriter */
|
||||
typedef enum dds_reliability_kind
|
||||
{
|
||||
DDS_RELIABILITY_BEST_EFFORT,
|
||||
DDS_RELIABILITY_RELIABLE
|
||||
}
|
||||
dds_reliability_kind_t;
|
||||
|
||||
/** DestinationOrder QoS: Applies to Topic, DataReader, DataWriter */
|
||||
typedef enum dds_destination_order_kind
|
||||
{
|
||||
DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP,
|
||||
DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP
|
||||
}
|
||||
dds_destination_order_kind_t;
|
||||
|
||||
/** History QoS: Applies to Topic, DataReader, DataWriter */
|
||||
typedef struct dds_history_qospolicy
|
||||
{
|
||||
dds_history_kind_t kind;
|
||||
int32_t depth;
|
||||
}
|
||||
dds_history_qospolicy_t;
|
||||
|
||||
/** ResourceLimits QoS: Applies to Topic, DataReader, DataWriter */
|
||||
typedef struct dds_resource_limits_qospolicy
|
||||
{
|
||||
int32_t max_samples;
|
||||
int32_t max_instances;
|
||||
int32_t max_samples_per_instance;
|
||||
}
|
||||
dds_resource_limits_qospolicy_t;
|
||||
|
||||
/** Presentation QoS: Applies to Publisher, Subscriber */
|
||||
typedef enum dds_presentation_access_scope_kind
|
||||
{
|
||||
DDS_PRESENTATION_INSTANCE,
|
||||
DDS_PRESENTATION_TOPIC,
|
||||
DDS_PRESENTATION_GROUP
|
||||
}
|
||||
dds_presentation_access_scope_kind_t;
|
||||
|
||||
/**
|
||||
* @brief Allocate memory and initialize default QoS-policies
|
||||
*
|
||||
* @returns - Pointer to the initialized dds_qos_t structure, NULL if unsuccessful.
|
||||
*/
|
||||
_Ret_notnull_
|
||||
DDS_EXPORT
|
||||
dds_qos_t * dds_qos_create (void);
|
||||
|
||||
/**
|
||||
* @brief Delete memory allocated to QoS-policies structure
|
||||
*
|
||||
* @param[in] qos - Pointer to dds_qos_t structure
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qos_delete (
|
||||
_In_ _Post_invalid_ dds_qos_t * __restrict qos
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Reset a QoS-policies structure to default values
|
||||
*
|
||||
* @param[in,out] qos - Pointer to the dds_qos_t structure
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qos_reset (
|
||||
_Out_ dds_qos_t * __restrict qos
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Copy all QoS-policies from one structure to another
|
||||
*
|
||||
* @param[in,out] dst - Pointer to the destination dds_qos_t structure
|
||||
* @param[in] src - Pointer to the source dds_qos_t structure
|
||||
*
|
||||
* @returns - Return-code indicating success or failure
|
||||
*/
|
||||
DDS_EXPORT
|
||||
dds_return_t dds_qos_copy (
|
||||
_Out_ dds_qos_t * __restrict dst,
|
||||
_In_ const dds_qos_t * __restrict src
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Copy all QoS-policies from one structure to another, unless already set
|
||||
*
|
||||
* Policies are copied from src to dst, unless src already has the policy set to a non-default value.
|
||||
*
|
||||
* @param[in,out] dst - Pointer to the destination qos structure
|
||||
* @param[in] src - Pointer to the source qos structure
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qos_merge
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict dst,
|
||||
_In_ const dds_qos_t * __restrict src
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the userdata of a qos structure.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the userdata
|
||||
* @param[in] value - Pointer to the userdata
|
||||
* @param[in] sz - Size of userdata stored in value
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_userdata
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_reads_bytes_opt_(sz) const void * __restrict value,
|
||||
_In_ size_t sz
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the topicdata of a qos structure.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the topicdata
|
||||
* @param[in] value - Pointer to the topicdata
|
||||
* @param[in] sz - Size of the topicdata stored in value
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_topicdata
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_reads_bytes_opt_(sz) const void * __restrict value,
|
||||
_In_ size_t sz
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the groupdata of a qos structure.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the groupdata
|
||||
* @param[in] value - Pointer to the group data
|
||||
* @param[in] sz - Size of groupdata stored in value
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_groupdata
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_reads_bytes_opt_(sz) const void * __restrict value,
|
||||
_In_ size_t sz
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the durability policy of a qos structure.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] kind - Durability kind value \ref DCPS_QoS_Durability
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_durability
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(DDS_DURABILITY_VOLATILE, DDS_DURABILITY_PERSISTENT) dds_durability_kind_t kind
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the history policy of a qos structure.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] kind - History kind value \ref DCPS_QoS_History
|
||||
* @param[in] depth - History depth value \ref DCPS_QoS_History
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_history
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(DDS_HISTORY_KEEP_LAST, DDS_HISTORY_KEEP_ALL) dds_history_kind_t kind,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t depth
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the resource limits policy of a qos structure.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] max_samples - Number of samples resource-limit value
|
||||
* @param[in] max_instances - Number of instances resource-limit value
|
||||
* @param[in] max_samples_per_instance - Number of samples per instance resource-limit value
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_resource_limits
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t max_samples,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t max_instances,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t max_samples_per_instance
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the presentation policy of a qos structure.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] access_scope - Access-scope kind
|
||||
* @param[in] coherent_access - Coherent access enable value
|
||||
* @param[in] ordered_access - Ordered access enable value
|
||||
*/
|
||||
DDS_EXPORT void dds_qset_presentation
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(DDS_PRESENTATION_INSTANCE, DDS_PRESENTATION_GROUP) dds_presentation_access_scope_kind_t access_scope,
|
||||
_In_ bool coherent_access,
|
||||
_In_ bool ordered_access
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the lifespan policy of a qos structure.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] lifespan - Lifespan duration (expiration time relative to source timestamp of a sample)
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_lifespan
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t lifespan
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the deadline policy of a qos structure.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] deadline - Deadline duration
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_deadline
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t deadline
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the latency-budget policy of a qos structure
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] duration - Latency budget duration
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_latency_budget
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t duration
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the ownership policy of a qos structure
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] kind - Ownership kind
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_ownership
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(DDS_OWNERSHIP_SHARED, DDS_OWNERSHIP_EXCLUSIVE) dds_ownership_kind_t kind
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the ownership strength policy of a qos structure
|
||||
*
|
||||
* param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* param[in] value - Ownership strength value
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_ownership_strength
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_ int32_t value
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the liveliness policy of a qos structure
|
||||
*
|
||||
* param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* param[in] kind - Liveliness kind
|
||||
* param[in[ lease_duration - Lease duration
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_liveliness
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(DDS_LIVELINESS_AUTOMATIC, DDS_LIVELINESS_MANUAL_BY_TOPIC) dds_liveliness_kind_t kind,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t lease_duration
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the time-based filter policy of a qos structure
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] minimum_separation - Minimum duration between sample delivery for an instance
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_time_based_filter
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t minimum_separation
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the partition policy of a qos structure
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] n - Number of partitions stored in ps
|
||||
* @param[in[ ps - Pointer to string(s) storing partition name(s)
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_partition
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_ uint32_t n,
|
||||
_In_count_(n) _Deref_pre_z_ const char ** __restrict ps
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the reliability policy of a qos structure
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] kind - Reliability kind
|
||||
* @param[in] max_blocking_time - Max blocking duration applied when kind is reliable.
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_reliability
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(DDS_RELIABILITY_BEST_EFFORT, DDS_RELIABILITY_RELIABLE) dds_reliability_kind_t kind,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t max_blocking_time
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the transport-priority policy of a qos structure
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] value - Priority value
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_transport_priority
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_ int32_t value
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the destination-order policy of a qos structure
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] kind - Destination-order kind
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_destination_order
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP,
|
||||
DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP) dds_destination_order_kind_t kind
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the writer data-lifecycle policy of a qos structure
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] autodispose_unregistered_instances - Automatic disposal of unregistered instances
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_writer_data_lifecycle
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_ bool autodispose
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the reader data-lifecycle policy of a qos structure
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] autopurge_nowriter_samples_delay - Delay for purging of samples from instances in a no-writers state
|
||||
* @param[in] autopurge_disposed_samples_delay - Delay for purging of samples from disposed instances
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_reader_data_lifecycle
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t autopurge_nowriter_samples_delay,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t autopurge_disposed_samples_delay
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Set the durability-service policy of a qos structure
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the policy
|
||||
* @param[in] service_cleanup_delay - Delay for purging of abandoned instances from the durability service
|
||||
* @param[in] history_kind - History policy kind applied by the durability service
|
||||
* @param[in] history_depth - History policy depth applied by the durability service
|
||||
* @param[in] max_samples - Number of samples resource-limit policy applied by the durability service
|
||||
* @param[in] max_instances - Number of instances resource-limit policy applied by the durability service
|
||||
* @param[in] max_samples_per_instance - Number of samples per instance resource-limit policy applied by the durability service
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qset_durability_service
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t service_cleanup_delay,
|
||||
_In_range_(DDS_HISTORY_KEEP_LAST, DDS_HISTORY_KEEP_ALL) dds_history_kind_t history_kind,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t history_depth,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t max_samples,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t max_instances,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t max_samples_per_instance
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the userdata from a qos structure
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] value - Pointer that will store the userdata
|
||||
* @param[in,out] sz - Pointer that will store the size of userdata
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_userdata
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Outptr_result_bytebuffer_maybenull_(*sz) void ** value,
|
||||
_Out_ size_t * sz
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the topicdata from a qos structure
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] value - Pointer that will store the topicdata
|
||||
* @param[in,out] sz - Pointer that will store the size of topicdata
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_topicdata
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Outptr_result_bytebuffer_maybenull_(*sz) void ** value,
|
||||
_Out_ size_t * sz
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the groupdata from a qos structure
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] value - Pointer that will store the groupdata
|
||||
* @param[in,out] sz - Pointer that will store the size of groupdata
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_groupdata
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Outptr_result_bytebuffer_maybenull_(*sz) void ** value,
|
||||
_Out_ size_t * sz
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the durability policy from a qos structure
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] kind - Pointer that will store the durability kind
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_durability
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ dds_durability_kind_t *kind
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the history policy from a qos structure
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] kind - Pointer that will store the history kind (optional)
|
||||
* @param[in,out] depth - Pointer that will store the history depth (optional)
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_history
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_opt_ dds_history_kind_t * kind,
|
||||
_Out_opt_ int32_t *depth
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the resource-limits policy from a qos structure
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] max_samples - Pointer that will store the number of samples resource-limit (optional)
|
||||
* @param[in,out] max_instances - Pointer that will store the number of instances resource-limit (optional)
|
||||
* @param[in,out] max_samples_per_instance - Pointer that will store the number of samples per instance resource-limit (optional)
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_resource_limits
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_opt_ int32_t *max_samples,
|
||||
_Out_opt_ int32_t *max_instances,
|
||||
_Out_opt_ int32_t *max_samples_per_instance
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the presentation policy from a qos structure
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] access_scope - Pointer that will store access scope kind (optional)
|
||||
* @param[in,out] coherent_access - Pointer that will store coherent access enable value (optional)
|
||||
* @param[in,out] ordered_access - Pointer that will store orderede access enable value (optional)
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_presentation
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_opt_ dds_presentation_access_scope_kind_t *access_scope,
|
||||
_Out_opt_ bool *coherent_access,
|
||||
_Out_opt_ bool *ordered_access
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the lifespan policy from a qos structure
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] lifespan - Pointer that will store lifespan duration
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_lifespan
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ dds_duration_t * lifespan
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the deadline policy from a qos structure
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] deadline - Pointer that will store deadline duration
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_deadline
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ dds_duration_t * deadline
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the latency-budget policy from a qos structure
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] duration - Pointer that will store latency-budget duration
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_latency_budget
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ dds_duration_t *duration
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the ownership policy from a qos structure
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] kind - Pointer that will store the ownership kind
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_ownership
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ dds_ownership_kind_t *kind
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the ownership strength qos policy
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] value - Pointer that will store the ownership strength value
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_ownership_strength
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ int32_t *value
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the liveliness qos policy
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] kind - Pointer that will store the liveliness kind (optional)
|
||||
* @param[in,out] lease_duration - Pointer that will store the liveliness lease duration (optional)
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_liveliness
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_opt_ dds_liveliness_kind_t *kind,
|
||||
_Out_opt_ dds_duration_t *lease_duration
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the time-based filter qos policy
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] minimum_separation - Pointer that will store the minimum separation duration (optional)
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_time_based_filter
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ dds_duration_t *minimum_separation
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the partition qos policy
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] n - Pointer that will store the number of partitions (optional)
|
||||
* @param[in,out] ps - Pointer that will store the string(s) containing partition name(s) (optional)
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_partition
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ uint32_t *n,
|
||||
_Outptr_opt_result_buffer_all_maybenull_(*n) char *** ps
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the reliability qos policy
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] kind - Pointer that will store the reliability kind (optional)
|
||||
* @param[in,out] max_blocking_time - Pointer that will store the max blocking time for reliable reliability (optional)
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_reliability
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_opt_ dds_reliability_kind_t *kind,
|
||||
_Out_opt_ dds_duration_t *max_blocking_time
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the transport priority qos policy
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] value - Pointer that will store the transport priority value
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_transport_priority
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ int32_t *value
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the destination-order qos policy
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] kind - Pointer that will store the destination-order kind
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_destination_order
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ dds_destination_order_kind_t *kind
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the writer data-lifecycle qos policy
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] autodispose_unregistered_instances - Pointer that will store the autodispose unregistered instances enable value
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_writer_data_lifecycle
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ bool * autodispose
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the reader data-lifecycle qos policy
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] autopurge_nowriter_samples_delay - Pointer that will store the delay for auto-purging samples from instances in a no-writer state (optional)
|
||||
* @param[in,out] autopurge_disposed_samples_delay - Pointer that will store the delay for auto-purging of disposed instances (optional)
|
||||
*/
|
||||
DDS_EXPORT
|
||||
void dds_qget_reader_data_lifecycle
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_opt_ dds_duration_t *autopurge_nowriter_samples_delay,
|
||||
_Out_opt_ dds_duration_t *autopurge_disposed_samples_delay
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the durability-service qos policy values.
|
||||
*
|
||||
* @param[in] qos - Pointer to a dds_qos_t structure storing the policy
|
||||
* @param[in,out] service_cleanup_delay - Pointer that will store the delay for purging of abandoned instances from the durability service (optional)
|
||||
* @param[in,out] history_kind - Pointer that will store history policy kind applied by the durability service (optional)
|
||||
* @param[in,out] history_depth - Pointer that will store history policy depth applied by the durability service (optional)
|
||||
* @param[in,out] max_samples - Pointer that will store number of samples resource-limit policy applied by the durability service (optional)
|
||||
* @param[in,out] max_instances - Pointer that will store number of instances resource-limit policy applied by the durability service (optional)
|
||||
* @param[in,out] max_samples_per_instance - Pointer that will store number of samples per instance resource-limit policy applied by the durability service (optional)
|
||||
*/
|
||||
DDS_EXPORT void dds_qget_durability_service
|
||||
(
|
||||
_In_ const dds_qos_t * qos,
|
||||
_Out_opt_ dds_duration_t * service_cleanup_delay,
|
||||
_Out_opt_ dds_history_kind_t * history_kind,
|
||||
_Out_opt_ int32_t * history_depth,
|
||||
_Out_opt_ int32_t * max_samples,
|
||||
_Out_opt_ int32_t * max_instances,
|
||||
_Out_opt_ int32_t * max_samples_per_instance
|
||||
);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
491
src/core/ddsc/include/ddsc/dds_public_status.h
Normal file
491
src/core/ddsc/include/ddsc/dds_public_status.h
Normal file
|
|
@ -0,0 +1,491 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/** @file
|
||||
*
|
||||
* @brief DDS C Communication Status API
|
||||
*
|
||||
* This header file defines the public API of the Communication Status in the
|
||||
* CycloneDDS C language binding.
|
||||
*/
|
||||
#ifndef DDS_STATUS_H
|
||||
#define DDS_STATUS_H
|
||||
|
||||
#include "os/os_public.h"
|
||||
#include "ddsc/dds_export.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Listeners implemented as structs containing callback functions
|
||||
that take listener status types as arguments.
|
||||
*/
|
||||
|
||||
/* Listener status types */
|
||||
/**
|
||||
* \ref DCPS_Status_OfferedDeadlineMissed
|
||||
*/
|
||||
typedef struct dds_offered_deadline_missed_status
|
||||
{
|
||||
uint32_t total_count;
|
||||
int32_t total_count_change;
|
||||
dds_instance_handle_t last_instance_handle;
|
||||
}
|
||||
dds_offered_deadline_missed_status_t;
|
||||
|
||||
/**
|
||||
* \ref DCPS_Status_OfferedIncompatibleQoS
|
||||
*/
|
||||
typedef struct dds_offered_incompatible_qos_status
|
||||
{
|
||||
uint32_t total_count;
|
||||
int32_t total_count_change;
|
||||
uint32_t last_policy_id;
|
||||
}
|
||||
dds_offered_incompatible_qos_status_t;
|
||||
|
||||
/**
|
||||
* \ref DCPS_Status_PublicationMatched
|
||||
*/
|
||||
typedef struct dds_publication_matched_status
|
||||
{
|
||||
uint32_t total_count;
|
||||
int32_t total_count_change;
|
||||
uint32_t current_count;
|
||||
int32_t current_count_change;
|
||||
dds_instance_handle_t last_subscription_handle;
|
||||
}
|
||||
dds_publication_matched_status_t;
|
||||
|
||||
/**
|
||||
* \ref DCPS_Status_LivelinessLost
|
||||
*/
|
||||
typedef struct dds_liveliness_lost_status
|
||||
{
|
||||
uint32_t total_count;
|
||||
int32_t total_count_change;
|
||||
}
|
||||
dds_liveliness_lost_status_t;
|
||||
|
||||
/**
|
||||
* \ref DCPS_Status_SubscriptionMatched
|
||||
*/
|
||||
typedef struct dds_subscription_matched_status
|
||||
{
|
||||
uint32_t total_count;
|
||||
int32_t total_count_change;
|
||||
uint32_t current_count;
|
||||
int32_t current_count_change;
|
||||
dds_instance_handle_t last_publication_handle;
|
||||
}
|
||||
dds_subscription_matched_status_t;
|
||||
|
||||
/**
|
||||
* dds_sample_rejected_status_kind
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
DDS_NOT_REJECTED,
|
||||
DDS_REJECTED_BY_INSTANCES_LIMIT,
|
||||
DDS_REJECTED_BY_SAMPLES_LIMIT,
|
||||
DDS_REJECTED_BY_SAMPLES_PER_INSTANCE_LIMIT
|
||||
}
|
||||
dds_sample_rejected_status_kind;
|
||||
|
||||
/**
|
||||
* \ref DCPS_Status_SampleRejected
|
||||
*/
|
||||
typedef struct dds_sample_rejected_status
|
||||
{
|
||||
uint32_t total_count;
|
||||
int32_t total_count_change;
|
||||
dds_sample_rejected_status_kind last_reason;
|
||||
dds_instance_handle_t last_instance_handle;
|
||||
}
|
||||
dds_sample_rejected_status_t;
|
||||
|
||||
/**
|
||||
* \ref DCPS_Status_LivelinessChanged
|
||||
*/
|
||||
typedef struct dds_liveliness_changed_status
|
||||
{
|
||||
uint32_t alive_count;
|
||||
uint32_t not_alive_count;
|
||||
int32_t alive_count_change;
|
||||
int32_t not_alive_count_change;
|
||||
dds_instance_handle_t last_publication_handle;
|
||||
}
|
||||
dds_liveliness_changed_status_t;
|
||||
|
||||
/**
|
||||
* \ref DCPS_Status_RequestedDeadlineMissed
|
||||
*/
|
||||
typedef struct dds_requested_deadline_missed_status
|
||||
{
|
||||
uint32_t total_count;
|
||||
int32_t total_count_change;
|
||||
dds_instance_handle_t last_instance_handle;
|
||||
}
|
||||
dds_requested_deadline_missed_status_t;
|
||||
|
||||
/**
|
||||
* \ref DCPS_Status_RequestedIncompatibleQoS
|
||||
*/
|
||||
typedef struct dds_requested_incompatible_qos_status
|
||||
{
|
||||
uint32_t total_count;
|
||||
int32_t total_count_change;
|
||||
uint32_t last_policy_id;
|
||||
}
|
||||
dds_requested_incompatible_qos_status_t;
|
||||
|
||||
/**
|
||||
* \ref DCPS_Status_SampleLost
|
||||
*/
|
||||
typedef struct dds_sample_lost_status
|
||||
{
|
||||
uint32_t total_count;
|
||||
int32_t total_count_change;
|
||||
}
|
||||
dds_sample_lost_status_t;
|
||||
|
||||
/**
|
||||
* \ref DCPS_Status_InconsistentTopic
|
||||
*/
|
||||
typedef struct dds_inconsistent_topic_status
|
||||
{
|
||||
uint32_t total_count;
|
||||
int32_t total_count_change;
|
||||
}
|
||||
dds_inconsistent_topic_status_t;
|
||||
|
||||
|
||||
/*
|
||||
get_<status> APIs return the status of an entity and resets the status
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Get INCONSISTENT_TOPIC status
|
||||
*
|
||||
* This operation gets the status value corresponding to INCONSISTENT_TOPIC
|
||||
* and reset the status. The value can be obtained, only if the status is enabled for an entity.
|
||||
* NULL value for status is allowed and it will reset the trigger value when status is enabled.
|
||||
*
|
||||
* @param[in] topic The entity to get the status
|
||||
* @param[out] status The pointer to \ref DCPS_Status_InconsistentTopic to get the status
|
||||
*
|
||||
* @returns 0 - Success
|
||||
* @returns <0 - Failure (use dds_err_nr() to get error value).
|
||||
*
|
||||
* @retval DDS_RETCODE_ERROR
|
||||
* An internal error has occurred.
|
||||
* @retval DDS_RETCODE_BAD_PARAMETER
|
||||
* One of the given arguments is not valid.
|
||||
* @retval DDS_RETCODE_ILLEGAL_OPERATION
|
||||
* The operation is invoked on an inappropriate object.
|
||||
* @retval DDS_RETCODE_ALREADY_DELETED
|
||||
* The entity has already been deleted.
|
||||
*/
|
||||
_Pre_satisfies_((topic & DDS_ENTITY_KIND_MASK) == DDS_KIND_TOPIC)
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_get_inconsistent_topic_status (
|
||||
_In_ dds_entity_t topic,
|
||||
_Out_opt_ dds_inconsistent_topic_status_t * status);
|
||||
|
||||
/**
|
||||
* @brief Get PUBLICATION_MATCHED status
|
||||
*
|
||||
* This operation gets the status value corresponding to PUBLICATION_MATCHED
|
||||
* and reset the status. The value can be obtained, only if the status is enabled for an entity.
|
||||
* NULL value for status is allowed and it will reset the trigger value when status is enabled.
|
||||
*
|
||||
* @param[in] writer The entity to get the status
|
||||
* @param[out] status The pointer to \ref DCPS_Status_PublicationMatched to get the status
|
||||
*
|
||||
* @returns 0 - Success
|
||||
* @returns <0 - Failure (use dds_err_nr() to get error value).
|
||||
*
|
||||
* @retval DDS_RETCODE_ERROR
|
||||
* An internal error has occurred.
|
||||
* @retval DDS_RETCODE_BAD_PARAMETER
|
||||
* One of the given arguments is not valid.
|
||||
* @retval DDS_RETCODE_ILLEGAL_OPERATION
|
||||
* The operation is invoked on an inappropriate object.
|
||||
* @retval DDS_RETCODE_ALREADY_DELETED
|
||||
* The entity has already been deleted.
|
||||
*/
|
||||
_Pre_satisfies_(((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER))
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_get_publication_matched_status (
|
||||
_In_ dds_entity_t writer,
|
||||
_Out_opt_ dds_publication_matched_status_t * status);
|
||||
|
||||
/**
|
||||
* @brief Get LIVELINESS_LOST status
|
||||
*
|
||||
* This operation gets the status value corresponding to LIVELINESS_LOST
|
||||
* and reset the status. The value can be obtained, only if the status is enabled for an entity.
|
||||
* NULL value for status is allowed and it will reset the trigger value when status is enabled.
|
||||
*
|
||||
* @param[in] writer The entity to get the status
|
||||
* @param[out] status The pointer to \ref DCPS_Status_LivelinessLost to get the status
|
||||
*
|
||||
* @returns 0 - Success
|
||||
* @returns <0 - Failure (use dds_err_nr() to get error value).
|
||||
*
|
||||
* @retval DDS_RETCODE_ERROR
|
||||
* An internal error has occurred.
|
||||
* @retval DDS_RETCODE_BAD_PARAMETER
|
||||
* One of the given arguments is not valid.
|
||||
* @retval DDS_RETCODE_ILLEGAL_OPERATION
|
||||
* The operation is invoked on an inappropriate object.
|
||||
* @retval DDS_RETCODE_ALREADY_DELETED
|
||||
* The entity has already been deleted.
|
||||
*/
|
||||
_Pre_satisfies_(((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER))
|
||||
DDS_EXPORT dds_return_t dds_get_liveliness_lost_status (
|
||||
_In_ dds_entity_t writer,
|
||||
_Out_opt_ dds_liveliness_lost_status_t * status);
|
||||
|
||||
/**
|
||||
* @brief Get OFFERED_DEADLINE_MISSED status
|
||||
*
|
||||
* This operation gets the status value corresponding to OFFERED_DEADLINE_MISSED
|
||||
* and reset the status. The value can be obtained, only if the status is enabled for an entity.
|
||||
* NULL value for status is allowed and it will reset the trigger value when status is enabled.
|
||||
*
|
||||
* @param[in] writer The entity to get the status
|
||||
* @param[out] status The pointer to \ref DCPS_Status_OfferedDeadlineMissed to get the status
|
||||
*
|
||||
* @returns 0 - Success
|
||||
* @returns <0 - Failure (use dds_err_nr() to get error value).
|
||||
*
|
||||
* @retval DDS_RETCODE_ERROR
|
||||
* An internal error has occurred.
|
||||
* @retval DDS_RETCODE_BAD_PARAMETER
|
||||
* One of the given arguments is not valid.
|
||||
* @retval DDS_RETCODE_ILLEGAL_OPERATION
|
||||
* The operation is invoked on an inappropriate object.
|
||||
* @retval DDS_RETCODE_ALREADY_DELETED
|
||||
* The entity has already been deleted.
|
||||
*/
|
||||
_Pre_satisfies_(((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER))
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_get_offered_deadline_missed_status(
|
||||
_In_ dds_entity_t writer,
|
||||
_Out_opt_ dds_offered_deadline_missed_status_t *status);
|
||||
|
||||
/**
|
||||
* @brief Get OFFERED_INCOMPATIBLE_QOS status
|
||||
*
|
||||
* This operation gets the status value corresponding to OFFERED_INCOMPATIBLE_QOS
|
||||
* and reset the status. The value can be obtained, only if the status is enabled for an entity.
|
||||
* NULL value for status is allowed and it will reset the trigger value when status is enabled.
|
||||
*
|
||||
* @param[in] writer The writer entity to get the status
|
||||
* @param[out] status The pointer to \ref DCPS_Status_OfferedIncompatibleQoS to get the status
|
||||
*
|
||||
* @returns 0 - Success
|
||||
* @returns <0 - Failure (use dds_err_nr() to get error value).
|
||||
*
|
||||
* @retval DDS_RETCODE_ERROR
|
||||
* An internal error has occurred.
|
||||
* @retval DDS_RETCODE_BAD_PARAMETER
|
||||
* One of the given arguments is not valid.
|
||||
* @retval DDS_RETCODE_ILLEGAL_OPERATION
|
||||
* The operation is invoked on an inappropriate object.
|
||||
* @retval DDS_RETCODE_ALREADY_DELETED
|
||||
* The entity has already been deleted.
|
||||
*/
|
||||
_Pre_satisfies_(((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER))
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_get_offered_incompatible_qos_status (
|
||||
_In_ dds_entity_t writer,
|
||||
_Out_opt_ dds_offered_incompatible_qos_status_t * status);
|
||||
|
||||
/**
|
||||
* @brief Get SUBSCRIPTION_MATCHED status
|
||||
*
|
||||
* This operation gets the status value corresponding to SUBSCRIPTION_MATCHED
|
||||
* and reset the status. The value can be obtained, only if the status is enabled for an entity.
|
||||
* NULL value for status is allowed and it will reset the trigger value when status is enabled.
|
||||
*
|
||||
* @param[in] reader The reader entity to get the status
|
||||
* @param[out] status The pointer to \ref DCPS_Status_SubscriptionMatched to get the status
|
||||
*
|
||||
* @returns 0 - Success
|
||||
* @returns <0 - Failure (use dds_err_nr() to get error value).
|
||||
*
|
||||
* @retval DDS_RETCODE_ERROR
|
||||
* An internal error has occurred.
|
||||
* @retval DDS_RETCODE_BAD_PARAMETER
|
||||
* One of the given arguments is not valid.
|
||||
* @retval DDS_RETCODE_ILLEGAL_OPERATION
|
||||
* The operation is invoked on an inappropriate object.
|
||||
* @retval DDS_RETCODE_ALREADY_DELETED
|
||||
* The entity has already been deleted.
|
||||
*/
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_get_subscription_matched_status (
|
||||
_In_ dds_entity_t reader,
|
||||
_Out_opt_ dds_subscription_matched_status_t * status);
|
||||
|
||||
/**
|
||||
* @brief Get LIVELINESS_CHANGED status
|
||||
*
|
||||
* This operation gets the status value corresponding to LIVELINESS_CHANGED
|
||||
* and reset the status. The value can be obtained, only if the status is enabled for an entity.
|
||||
* NULL value for status is allowed and it will reset the trigger value when status is enabled.
|
||||
*
|
||||
* @param[in] reader The entity to get the status
|
||||
* @param[out] status The pointer to \ref DCPS_Status_LivelinessChanged to get the status
|
||||
*
|
||||
* @returns 0 - Success
|
||||
* @returns <0 - Failure (use dds_err_nr() to get error value).
|
||||
*
|
||||
* @retval DDS_RETCODE_ERROR
|
||||
* An internal error has occurred.
|
||||
* @retval DDS_RETCODE_BAD_PARAMETER
|
||||
* One of the given arguments is not valid.
|
||||
* @retval DDS_RETCODE_ILLEGAL_OPERATION
|
||||
* The operation is invoked on an inappropriate object.
|
||||
* @retval DDS_RETCODE_ALREADY_DELETED
|
||||
* The entity has already been deleted.
|
||||
*/
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_get_liveliness_changed_status (
|
||||
_In_ dds_entity_t reader,
|
||||
_Out_opt_ dds_liveliness_changed_status_t * status);
|
||||
|
||||
/**
|
||||
* @brief Get SAMPLE_REJECTED status
|
||||
*
|
||||
* This operation gets the status value corresponding to SAMPLE_REJECTED
|
||||
* and reset the status. The value can be obtained, only if the status is enabled for an entity.
|
||||
* NULL value for status is allowed and it will reset the trigger value when status is enabled.
|
||||
*
|
||||
* @param[in] reader The entity to get the status
|
||||
* @param[out] status The pointer to \ref DCPS_Status_SampleRejected to get the status
|
||||
*
|
||||
* @returns 0 - Success
|
||||
* @returns <0 - Failure (use dds_err_nr() to get error value).
|
||||
*
|
||||
* @retval DDS_RETCODE_ERROR
|
||||
* An internal error has occurred.
|
||||
* @retval DDS_RETCODE_BAD_PARAMETER
|
||||
* One of the given arguments is not valid.
|
||||
* @retval DDS_RETCODE_ILLEGAL_OPERATION
|
||||
* The operation is invoked on an inappropriate object.
|
||||
* @retval DDS_RETCODE_ALREADY_DELETED
|
||||
* The entity has already been deleted.
|
||||
*/
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_get_sample_rejected_status (
|
||||
_In_ dds_entity_t reader,
|
||||
_Out_opt_ dds_sample_rejected_status_t * status);
|
||||
|
||||
/**
|
||||
* @brief Get SAMPLE_LOST status
|
||||
*
|
||||
* This operation gets the status value corresponding to SAMPLE_LOST
|
||||
* and reset the status. The value can be obtained, only if the status is enabled for an entity.
|
||||
* NULL value for status is allowed and it will reset the trigger value when status is enabled.
|
||||
*
|
||||
* @param[in] reader The entity to get the status
|
||||
* @param[out] status The pointer to \ref DCPS_Status_SampleLost to get the status
|
||||
*
|
||||
* @returns A dds_return_t indicating success or failure
|
||||
*
|
||||
* @retval DDS_RETCODE_OK
|
||||
* Success
|
||||
* @retval DDS_RETCODE_ERROR
|
||||
* An internal error has occurred.
|
||||
* @retval DDS_RETCODE_BAD_PARAMETER
|
||||
* One of the given arguments is not valid.
|
||||
* @retval DDS_RETCODE_ILLEGAL_OPERATION
|
||||
* The operation is invoked on an inappropriate object.
|
||||
* @retval DDS_RETCODE_ALREADY_DELETED
|
||||
* The entity has already been deleted.
|
||||
*/
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_get_sample_lost_status (
|
||||
_In_ dds_entity_t reader,
|
||||
_Out_opt_ dds_sample_lost_status_t * status);
|
||||
|
||||
/**
|
||||
* @brief Get REQUESTED_DEADLINE_MISSED status
|
||||
*
|
||||
* This operation gets the status value corresponding to REQUESTED_DEADLINE_MISSED
|
||||
* and reset the status. The value can be obtained, only if the status is enabled for an entity.
|
||||
* NULL value for status is allowed and it will reset the trigger value when status is enabled.
|
||||
*
|
||||
* @param[in] reader The entity to get the status
|
||||
* @param[out] status The pointer to \ref DCPS_Status_RequestedDeadlineMissed to get the status
|
||||
*
|
||||
* @returns A dds_return_t indicating success or failure
|
||||
*
|
||||
* @retval DDS_RETCODE_OK
|
||||
* Success
|
||||
* @retval DDS_RETCODE_ERROR
|
||||
* An internal error has occurred.
|
||||
* @retval DDS_RETCODE_BAD_PARAMETER
|
||||
* One of the given arguments is not valid.
|
||||
* @retval DDS_RETCODE_ILLEGAL_OPERATION
|
||||
* The operation is invoked on an inappropriate object.
|
||||
* @retval DDS_RETCODE_ALREADY_DELETED
|
||||
* The entity has already been deleted.
|
||||
*/
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_get_requested_deadline_missed_status (
|
||||
_In_ dds_entity_t reader,
|
||||
_Out_opt_ dds_requested_deadline_missed_status_t * status);
|
||||
|
||||
/**
|
||||
* @brief Get REQUESTED_INCOMPATIBLE_QOS status
|
||||
*
|
||||
* This operation gets the status value corresponding to REQUESTED_INCOMPATIBLE_QOS
|
||||
* and reset the status. The value can be obtained, only if the status is enabled for an entity.
|
||||
* NULL value for status is allowed and it will reset the trigger value when status is enabled.
|
||||
*
|
||||
* @param[in] reader The entity to get the status
|
||||
* @param[out] status The pointer to \ref DCPS_Status_RequestedIncompatibleQoS to get the status
|
||||
*
|
||||
* @returns A dds_return_t indicating success or failure
|
||||
*
|
||||
* @retval DDS_RETCODE_OK
|
||||
* Success
|
||||
* @retval DDS_RETCODE_ERROR
|
||||
* An internal error has occurred.
|
||||
* @retval DDS_RETCODE_BAD_PARAMETER
|
||||
* One of the given arguments is not valid.
|
||||
* @retval DDS_RETCODE_ILLEGAL_OPERATION
|
||||
* The operation is invoked on an inappropriate object.
|
||||
* @retval DDS_RETCODE_ALREADY_DELETED
|
||||
* The entity has already been deleted.
|
||||
*/
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_get_requested_incompatible_qos_status (
|
||||
_In_ dds_entity_t reader,
|
||||
_Out_opt_ dds_requested_incompatible_qos_status_t * status);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
101
src/core/ddsc/include/ddsc/dds_public_stream.h
Normal file
101
src/core/ddsc/include/ddsc/dds_public_stream.h
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/** @file
|
||||
*
|
||||
* @brief DDS C Stream API
|
||||
*
|
||||
* This header file defines the public API of the Streams in the
|
||||
* CycloneDDS C language binding.
|
||||
*/
|
||||
#ifndef DDS_STREAM_H
|
||||
#define DDS_STREAM_H
|
||||
|
||||
#include "os/os_public.h"
|
||||
#include <stdbool.h>
|
||||
#include "ddsc/dds_export.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct dds_sequence;
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint8_t * p8;
|
||||
uint16_t * p16;
|
||||
uint32_t * p32;
|
||||
uint64_t * p64;
|
||||
float * pf;
|
||||
double * pd;
|
||||
void * pv;
|
||||
}
|
||||
dds_uptr_t;
|
||||
|
||||
typedef struct dds_stream
|
||||
{
|
||||
dds_uptr_t m_buffer; /* Union of pointers to start of buffer */
|
||||
size_t m_size; /* Buffer size */
|
||||
size_t m_index; /* Read/write offset from start of buffer */
|
||||
bool m_endian; /* Endian: big (false) or little (true) */
|
||||
bool m_failed; /* Attempt made to read beyond end of buffer */
|
||||
}
|
||||
dds_stream_t;
|
||||
|
||||
#define DDS_STREAM_BE false
|
||||
#define DDS_STREAM_LE true
|
||||
|
||||
DDS_EXPORT dds_stream_t * dds_stream_create (size_t size);
|
||||
DDS_EXPORT void dds_stream_delete (dds_stream_t * st);
|
||||
DDS_EXPORT void dds_stream_fini (dds_stream_t * st);
|
||||
DDS_EXPORT void dds_stream_reset (dds_stream_t * st);
|
||||
DDS_EXPORT void dds_stream_init (dds_stream_t * st, size_t size);
|
||||
DDS_EXPORT void dds_stream_grow (dds_stream_t * st, size_t size);
|
||||
DDS_EXPORT bool dds_stream_endian (void);
|
||||
|
||||
DDS_EXPORT bool dds_stream_read_bool (dds_stream_t * is);
|
||||
DDS_EXPORT uint8_t dds_stream_read_uint8 (dds_stream_t * is);
|
||||
DDS_EXPORT uint16_t dds_stream_read_uint16 (dds_stream_t * is);
|
||||
DDS_EXPORT uint32_t dds_stream_read_uint32 (dds_stream_t * is);
|
||||
DDS_EXPORT uint64_t dds_stream_read_uint64 (dds_stream_t * is);
|
||||
DDS_EXPORT float dds_stream_read_float (dds_stream_t * is);
|
||||
DDS_EXPORT double dds_stream_read_double (dds_stream_t * is);
|
||||
DDS_EXPORT char * dds_stream_read_string (dds_stream_t * is);
|
||||
DDS_EXPORT void dds_stream_read_buffer (dds_stream_t * is, uint8_t * buffer, uint32_t len);
|
||||
|
||||
#define dds_stream_read_char(s) ((char) dds_stream_read_uint8 (s))
|
||||
#define dds_stream_read_int8(s) ((int8_t) dds_stream_read_uint8 (s))
|
||||
#define dds_stream_read_int16(s) ((int16_t) dds_stream_read_uint16 (s))
|
||||
#define dds_stream_read_int32(s) ((int32_t) dds_stream_read_uint32 (s))
|
||||
#define dds_stream_read_int64(s) ((int64_t) dds_stream_read_uint64 (s))
|
||||
|
||||
DDS_EXPORT void dds_stream_write_bool (dds_stream_t * os, bool val);
|
||||
DDS_EXPORT void dds_stream_write_uint8 (dds_stream_t * os, uint8_t val);
|
||||
DDS_EXPORT void dds_stream_write_uint16 (dds_stream_t * os, uint16_t val);
|
||||
DDS_EXPORT void dds_stream_write_uint32 (dds_stream_t * os, uint32_t val);
|
||||
DDS_EXPORT void dds_stream_write_uint64 (dds_stream_t * os, uint64_t val);
|
||||
DDS_EXPORT void dds_stream_write_float (dds_stream_t * os, float val);
|
||||
DDS_EXPORT void dds_stream_write_double (dds_stream_t * os, double val);
|
||||
DDS_EXPORT void dds_stream_write_string (dds_stream_t * os, const char * val);
|
||||
DDS_EXPORT void dds_stream_write_buffer (dds_stream_t * os, uint32_t len, uint8_t * buffer);
|
||||
|
||||
#define dds_stream_write_char(s,v) (dds_stream_write_uint8 ((s), (uint8_t)(v)))
|
||||
#define dds_stream_write_int8(s,v) (dds_stream_write_uint8 ((s), (uint8_t)(v)))
|
||||
#define dds_stream_write_int16(s,v) (dds_stream_write_uint16 ((s), (uint16_t)(v)))
|
||||
#define dds_stream_write_int32(s,v) (dds_stream_write_uint32 ((s), (uint32_t)(v)))
|
||||
#define dds_stream_write_int64(s,v) (dds_stream_write_uint64 ((s), (uint64_t)(v)))
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
96
src/core/ddsc/include/ddsc/dds_public_time.h
Normal file
96
src/core/ddsc/include/ddsc/dds_public_time.h
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/** @file
|
||||
*
|
||||
* @brief DDS C Time support API
|
||||
*
|
||||
* This header file defines the public API of the in the
|
||||
* CycloneDDS C language binding.
|
||||
*/
|
||||
#ifndef DDS_TIME_H
|
||||
#define DDS_TIME_H
|
||||
|
||||
#include "os/os_public.h"
|
||||
#include "ddsc/dds_export.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Times are represented using a 64-bit signed integer, encoding
|
||||
nanoseconds since the epoch. Considering the nature of these
|
||||
systems, one would best use TAI, International Atomic Time, rather
|
||||
than something UTC, but availability may be limited.
|
||||
|
||||
Valid times are non-negative and times up to 2**63-2 can be
|
||||
represented. 2**63-1 is defined to represent, essentially, "never".
|
||||
This is good enough for a couple of centuries.
|
||||
*/
|
||||
|
||||
/** Absolute Time definition */
|
||||
typedef int64_t dds_time_t;
|
||||
|
||||
/** Relative Time definition */
|
||||
typedef int64_t dds_duration_t;
|
||||
|
||||
/** @name Macro definition for time units in nanoseconds.
|
||||
@{**/
|
||||
#define DDS_NSECS_IN_SEC 1000000000LL
|
||||
#define DDS_NSECS_IN_MSEC 1000000LL
|
||||
#define DDS_NSECS_IN_USEC 1000LL
|
||||
/** @}*/
|
||||
|
||||
/** @name Infinite timeout for indicate absolute time */
|
||||
#define DDS_NEVER ((dds_time_t) INT64_MAX)
|
||||
|
||||
/** @name Infinite timeout for relative time */
|
||||
#define DDS_INFINITY ((dds_duration_t) INT64_MAX)
|
||||
|
||||
/** @name Macro definition for time conversion from nanoseconds
|
||||
@{**/
|
||||
#define DDS_SECS(n) ((n) * DDS_NSECS_IN_SEC)
|
||||
#define DDS_MSECS(n) ((n) * DDS_NSECS_IN_MSEC)
|
||||
#define DDS_USECS(n) ((n) * DDS_NSECS_IN_USEC)
|
||||
/** @}*/
|
||||
|
||||
/**
|
||||
* Description : This operation returns the current time (in nanoseconds)
|
||||
*
|
||||
* Arguments :
|
||||
* -# Returns current time
|
||||
*/
|
||||
DDS_EXPORT dds_time_t dds_time (void);
|
||||
|
||||
/**
|
||||
* Description : This operation blocks the calling thread until the relative time
|
||||
* n has elapsed
|
||||
*
|
||||
* Arguments :
|
||||
* -# n Relative Time to block a thread
|
||||
*/
|
||||
DDS_EXPORT void dds_sleepfor (dds_duration_t n);
|
||||
|
||||
/**
|
||||
* Description : This operation blocks the calling thread until the absolute time
|
||||
* n has elapsed
|
||||
*
|
||||
* Arguments :
|
||||
* -# n absolute Time to block a thread
|
||||
*/
|
||||
DDS_EXPORT void dds_sleepuntil (dds_time_t n);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
2927
src/core/ddsc/include/ddsc/ddsv2.h
Normal file
2927
src/core/ddsc/include/ddsc/ddsv2.h
Normal file
File diff suppressed because it is too large
Load diff
26
src/core/ddsc/src/dds__alloc.h
Normal file
26
src/core/ddsc/src/dds__alloc.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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 _DDS_ALLOC_H_
|
||||
#define _DDS_ALLOC_H_
|
||||
|
||||
#include "dds__types.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void dds_sample_free_contents (char * data, const uint32_t * ops);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
72
src/core/ddsc/src/dds__builtin.h
Normal file
72
src/core/ddsc/src/dds__builtin.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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 _DDS_BUILTIN_H_
|
||||
#define _DDS_BUILTIN_H_
|
||||
|
||||
#include "ddsi/q_time.h"
|
||||
#include "dds_builtinTopics.h"
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Get actual topic in related participant related to topic 'id'. */
|
||||
_Must_inspect_result_ dds_entity_t
|
||||
dds__get_builtin_topic(
|
||||
_In_ dds_entity_t e,
|
||||
_In_ dds_entity_t topic);
|
||||
|
||||
/* Global publisher singleton (publishes only locally). */
|
||||
_Must_inspect_result_ dds_entity_t
|
||||
dds__get_builtin_publisher(
|
||||
void);
|
||||
|
||||
/* Subscriber singleton within related participant. */
|
||||
_Must_inspect_result_ dds_entity_t
|
||||
dds__get_builtin_subscriber(
|
||||
_In_ dds_entity_t e);
|
||||
|
||||
|
||||
|
||||
/* Initialization and finalize functions. */
|
||||
void
|
||||
dds__builtin_init(
|
||||
void);
|
||||
|
||||
void
|
||||
dds__builtin_fini(
|
||||
void);
|
||||
|
||||
|
||||
|
||||
/* Callback functions that contain received builtin data. */
|
||||
void
|
||||
dds__builtin_participant_cb(
|
||||
DDS_ParticipantBuiltinTopicData *data,
|
||||
nn_wctime_t timestamp);
|
||||
|
||||
void
|
||||
dds__builtin_cmparticipant_cb(
|
||||
DDS_CMParticipantBuiltinTopicData *data,
|
||||
nn_wctime_t timestamp);
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _DDS_BUILTIN_H_ */
|
||||
|
||||
30
src/core/ddsc/src/dds__domain.h
Normal file
30
src/core/ddsc/src/dds__domain.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 _DDS_DOMAIN_H_
|
||||
#define _DDS_DOMAIN_H_
|
||||
|
||||
#include "dds__types.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const ut_avlTreedef_t dds_domaintree_def;
|
||||
|
||||
extern dds_domain * dds_domain_create (dds_domainid_t id);
|
||||
extern void dds_domain_free (dds_domain * domain);
|
||||
extern dds_domain * dds_domain_find_locked (dds_domainid_t id);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
114
src/core/ddsc/src/dds__entity.h
Normal file
114
src/core/ddsc/src/dds__entity.h
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* 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 _DDS_ENTITY_H_
|
||||
#define _DDS_ENTITY_H_
|
||||
|
||||
#include "dds__types.h"
|
||||
#include "ddsi/q_thread.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
_Check_return_ dds_entity_t
|
||||
dds_entity_init(
|
||||
_In_ dds_entity * e,
|
||||
_When_(kind != DDS_KIND_PARTICIPANT, _Notnull_)
|
||||
_When_(kind == DDS_KIND_PARTICIPANT, _Null_)
|
||||
_In_opt_ dds_entity * parent,
|
||||
_In_ dds_entity_kind_t kind,
|
||||
_In_opt_ dds_qos_t * qos,
|
||||
_In_opt_ const dds_listener_t *listener,
|
||||
_In_ uint32_t mask);
|
||||
|
||||
void
|
||||
dds_entity_add_ref(
|
||||
_In_ dds_entity *e);
|
||||
void
|
||||
dds_entity_add_ref_nolock(
|
||||
_In_ dds_entity *e);
|
||||
|
||||
_Check_return_ dds__retcode_t
|
||||
dds_entity_listener_propagation(
|
||||
_Inout_opt_ dds_entity *e,
|
||||
_In_ dds_entity *src,
|
||||
_In_ uint32_t status,
|
||||
_In_opt_ void *metrics,
|
||||
_In_ bool propagate);
|
||||
|
||||
#define dds_entity_is_enabled(e, k) (((dds_entity*)e)->m_flags & DDS_ENTITY_ENABLED)
|
||||
|
||||
#define dds_entity_status_set(e, t) (((dds_entity*)e)->m_trigger |= (((dds_entity*)e)->m_status_enable & t))
|
||||
#define dds_entity_status_reset(e,t) (((dds_entity*)e)->m_trigger &= ~t)
|
||||
#define dds_entity_status_match(e,t) (((dds_entity*)e)->m_trigger & t)
|
||||
|
||||
/* The mutex needs to be unlocked when calling this because the entity can be called
|
||||
* within the signal callback from other contexts. That shouldn't deadlock. */
|
||||
void
|
||||
dds_entity_status_signal(
|
||||
_In_ dds_entity *e);
|
||||
|
||||
_Check_return_ dds__retcode_t
|
||||
dds_valid_hdl(
|
||||
_In_ dds_entity_t hdl,
|
||||
_In_ dds_entity_kind_t kind);
|
||||
|
||||
_Acquires_exclusive_lock_(*e)
|
||||
_Check_return_ dds__retcode_t
|
||||
dds_entity_lock(
|
||||
_In_ dds_entity_t hdl,
|
||||
_In_ dds_entity_kind_t kind,
|
||||
_Out_ dds_entity **e);
|
||||
|
||||
_Releases_exclusive_lock_(e)
|
||||
void
|
||||
dds_entity_unlock(
|
||||
_Inout_ dds_entity *e);
|
||||
|
||||
#define dds_entity_kind(hdl) ((hdl > 0) ? (hdl & DDS_ENTITY_KIND_MASK) : 0)
|
||||
|
||||
_Check_return_ dds__retcode_t
|
||||
dds_entity_observer_register_nl(
|
||||
_In_ dds_entity* observed,
|
||||
_In_ dds_entity_t observer,
|
||||
_In_ dds_entity_callback cb);
|
||||
|
||||
_Check_return_ dds__retcode_t
|
||||
dds_entity_observer_register(
|
||||
_In_ dds_entity_t observed,
|
||||
_In_ dds_entity_t observer,
|
||||
_In_ dds_entity_callback cb);
|
||||
|
||||
dds__retcode_t
|
||||
dds_entity_observer_unregister_nl(
|
||||
_In_ dds_entity* observed,
|
||||
_In_ dds_entity_t observer);
|
||||
|
||||
dds__retcode_t
|
||||
dds_entity_observer_unregister(
|
||||
_In_ dds_entity_t observed,
|
||||
_In_ dds_entity_t observer);
|
||||
|
||||
_Pre_satisfies_(entity & DDS_ENTITY_KIND_MASK)
|
||||
dds_return_t
|
||||
dds_delete_impl(
|
||||
_In_ dds_entity_t entity,
|
||||
_In_ bool keep_if_explicit);
|
||||
|
||||
const char *
|
||||
dds__entity_kind_str(
|
||||
_In_ dds_entity_t e);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
41
src/core/ddsc/src/dds__err.h
Normal file
41
src/core/ddsc/src/dds__err.h
Normal 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 _DDS_ERR_H_
|
||||
#define _DDS_ERR_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include "os/os.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* To construct return status
|
||||
* Use '+' instead of '|'. Otherwise, the SAL checking doesn't
|
||||
* understand when a return value is negative or positive and
|
||||
* complains a lot about "A successful path through the function
|
||||
* does not set the named _Out_ parameter." */
|
||||
#if !defined(__FILE_ID__)
|
||||
#error "__FILE_ID__ not defined"
|
||||
#endif
|
||||
|
||||
#define DDS__FILE_ID__ (((__FILE_ID__ & 0x1ff)) << 22)
|
||||
#define DDS__LINE__ ((__LINE__ & 0x3fff) << 8)
|
||||
|
||||
#define DDS_ERR_NO(err) -(DDS__FILE_ID__ + DDS__LINE__ + (err))
|
||||
|
||||
#define DDS_ERRNO(e,msg,...) (assert(e > DDS_RETCODE_OK), os_report(OS_REPORT_ERROR, OS_FUNCTION, __FILE__, __LINE__, DDS_ERR_NO(e), (msg), ##__VA_ARGS__), DDS_ERR_NO(e))
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
28
src/core/ddsc/src/dds__iid.h
Normal file
28
src/core/ddsc/src/dds__iid.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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 _DDS_IID_H_
|
||||
#define _DDS_IID_H_
|
||||
|
||||
#include "dds__types.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void dds_iid_init (void);
|
||||
void dds_iid_fini (void);
|
||||
uint64_t dds_iid_gen (void);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
78
src/core/ddsc/src/dds__init.h
Normal file
78
src/core/ddsc/src/dds__init.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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 _DDS_INIT_H_
|
||||
#define _DDS_INIT_H_
|
||||
|
||||
#include "dds__types.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
dds_return_t
|
||||
dds__check_domain(
|
||||
_In_ dds_domainid_t domain);
|
||||
|
||||
/**
|
||||
*Description : Initialization function. This operation initializes all the
|
||||
*required resources that are needed for the DDSC API process lifecycle
|
||||
*(like the init mutex and os layer).
|
||||
*A function will be registered that is called at the end of the process
|
||||
*lifecycle and will destroy the resources initialized in this function.
|
||||
**/
|
||||
void
|
||||
dds__startup(void);
|
||||
|
||||
/**
|
||||
*Description : Initialization function, called from main. This operation
|
||||
*initializes all the required DDS resources,
|
||||
*handles configuration of domainid based on the input passed, parses and
|
||||
*configures middleware from a xml file and initializes required resources.
|
||||
*
|
||||
*Arguments :
|
||||
*-# Returns 0 on success or a non-zero error status
|
||||
**/
|
||||
dds_return_t
|
||||
dds_init(void);
|
||||
|
||||
/* Finalization function, called from main */
|
||||
|
||||
/**
|
||||
*Description : Finalization function, called from main. This operation
|
||||
*releases all the resources used by DDS.
|
||||
*
|
||||
*Arguments :
|
||||
*-# None
|
||||
**/
|
||||
void
|
||||
dds_fini(void);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Description : Function that provides the explicit ID of default domain
|
||||
* It should be called after DDS initialization.
|
||||
* @return Valid domain id. Undetermined behaviour if DDS is not initialized.
|
||||
*/
|
||||
dds_domainid_t dds_domain_default (void);
|
||||
|
||||
|
||||
/**
|
||||
* Description : Mutex used for initialization synchronization.
|
||||
*/
|
||||
extern os_mutex dds__init_mutex;
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
35
src/core/ddsc/src/dds__key.h
Normal file
35
src/core/ddsc/src/dds__key.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 _DDS_KEY_H_
|
||||
#define _DDS_KEY_H_
|
||||
|
||||
#include "dds__types.h"
|
||||
|
||||
struct dds_key_hash;
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void dds_key_md5 (struct dds_key_hash * kh);
|
||||
|
||||
void dds_key_gen
|
||||
(
|
||||
const dds_topic_descriptor_t * const desc,
|
||||
struct dds_key_hash * kh,
|
||||
const char * sample
|
||||
);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
31
src/core/ddsc/src/dds__listener.h
Normal file
31
src/core/ddsc/src/dds__listener.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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 _DDS_LISTENER_H_
|
||||
#define _DDS_LISTENER_H_
|
||||
|
||||
#include "dds__types.h"
|
||||
#include "ddsc/dds_public_listener.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Listener API (internal & external) are present in
|
||||
* dds__types.h
|
||||
* ddsc/dds_public_listener.h
|
||||
*/
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
23
src/core/ddsc/src/dds__participant.h
Normal file
23
src/core/ddsc/src/dds__participant.h
Normal 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
|
||||
*/
|
||||
#ifndef _DDS_PPANT_H_
|
||||
#define _DDS_PPANT_H_
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
27
src/core/ddsc/src/dds__publisher.h
Normal file
27
src/core/ddsc/src/dds__publisher.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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 _DDS_PUBLISHER_H_
|
||||
#define _DDS_PUBLISHER_H_
|
||||
|
||||
#include "ddsc/dds.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
dds_return_t dds_publisher_begin_coherent (dds_entity_t e);
|
||||
dds_return_t dds_publisher_end_coherent (dds_entity_t e);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif /* _DDS_PUBLISHER_H_ */
|
||||
37
src/core/ddsc/src/dds__qos.h
Normal file
37
src/core/ddsc/src/dds__qos.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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 _DDS_QOS_H_
|
||||
#define _DDS_QOS_H_
|
||||
|
||||
#include "dds__entity.h"
|
||||
#include "ddsi/q_xqos.h"
|
||||
#include "ddsi/q_time.h"
|
||||
#include "ddsi/q_plist.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool validate_deadline_and_timebased_filter (const nn_duration_t deadline, const nn_duration_t minimum_separation);
|
||||
bool validate_entityfactory_qospolicy (const nn_entity_factory_qospolicy_t * entityfactory);
|
||||
bool validate_octetseq (const nn_octetseq_t* seq);
|
||||
bool validate_partition_qospolicy (_In_ const nn_partition_qospolicy_t * partition);
|
||||
bool validate_reliability_qospolicy (const nn_reliability_qospolicy_t * reliability);
|
||||
bool validate_stringseq (const nn_stringseq_t* seq);
|
||||
|
||||
bool dds_qos_validate_common (const dds_qos_t *qos);
|
||||
dds_return_t dds_qos_validate_mutable_common (_In_ const dds_qos_t *qos);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
23
src/core/ddsc/src/dds__querycond.h
Normal file
23
src/core/ddsc/src/dds__querycond.h
Normal 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
|
||||
*/
|
||||
#ifndef _DDS_QUERYCOND_H_
|
||||
#define _DDS_QUERYCOND_H_
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
23
src/core/ddsc/src/dds__readcond.h
Normal file
23
src/core/ddsc/src/dds__readcond.h
Normal 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
|
||||
*/
|
||||
#ifndef _DDS_READCOND_H_
|
||||
#define _DDS_READCOND_H_
|
||||
|
||||
#include "dds__entity.h"
|
||||
|
||||
_Must_inspect_result_ dds_readcond*
|
||||
dds_create_readcond(
|
||||
_In_ dds_reader *rd,
|
||||
_In_ dds_entity_kind_t kind,
|
||||
_In_ uint32_t mask);
|
||||
|
||||
#endif
|
||||
49
src/core/ddsc/src/dds__reader.h
Normal file
49
src/core/ddsc/src/dds__reader.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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 _DDS_READER_H_
|
||||
#define _DDS_READER_H_
|
||||
|
||||
#include "dds__types.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct status_cb_data;
|
||||
|
||||
void dds_reader_status_cb (void * entity, const struct status_cb_data * data);
|
||||
|
||||
/*
|
||||
dds_reader_lock_samples: Returns number of samples in read cache and locks the
|
||||
reader cache to make sure that the samples content doesn't change.
|
||||
Because the cache is locked, you should be able to read/take without having to
|
||||
lock first. This is done by passing the DDS_READ_WITHOUT_LOCK value to the
|
||||
read/take call as maxs. Then the read/take will not lock but still unlock.
|
||||
|
||||
See also CHAM-287, CHAM-306 and LITE-1183.
|
||||
|
||||
Used to support LENGTH_UNLIMITED in C++.
|
||||
*/
|
||||
#define DDS_READ_WITHOUT_LOCK (0xFFFFFFED)
|
||||
DDS_EXPORT uint32_t dds_reader_lock_samples (dds_entity_t entity);
|
||||
|
||||
struct nn_rsample_info;
|
||||
struct nn_rdata;
|
||||
DDS_EXPORT void dds_reader_ddsi2direct (dds_entity_t entity, void (*cb) (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, void *arg), void *cbarg);
|
||||
|
||||
#define dds_reader_lock(hdl, obj) dds_entity_lock(hdl, DDS_KIND_READER, (dds_entity**)obj)
|
||||
#define dds_reader_unlock(obj) dds_entity_unlock((dds_entity*)obj);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
78
src/core/ddsc/src/dds__report.h
Normal file
78
src/core/ddsc/src/dds__report.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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 DDS_REPORT_H
|
||||
#define DDS_REPORT_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "os/os_report.h"
|
||||
|
||||
#define DDS_REPORT_STACK() \
|
||||
os_report_stack ()
|
||||
|
||||
#define DDS_CRITICAL(...) \
|
||||
dds_report ( \
|
||||
OS_REPORT_CRITICAL, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
OS_FUNCTION, \
|
||||
DDS_RETCODE_ERROR, \
|
||||
__VA_ARGS__)
|
||||
|
||||
#define DDS_ERROR(code,...) \
|
||||
dds_report ( \
|
||||
OS_REPORT_ERROR, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
OS_FUNCTION, \
|
||||
(code), \
|
||||
__VA_ARGS__)
|
||||
|
||||
#define DDS_INFO(...) \
|
||||
dds_report ( \
|
||||
OS_REPORT_INFO, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
OS_FUNCTION, \
|
||||
DDS_RETCODE_OK, \
|
||||
__VA_ARGS__)
|
||||
|
||||
#define DDS_WARNING(code,...) \
|
||||
dds_report ( \
|
||||
OS_REPORT_WARNING, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
OS_FUNCTION, \
|
||||
(code), \
|
||||
__VA_ARGS__)
|
||||
|
||||
#define DDS_REPORT(type, code,...) \
|
||||
dds_report ( \
|
||||
type, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
OS_FUNCTION, \
|
||||
(code), \
|
||||
__VA_ARGS__)
|
||||
|
||||
#define DDS_REPORT_FLUSH OS_REPORT_FLUSH
|
||||
|
||||
void
|
||||
dds_report(
|
||||
os_reportType reportType,
|
||||
const char *file,
|
||||
int32_t line,
|
||||
const char *function,
|
||||
dds_return_t code,
|
||||
const char *format,
|
||||
...);
|
||||
|
||||
#endif
|
||||
86
src/core/ddsc/src/dds__rhc.h
Normal file
86
src/core/ddsc/src/dds__rhc.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* 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 _DDS_RHC_H_
|
||||
#define _DDS_RHC_H_
|
||||
|
||||
#include "os/os_defs.h"
|
||||
|
||||
#define NO_STATE_MASK_SET (DDS_ANY_STATE + 1)
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct rhc;
|
||||
struct nn_xqos;
|
||||
struct serdata;
|
||||
struct tkmap_instance;
|
||||
struct tkmap;
|
||||
struct nn_rsample_info;
|
||||
struct proxy_writer_info;
|
||||
|
||||
struct rhc * dds_rhc_new (dds_reader * reader, const struct sertopic * topic);
|
||||
void dds_rhc_free (struct rhc * rhc);
|
||||
void dds_rhc_fini (struct rhc * rhc);
|
||||
|
||||
uint32_t dds_rhc_lock_samples (struct rhc * rhc);
|
||||
|
||||
DDS_EXPORT bool dds_rhc_store
|
||||
(
|
||||
struct rhc * __restrict rhc, const struct nn_rsample_info * __restrict sampleinfo,
|
||||
struct serdata * __restrict sample, struct tkmap_instance * __restrict tk
|
||||
);
|
||||
void dds_rhc_unregister_wr (struct rhc * __restrict rhc, const struct proxy_writer_info * __restrict pwr_info);
|
||||
void dds_rhc_relinquish_ownership (struct rhc * __restrict rhc, const uint64_t wr_iid);
|
||||
|
||||
int
|
||||
dds_rhc_read(
|
||||
struct rhc *rhc,
|
||||
bool lock,
|
||||
void ** values,
|
||||
dds_sample_info_t *info_seq,
|
||||
uint32_t max_samples,
|
||||
uint32_t mask,
|
||||
dds_instance_handle_t handle,
|
||||
dds_readcond *cond);
|
||||
int
|
||||
dds_rhc_take(
|
||||
struct rhc *rhc,
|
||||
bool lock,
|
||||
void ** values,
|
||||
dds_sample_info_t *info_seq,
|
||||
uint32_t max_samples,
|
||||
uint32_t mask,
|
||||
dds_instance_handle_t handle,
|
||||
dds_readcond *cond);
|
||||
|
||||
void dds_rhc_set_qos (struct rhc * rhc, const struct nn_xqos * qos);
|
||||
|
||||
void dds_rhc_add_readcondition (dds_readcond * cond);
|
||||
void dds_rhc_remove_readcondition (dds_readcond * cond);
|
||||
|
||||
bool dds_rhc_add_waitset (dds_readcond * cond, dds_waitset * waitset, dds_attach_t x);
|
||||
int dds_rhc_remove_waitset (dds_readcond * cond, dds_waitset * waitset);
|
||||
|
||||
int dds_rhc_takecdr
|
||||
(
|
||||
struct rhc *rhc, bool lock, struct serdata **values, dds_sample_info_t *info_seq,
|
||||
uint32_t max_samples, unsigned sample_states,
|
||||
unsigned view_states, unsigned instance_states,
|
||||
dds_instance_handle_t handle
|
||||
);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
88
src/core/ddsc/src/dds__stream.h
Normal file
88
src/core/ddsc/src/dds__stream.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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 _DDS_STREAM_H_
|
||||
#define _DDS_STREAM_H_
|
||||
|
||||
#include "ddsi/ddsi_ser.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void dds_stream_write_sample
|
||||
(
|
||||
dds_stream_t * os,
|
||||
const void * data,
|
||||
const struct sertopic * topic
|
||||
);
|
||||
void dds_stream_read_sample
|
||||
(
|
||||
dds_stream_t * is,
|
||||
void * data,
|
||||
const struct sertopic * topic
|
||||
);
|
||||
|
||||
size_t dds_stream_check_optimize (_In_ const dds_topic_descriptor_t * desc);
|
||||
void dds_stream_from_serstate (_Out_ dds_stream_t * s, _In_ const serstate_t st);
|
||||
void dds_stream_add_to_serstate (_Inout_ dds_stream_t * s, _Inout_ serstate_t st);
|
||||
|
||||
void dds_stream_write_key
|
||||
(
|
||||
dds_stream_t * os,
|
||||
const char * sample,
|
||||
const dds_topic_descriptor_t * desc
|
||||
);
|
||||
void dds_stream_read_key
|
||||
(
|
||||
dds_stream_t * is,
|
||||
char * sample,
|
||||
const dds_topic_descriptor_t * desc
|
||||
);
|
||||
void dds_stream_read_keyhash
|
||||
(
|
||||
dds_stream_t * is,
|
||||
dds_key_hash_t * kh,
|
||||
const dds_topic_descriptor_t * desc,
|
||||
const bool just_key
|
||||
);
|
||||
char * dds_stream_reuse_string
|
||||
(
|
||||
dds_stream_t * is,
|
||||
char * str,
|
||||
const uint32_t bound
|
||||
);
|
||||
DDS_EXPORT void dds_stream_swap (void * buff, uint32_t size, uint32_t num);
|
||||
|
||||
extern const uint32_t dds_op_size[5];
|
||||
|
||||
/* For marshalling op code handling */
|
||||
|
||||
#define DDS_OP_MASK 0xff000000
|
||||
#define DDS_OP_TYPE_MASK 0x00ff0000
|
||||
#define DDS_OP_SUBTYPE_MASK 0x0000ff00
|
||||
#define DDS_OP_JMP_MASK 0x0000ffff
|
||||
#define DDS_OP_FLAGS_MASK 0x000000ff
|
||||
#define DDS_JEQ_TYPE_MASK 0x00ff0000
|
||||
|
||||
#define DDS_OP(o) ((o) & DDS_OP_MASK)
|
||||
#define DDS_OP_TYPE(o) (((o) & DDS_OP_TYPE_MASK) >> 16)
|
||||
#define DDS_OP_SUBTYPE(o) (((o) & DDS_OP_SUBTYPE_MASK) >> 8)
|
||||
#define DDS_OP_FLAGS(o) ((o) & DDS_OP_FLAGS_MASK)
|
||||
#define DDS_OP_ADR_JSR(o) ((o) & DDS_OP_JMP_MASK)
|
||||
#define DDS_OP_JUMP(o) ((int16_t) ((o) & DDS_OP_JMP_MASK))
|
||||
#define DDS_OP_ADR_JMP(o) ((o) >> 16)
|
||||
#define DDS_JEQ_TYPE(o) (((o) & DDS_JEQ_TYPE_MASK) >> 16)
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
41
src/core/ddsc/src/dds__subscriber.h
Normal file
41
src/core/ddsc/src/dds__subscriber.h
Normal 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 _DDS_SUBSCRIBER_H_
|
||||
#define _DDS_SUBSCRIBER_H_
|
||||
|
||||
#include "ddsc/dds.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct dds_entity;
|
||||
|
||||
_Requires_exclusive_lock_held_(participant)
|
||||
_Check_return_ dds_entity_t
|
||||
dds__create_subscriber_l(
|
||||
_Inout_ struct dds_entity *participant, /* entity-lock must be held */
|
||||
_In_opt_ const dds_qos_t *qos,
|
||||
_In_opt_ const dds_listener_t *listener);
|
||||
|
||||
dds_return_t
|
||||
dds_subscriber_begin_coherent(
|
||||
_In_ dds_entity_t e);
|
||||
|
||||
dds_return_t
|
||||
dds_subscriber_end_coherent (
|
||||
_In_ dds_entity_t e);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif /* _DDS_SUBSCRIBER_H_ */
|
||||
53
src/core/ddsc/src/dds__tkmap.h
Normal file
53
src/core/ddsc/src/dds__tkmap.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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 _DDS_TKMAP_H_
|
||||
#define _DDS_TKMAP_H_
|
||||
|
||||
#include "dds__types.h"
|
||||
#include "os/os_atomics.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct tkmap;
|
||||
struct serdata;
|
||||
struct dds_topic;
|
||||
|
||||
struct tkmap_instance
|
||||
{
|
||||
struct serdata * m_sample;
|
||||
struct tkmap * m_map;
|
||||
uint64_t m_iid;
|
||||
os_atomic_uint32_t m_refc;
|
||||
};
|
||||
|
||||
|
||||
struct tkmap * dds_tkmap_new (void);
|
||||
void dds_tkmap_free (_Inout_ _Post_invalid_ struct tkmap *tkmap);
|
||||
void dds_tkmap_instance_ref (_In_ struct tkmap_instance *tk);
|
||||
uint64_t dds_tkmap_lookup (_In_ struct tkmap *tkmap, _In_ const struct serdata *serdata);
|
||||
_Check_return_ bool dds_tkmap_get_key (_In_ struct tkmap * map, _In_ uint64_t iid, _Out_ void * sample);
|
||||
_Check_return_ struct tkmap_instance * dds_tkmap_find(
|
||||
_In_opt_ const struct dds_topic * topic,
|
||||
_In_ struct serdata * sd,
|
||||
_In_ const bool rd,
|
||||
_In_ const bool create);
|
||||
_Check_return_ struct tkmap_instance * dds_tkmap_find_by_id (_In_ struct tkmap * map, _In_ uint64_t iid);
|
||||
|
||||
DDS_EXPORT _Check_return_ struct tkmap_instance * dds_tkmap_lookup_instance_ref (_In_ struct serdata * sd);
|
||||
DDS_EXPORT void dds_tkmap_instance_unref (_In_ struct tkmap_instance * tk);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
41
src/core/ddsc/src/dds__topic.h
Normal file
41
src/core/ddsc/src/dds__topic.h
Normal 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 _DDS_TOPIC_H_
|
||||
#define _DDS_TOPIC_H_
|
||||
|
||||
#include "dds__types.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define dds_topic_lock(hdl, obj) dds_entity_lock(hdl, DDS_KIND_TOPIC, (dds_entity**)obj)
|
||||
#define dds_topic_unlock(obj) dds_entity_unlock((dds_entity*)obj);
|
||||
|
||||
extern struct sertopic * dds_topic_lookup (dds_domain * domain, const char * name);
|
||||
extern void dds_topic_free (dds_domainid_t domainid, struct sertopic * st);
|
||||
|
||||
#ifndef DDS_TOPIC_INTERN_FILTER_FN_DEFINED
|
||||
#define DDS_TOPIC_INTERN_FILTER_FN_DEFINED
|
||||
typedef bool (*dds_topic_intern_filter_fn) (const void * sample, void *ctx);
|
||||
#endif
|
||||
|
||||
DDS_EXPORT void dds_topic_set_filter_with_ctx
|
||||
(dds_entity_t topic, dds_topic_intern_filter_fn filter, void *ctx);
|
||||
|
||||
DDS_EXPORT dds_topic_intern_filter_fn dds_topic_get_filter_with_ctx
|
||||
(dds_entity_t topic);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
273
src/core/ddsc/src/dds__types.h
Normal file
273
src/core/ddsc/src/dds__types.h
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
* 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 _DDS_TYPES_H_
|
||||
#define _DDS_TYPES_H_
|
||||
|
||||
/* DDS internal type definitions */
|
||||
|
||||
#include "os/os.h"
|
||||
#include "ddsc/dds.h"
|
||||
#include "ddsi/q_rtps.h"
|
||||
#include "util/ut_avl.h"
|
||||
#include "util/ut_handleserver.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef _Return_type_success_(return == DDS_RETCODE_OK) int32_t dds__retcode_t;
|
||||
|
||||
struct dds_domain;
|
||||
struct dds_entity;
|
||||
struct dds_participant;
|
||||
struct dds_reader;
|
||||
struct dds_writer;
|
||||
struct dds_publisher;
|
||||
struct dds_subscriber;
|
||||
struct dds_topic;
|
||||
struct dds_readcond;
|
||||
struct dds_guardcond;
|
||||
|
||||
struct sertopic;
|
||||
struct rhc;
|
||||
|
||||
/* Internal entity status flags */
|
||||
|
||||
#define DDS_INTERNAL_STATUS_MASK (0xFF000000)
|
||||
|
||||
#define DDS_WAITSET_TRIGGER_STATUS (0x01000000)
|
||||
#define DDS_DELETING_STATUS (0x02000000)
|
||||
|
||||
/* This can be used when polling for various states.
|
||||
* Obviously, it is encouraged to use condition variables and such. But
|
||||
* sometimes it wouldn't make that much of a difference and taking the
|
||||
* easy route is somewhat pragmatic. */
|
||||
#define DDS_HEADBANG_TIMEOUT_MS (10)
|
||||
|
||||
typedef bool (*dds_querycondition_filter_with_ctx_fn) (const void * sample, const void *ctx);
|
||||
|
||||
|
||||
/* The listener struct. */
|
||||
|
||||
typedef struct c_listener {
|
||||
dds_on_inconsistent_topic_fn on_inconsistent_topic;
|
||||
dds_on_liveliness_lost_fn on_liveliness_lost;
|
||||
dds_on_offered_deadline_missed_fn on_offered_deadline_missed;
|
||||
dds_on_offered_incompatible_qos_fn on_offered_incompatible_qos;
|
||||
dds_on_data_on_readers_fn on_data_on_readers;
|
||||
dds_on_sample_lost_fn on_sample_lost;
|
||||
dds_on_data_available_fn on_data_available;
|
||||
dds_on_sample_rejected_fn on_sample_rejected;
|
||||
dds_on_liveliness_changed_fn on_liveliness_changed;
|
||||
dds_on_requested_deadline_missed_fn on_requested_deadline_missed;
|
||||
dds_on_requested_incompatible_qos_fn on_requested_incompatible_qos;
|
||||
dds_on_publication_matched_fn on_publication_matched;
|
||||
dds_on_subscription_matched_fn on_subscription_matched;
|
||||
void *arg;
|
||||
} c_listener_t;
|
||||
|
||||
/* Entity flag values */
|
||||
|
||||
#define DDS_ENTITY_ENABLED 0x0001
|
||||
#define DDS_ENTITY_IMPLICIT 0x0002
|
||||
|
||||
typedef struct dds_domain
|
||||
{
|
||||
ut_avlNode_t m_node;
|
||||
dds_domainid_t m_id;
|
||||
ut_avlTree_t m_topics;
|
||||
uint32_t m_refc;
|
||||
}
|
||||
dds_domain;
|
||||
|
||||
struct dds_entity;
|
||||
typedef struct dds_entity_deriver {
|
||||
/* Close can be used to terminate (blocking) actions on a entity before actually deleting it. */
|
||||
dds_return_t (*close)(struct dds_entity *e);
|
||||
/* Delete is used to actually free the entity. */
|
||||
dds_return_t (*delete)(struct dds_entity *e);
|
||||
dds_return_t (*set_qos)(struct dds_entity *e, const dds_qos_t *qos, bool enabled);
|
||||
dds_return_t (*validate_status)(uint32_t mask);
|
||||
dds_return_t (*propagate_status)(struct dds_entity *e, uint32_t mask, bool set);
|
||||
dds_return_t (*get_instance_hdl)(struct dds_entity *e, dds_instance_handle_t *i);
|
||||
}
|
||||
dds_entity_deriver;
|
||||
|
||||
typedef void (*dds_entity_callback)(dds_entity_t observer, dds_entity_t observed, uint32_t status);
|
||||
|
||||
typedef struct dds_entity_observer
|
||||
{
|
||||
dds_entity_callback m_cb;
|
||||
dds_entity_t m_observer;
|
||||
struct dds_entity_observer *m_next;
|
||||
}
|
||||
dds_entity_observer;
|
||||
|
||||
typedef struct dds_entity
|
||||
{
|
||||
ut_handle_t m_hdl;
|
||||
dds_entity_deriver m_deriver;
|
||||
uint32_t m_refc;
|
||||
struct dds_entity * m_next;
|
||||
struct dds_entity * m_parent;
|
||||
struct dds_entity * m_children;
|
||||
struct dds_entity * m_participant;
|
||||
struct dds_domain * m_domain;
|
||||
dds_qos_t * m_qos;
|
||||
dds_domainid_t m_domainid;
|
||||
nn_guid_t m_guid;
|
||||
uint32_t m_status_enable;
|
||||
uint32_t m_flags;
|
||||
uint32_t m_cb_count;
|
||||
os_mutex m_mutex;
|
||||
os_cond m_cond;
|
||||
c_listener_t m_listener;
|
||||
uint32_t m_trigger;
|
||||
dds_entity_observer *m_observers;
|
||||
struct ut_handlelink *m_hdllink;
|
||||
}
|
||||
dds_entity;
|
||||
|
||||
extern const ut_avlTreedef_t dds_topictree_def;
|
||||
|
||||
typedef struct dds_subscriber
|
||||
{
|
||||
struct dds_entity m_entity;
|
||||
}
|
||||
dds_subscriber;
|
||||
|
||||
typedef struct dds_publisher
|
||||
{
|
||||
struct dds_entity m_entity;
|
||||
}
|
||||
dds_publisher;
|
||||
|
||||
typedef struct dds_participant
|
||||
{
|
||||
struct dds_entity m_entity;
|
||||
struct dds_entity * m_dur_reader;
|
||||
struct dds_entity * m_dur_writer;
|
||||
dds_entity_t m_builtin_subscriber;
|
||||
}
|
||||
dds_participant;
|
||||
|
||||
typedef struct dds_reader
|
||||
{
|
||||
struct dds_entity m_entity;
|
||||
const struct dds_topic * m_topic;
|
||||
struct reader * m_rd;
|
||||
bool m_data_on_readers;
|
||||
bool m_loan_out;
|
||||
char * m_loan;
|
||||
uint32_t m_loan_size;
|
||||
|
||||
/* Status metrics */
|
||||
|
||||
dds_sample_rejected_status_t m_sample_rejected_status;
|
||||
dds_liveliness_changed_status_t m_liveliness_changed_status;
|
||||
dds_requested_deadline_missed_status_t m_requested_deadline_missed_status;
|
||||
dds_requested_incompatible_qos_status_t m_requested_incompatible_qos_status;
|
||||
dds_sample_lost_status_t m_sample_lost_status;
|
||||
dds_subscription_matched_status_t m_subscription_matched_status;
|
||||
}
|
||||
dds_reader;
|
||||
|
||||
typedef struct dds_writer
|
||||
{
|
||||
struct dds_entity m_entity;
|
||||
const struct dds_topic * m_topic;
|
||||
struct nn_xpack * m_xp;
|
||||
struct writer * m_wr;
|
||||
os_mutex m_call_lock;
|
||||
|
||||
/* Status metrics */
|
||||
|
||||
dds_liveliness_lost_status_t m_liveliness_lost_status;
|
||||
dds_offered_deadline_missed_status_t m_offered_deadline_missed_status;
|
||||
dds_offered_incompatible_qos_status_t m_offered_incompatible_qos_status;
|
||||
dds_publication_matched_status_t m_publication_matched_status;
|
||||
}
|
||||
dds_writer;
|
||||
|
||||
typedef struct dds_topic
|
||||
{
|
||||
struct dds_entity m_entity;
|
||||
struct sertopic * m_stopic;
|
||||
const dds_topic_descriptor_t * m_descriptor;
|
||||
|
||||
/* Status metrics */
|
||||
|
||||
dds_inconsistent_topic_status_t m_inconsistent_topic_status;
|
||||
}
|
||||
dds_topic;
|
||||
|
||||
typedef struct dds_readcond
|
||||
{
|
||||
dds_entity m_entity;
|
||||
struct rhc * m_rhc;
|
||||
uint32_t m_qminv;
|
||||
uint32_t m_sample_states;
|
||||
uint32_t m_view_states;
|
||||
uint32_t m_instance_states;
|
||||
nn_guid_t m_rd_guid;
|
||||
struct dds_readcond * m_rhc_next;
|
||||
struct
|
||||
{
|
||||
dds_querycondition_filter_fn m_filter;
|
||||
} m_query;
|
||||
}
|
||||
dds_readcond;
|
||||
|
||||
typedef struct dds_attachment
|
||||
{
|
||||
dds_entity *entity;
|
||||
dds_attach_t arg;
|
||||
struct dds_attachment* next;
|
||||
}
|
||||
dds_attachment;
|
||||
|
||||
typedef struct dds_waitset
|
||||
{
|
||||
dds_entity m_entity;
|
||||
dds_attachment *observed;
|
||||
dds_attachment *triggered;
|
||||
}
|
||||
dds_waitset;
|
||||
|
||||
typedef struct dds_iid
|
||||
{
|
||||
uint64_t counter;
|
||||
uint32_t key[4];
|
||||
}
|
||||
dds_iid;
|
||||
|
||||
/* Globals */
|
||||
|
||||
typedef struct dds_globals
|
||||
{
|
||||
dds_domainid_t m_default_domain;
|
||||
int32_t m_init_count;
|
||||
void (*m_dur_reader) (struct dds_reader * reader, struct rhc * rhc);
|
||||
int (*m_dur_wait) (struct dds_reader * reader, dds_duration_t timeout);
|
||||
void (*m_dur_init) (void);
|
||||
void (*m_dur_fini) (void);
|
||||
ut_avlTree_t m_domains;
|
||||
os_mutex m_mutex;
|
||||
}
|
||||
dds_globals;
|
||||
|
||||
DDS_EXPORT extern dds_globals dds_global;
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
51
src/core/ddsc/src/dds__write.h
Normal file
51
src/core/ddsc/src/dds__write.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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 _DDS_WRITE_H_
|
||||
#define _DDS_WRITE_H_
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DDS_WR_KEY_BIT 0x01
|
||||
#define DDS_WR_DISPOSE_BIT 0x02
|
||||
#define DDS_WR_UNREGISTER_BIT 0x04
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DDS_WR_ACTION_WRITE = 0,
|
||||
DDS_WR_ACTION_WRITE_DISPOSE = DDS_WR_DISPOSE_BIT,
|
||||
DDS_WR_ACTION_DISPOSE = DDS_WR_KEY_BIT | DDS_WR_DISPOSE_BIT,
|
||||
DDS_WR_ACTION_UNREGISTER = DDS_WR_KEY_BIT | DDS_WR_UNREGISTER_BIT
|
||||
}
|
||||
dds_write_action;
|
||||
|
||||
int
|
||||
dds_write_impl(
|
||||
_In_ dds_writer *wr,
|
||||
_In_ const void *data,
|
||||
_In_ dds_time_t tstamp,
|
||||
_In_ dds_write_action action);
|
||||
|
||||
int
|
||||
dds_writecdr_impl(
|
||||
_In_ dds_writer *wr,
|
||||
_In_ const void *cdr,
|
||||
_In_ size_t sz,
|
||||
_In_ dds_time_t tstamp,
|
||||
_In_ dds_write_action action);
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
27
src/core/ddsc/src/dds__writer.h
Normal file
27
src/core/ddsc/src/dds__writer.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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 _DDS_WRITER_H_
|
||||
#define _DDS_WRITER_H_
|
||||
|
||||
#include "dds__entity.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define dds_writer_lock(hdl, obj) dds_entity_lock(hdl, DDS_KIND_WRITER, (dds_entity**)obj)
|
||||
#define dds_writer_unlock(obj) dds_entity_unlock((dds_entity*)obj);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
371
src/core/ddsc/src/dds_alloc.c
Normal file
371
src/core/ddsc/src/dds_alloc.c
Normal file
|
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
#include "dds__alloc.h"
|
||||
#include "dds__stream.h"
|
||||
#include "os/os_heap.h"
|
||||
#include "ddsi/q_config.h"
|
||||
|
||||
/*
|
||||
#define OP_DEBUG_FREE 1
|
||||
*/
|
||||
|
||||
#if defined OP_DEBUG_FREE
|
||||
static const char * stream_op_type[11] =
|
||||
{
|
||||
NULL, "1Byte", "2Byte", "4Byte", "8Byte", "String",
|
||||
"BString", "Sequence", "Array", "Union", "Struct"
|
||||
};
|
||||
#endif
|
||||
|
||||
static dds_allocator_t dds_allocator_fns = { os_malloc, os_realloc, os_free };
|
||||
|
||||
void * dds_alloc (size_t size)
|
||||
{
|
||||
void * ret = (dds_allocator_fns.malloc) (size);
|
||||
if (ret)
|
||||
{
|
||||
memset (ret, 0, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
DDS_FAIL ("dds_alloc");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void * dds_realloc (void * ptr, size_t size)
|
||||
{
|
||||
void * ret = (dds_allocator_fns.realloc) (ptr, size);
|
||||
if (ret == NULL) DDS_FAIL ("dds_realloc");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void * dds_realloc_zero (void * ptr, size_t size)
|
||||
{
|
||||
void * ret = dds_realloc (ptr, size);
|
||||
if (ret)
|
||||
{
|
||||
memset (ret, 0, size);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dds_free (void * ptr)
|
||||
{
|
||||
if (ptr) (dds_allocator_fns.free) (ptr);
|
||||
}
|
||||
|
||||
char * dds_string_alloc (size_t size)
|
||||
{
|
||||
return (char*) dds_alloc (size + 1);
|
||||
}
|
||||
|
||||
char * dds_string_dup (const char * str)
|
||||
{
|
||||
char * ret = NULL;
|
||||
if (str)
|
||||
{
|
||||
ret = dds_alloc (strlen (str) + 1);
|
||||
strcpy (ret, str);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dds_string_free (char * str)
|
||||
{
|
||||
dds_free (str);
|
||||
}
|
||||
|
||||
void dds_sample_free_contents (char * data, const uint32_t * ops)
|
||||
{
|
||||
uint32_t op;
|
||||
uint32_t type;
|
||||
uint32_t num;
|
||||
uint32_t subtype;
|
||||
char * addr;
|
||||
|
||||
while ((op = *ops) != DDS_OP_RTS)
|
||||
{
|
||||
switch (DDS_OP_MASK & op)
|
||||
{
|
||||
case DDS_OP_ADR:
|
||||
{
|
||||
type = DDS_OP_TYPE (op);
|
||||
#ifdef OP_DEBUG_FREE
|
||||
TRACE (("F-ADR: %s offset %d\n", stream_op_type[type], ops[1]));
|
||||
#endif
|
||||
addr = data + ops[1];
|
||||
ops += 2;
|
||||
switch (type)
|
||||
{
|
||||
case DDS_OP_VAL_1BY:
|
||||
case DDS_OP_VAL_2BY:
|
||||
case DDS_OP_VAL_4BY:
|
||||
case DDS_OP_VAL_8BY:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_STR:
|
||||
{
|
||||
#ifdef OP_DEBUG_FREE
|
||||
TRACE (("F-STR: @ %p %s\n", addr, *((char**) addr)));
|
||||
#endif
|
||||
dds_free (*((char**) addr));
|
||||
*((char**) addr) = NULL;
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_SEQ:
|
||||
{
|
||||
dds_sequence_t * seq = (dds_sequence_t*) addr;
|
||||
subtype = DDS_OP_SUBTYPE (op);
|
||||
num = (seq->_maximum > seq->_length) ? seq->_maximum : seq->_length;
|
||||
|
||||
#ifdef OP_DEBUG_FREE
|
||||
TRACE (("F-SEQ: of %s\n", stream_op_type[subtype]));
|
||||
#endif
|
||||
if ((seq->_release && num) || (subtype > DDS_OP_VAL_STR))
|
||||
{
|
||||
switch (subtype)
|
||||
{
|
||||
case DDS_OP_VAL_1BY:
|
||||
case DDS_OP_VAL_2BY:
|
||||
case DDS_OP_VAL_4BY:
|
||||
case DDS_OP_VAL_8BY:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_BST:
|
||||
{
|
||||
ops++;
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_STR:
|
||||
{
|
||||
char ** ptr = (char**) seq->_buffer;
|
||||
while (num--)
|
||||
{
|
||||
dds_free (*ptr++);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
const uint32_t elem_size = *ops++;
|
||||
const uint32_t * jsr_ops = ops + DDS_OP_ADR_JSR (*ops) - 3;
|
||||
const uint32_t jmp = DDS_OP_ADR_JMP (*ops);
|
||||
char * ptr = (char*) seq->_buffer;
|
||||
|
||||
while (num--)
|
||||
{
|
||||
dds_sample_free_contents (ptr, jsr_ops);
|
||||
ptr += elem_size;
|
||||
}
|
||||
ops += jmp ? (jmp - 3) : 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (seq->_release)
|
||||
{
|
||||
dds_free (seq->_buffer);
|
||||
seq->_buffer = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_ARR:
|
||||
{
|
||||
subtype = DDS_OP_SUBTYPE (op);
|
||||
num = *ops++;
|
||||
|
||||
#ifdef OP_DEBUG_FREE
|
||||
TRACE (("F-ARR: of %s size %d\n", stream_op_type[subtype], num));
|
||||
#endif
|
||||
switch (subtype)
|
||||
{
|
||||
case DDS_OP_VAL_1BY:
|
||||
case DDS_OP_VAL_2BY:
|
||||
case DDS_OP_VAL_4BY:
|
||||
case DDS_OP_VAL_8BY:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_STR:
|
||||
{
|
||||
char ** ptr = (char**) addr;
|
||||
while (num--)
|
||||
{
|
||||
dds_free (*ptr++);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_BST:
|
||||
{
|
||||
ops += 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
const uint32_t * jsr_ops = ops + DDS_OP_ADR_JSR (*ops) - 3;
|
||||
const uint32_t jmp = DDS_OP_ADR_JMP (*ops);
|
||||
const uint32_t elem_size = ops[1];
|
||||
|
||||
while (num--)
|
||||
{
|
||||
dds_sample_free_contents (addr, jsr_ops);
|
||||
addr += elem_size;
|
||||
}
|
||||
ops += jmp ? (jmp - 3) : 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_UNI:
|
||||
{
|
||||
const bool has_default = op & DDS_OP_FLAG_DEF;
|
||||
subtype = DDS_OP_SUBTYPE (op);
|
||||
num = ops[0];
|
||||
const uint32_t * jeq_op = ops + DDS_OP_ADR_JSR (ops[1]) - 2;
|
||||
uint32_t disc = 0;
|
||||
|
||||
assert (subtype <= DDS_OP_VAL_4BY);
|
||||
|
||||
#ifdef OP_DEBUG_FREE
|
||||
TRACE (("F-UNI: switch %s cases %d\n", stream_op_type[subtype], num));
|
||||
#endif
|
||||
/* Get discriminant */
|
||||
|
||||
switch (subtype)
|
||||
{
|
||||
case DDS_OP_VAL_1BY:
|
||||
{
|
||||
disc = *((uint8_t*) addr);
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_2BY:
|
||||
{
|
||||
disc = *((uint16_t*) addr);
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_4BY:
|
||||
{
|
||||
disc = *((uint32_t*) addr);
|
||||
break;
|
||||
}
|
||||
default: assert (0);
|
||||
}
|
||||
|
||||
/* Free case matching discriminant */
|
||||
|
||||
while (num--)
|
||||
{
|
||||
assert ((DDS_OP_MASK & jeq_op[0]) == DDS_OP_JEQ);
|
||||
if ((jeq_op[1] == disc) || (has_default && (num == 0)))
|
||||
{
|
||||
subtype = DDS_JEQ_TYPE (jeq_op[0]);
|
||||
addr = data + jeq_op[2];
|
||||
|
||||
switch (subtype)
|
||||
{
|
||||
case DDS_OP_VAL_1BY:
|
||||
case DDS_OP_VAL_2BY:
|
||||
case DDS_OP_VAL_4BY:
|
||||
case DDS_OP_VAL_8BY:
|
||||
case DDS_OP_VAL_BST:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_STR:
|
||||
{
|
||||
dds_free (*((char**) addr));
|
||||
*((char**) addr) = NULL;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
dds_sample_free_contents (addr, jeq_op + DDS_OP_ADR_JSR (jeq_op[0]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
jeq_op += 3;
|
||||
}
|
||||
|
||||
/* Jump to next instruction */
|
||||
|
||||
ops += DDS_OP_ADR_JMP (ops[1]) - 2;
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_BST:
|
||||
{
|
||||
ops++;
|
||||
break;
|
||||
}
|
||||
default: assert (0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DDS_OP_JSR: /* Implies nested type */
|
||||
{
|
||||
#ifdef OP_DEBUG_FREE
|
||||
TRACE (("F-JSR: %d\n", DDS_OP_JUMP (op)));
|
||||
#endif
|
||||
dds_sample_free_contents (data, ops + DDS_OP_JUMP (op));
|
||||
ops++;
|
||||
break;
|
||||
}
|
||||
default: assert (0);
|
||||
}
|
||||
}
|
||||
#ifdef OP_DEBUG_FREE
|
||||
TRACE (("F-RTS:\n"));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void dds_sample_free_key (char * sample, const struct dds_topic_descriptor * desc)
|
||||
{
|
||||
uint32_t i;
|
||||
const uint32_t * op;
|
||||
|
||||
for (i = 0; i < desc->m_nkeys; i++)
|
||||
{
|
||||
op = desc->m_ops + desc->m_keys[i].m_index;
|
||||
if (DDS_OP_TYPE (*op) == DDS_OP_VAL_STR)
|
||||
{
|
||||
dds_free (*(char**)(sample + op[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dds_sample_free (void * sample, const struct dds_topic_descriptor * desc, dds_free_op_t op)
|
||||
{
|
||||
assert (desc);
|
||||
|
||||
if (sample)
|
||||
{
|
||||
if (op & DDS_FREE_CONTENTS_BIT)
|
||||
{
|
||||
dds_sample_free_contents ((char*) sample, desc->m_ops);
|
||||
}
|
||||
else if (op & DDS_FREE_KEY_BIT)
|
||||
{
|
||||
dds_sample_free_key ((char*) sample, desc);
|
||||
}
|
||||
if (op & DDS_FREE_ALL_BIT)
|
||||
{
|
||||
dds_free (sample);
|
||||
}
|
||||
}
|
||||
}
|
||||
440
src/core/ddsc/src/dds_builtin.c
Normal file
440
src/core/ddsc/src/dds_builtin.c
Normal file
|
|
@ -0,0 +1,440 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
#include "ddsi/q_entity.h"
|
||||
#include "ddsi/q_thread.h"
|
||||
#include "ddsi/q_config.h"
|
||||
#include "ddsi/q_builtin_topic.h"
|
||||
#include "q__osplser.h"
|
||||
#include "dds__init.h"
|
||||
#include "dds__qos.h"
|
||||
#include "dds__domain.h"
|
||||
#include "dds__participant.h"
|
||||
#include "dds__err.h"
|
||||
#include "dds__types.h"
|
||||
#include "dds__report.h"
|
||||
#include "dds__builtin.h"
|
||||
#include "dds__subscriber.h"
|
||||
|
||||
|
||||
static dds_return_t
|
||||
dds__delete_builtin_participant(
|
||||
dds_entity *e);
|
||||
|
||||
static _Must_inspect_result_ dds_entity_t
|
||||
dds__create_builtin_participant(
|
||||
void);
|
||||
|
||||
static _Must_inspect_result_ dds_entity_t
|
||||
dds__create_builtin_publisher(
|
||||
_In_ dds_entity_t participant);
|
||||
|
||||
static _Must_inspect_result_ dds_entity_t
|
||||
dds__create_builtin_writer(
|
||||
_In_ dds_entity_t topic);
|
||||
|
||||
static _Must_inspect_result_ dds_entity_t
|
||||
dds__get_builtin_participant(
|
||||
void);
|
||||
|
||||
|
||||
|
||||
|
||||
static os_mutex g_builtin_mutex;
|
||||
static os_atomic_uint32_t m_call_count = OS_ATOMIC_UINT32_INIT(0);
|
||||
|
||||
/* Singletons are used to publish builtin data locally. */
|
||||
static dds_entity_t g_builtin_local_participant = 0;
|
||||
static dds_entity_t g_builtin_local_publisher = 0;
|
||||
static dds_entity_t g_builtin_local_writers[] = {
|
||||
0, /* index DDS_BUILTIN_TOPIC_DCPSPARTICIPANT - DDS_KIND_INTERNAL - 1 */
|
||||
0, /* index DDS_BUILTIN_TOPIC_CMPARTICIPANT - DDS_KIND_INTERNAL - 1 */
|
||||
0, /* index DDS_BUILTIN_TOPIC_DCPSTYPE - DDS_KIND_INTERNAL - 1 */
|
||||
0, /* index DDS_BUILTIN_TOPIC_DCPSTOPIC - DDS_KIND_INTERNAL - 1 */
|
||||
0, /* index DDS_BUILTIN_TOPIC_DCPSPUBLICATION - DDS_KIND_INTERNAL - 1 */
|
||||
0, /* index DDS_BUILTIN_TOPIC_CMPUBLISHER - DDS_KIND_INTERNAL - 1 */
|
||||
0, /* index DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION - DDS_KIND_INTERNAL - 1 */
|
||||
0, /* index DDS_BUILTIN_TOPIC_CMSUBSCRIBER - DDS_KIND_INTERNAL - 1 */
|
||||
0, /* index DDS_BUILTIN_TOPIC_CMDATAWRITER - DDS_KIND_INTERNAL - 1 */
|
||||
0, /* index DDS_BUILTIN_TOPIC_CMDATAREADER - DDS_KIND_INTERNAL - 1 */
|
||||
};
|
||||
|
||||
|
||||
static dds_return_t
|
||||
dds__delete_builtin_participant(
|
||||
dds_entity *e)
|
||||
{
|
||||
struct thread_state1 * const thr = lookup_thread_state ();
|
||||
const bool asleep = !vtime_awake_p (thr->vtime);
|
||||
|
||||
assert(e);
|
||||
assert(thr);
|
||||
assert(dds_entity_kind(e->m_hdl) == DDS_KIND_PARTICIPANT);
|
||||
|
||||
if (asleep) {
|
||||
thread_state_awake(thr);
|
||||
}
|
||||
dds_domain_free(e->m_domain);
|
||||
if (asleep) {
|
||||
thread_state_asleep(thr);
|
||||
}
|
||||
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't use the 'normal' create participant.
|
||||
*
|
||||
* This way, the application is not able to access the local builtin writers.
|
||||
* Also, we can indicate that it should be a 'local only' participant, which
|
||||
* means that none of the entities under the hierarchy of this participant will
|
||||
* be exposed to the outside world. This is what we want, because these builtin
|
||||
* writers are only applicable to local user readers.
|
||||
*/
|
||||
static _Must_inspect_result_ dds_entity_t
|
||||
dds__create_builtin_participant(
|
||||
void)
|
||||
{
|
||||
int q_rc;
|
||||
nn_plist_t plist;
|
||||
struct thread_state1 * thr;
|
||||
bool asleep;
|
||||
nn_guid_t guid;
|
||||
dds_entity_t participant;
|
||||
dds_participant *pp;
|
||||
|
||||
nn_plist_init_empty (&plist);
|
||||
|
||||
thr = lookup_thread_state ();
|
||||
asleep = !vtime_awake_p (thr->vtime);
|
||||
if (asleep) {
|
||||
thread_state_awake (thr);
|
||||
}
|
||||
q_rc = new_participant (&guid, RTPS_PF_NO_BUILTIN_WRITERS | RTPS_PF_NO_BUILTIN_READERS | RTPS_PF_ONLY_LOCAL, &plist);
|
||||
if (asleep) {
|
||||
thread_state_asleep (thr);
|
||||
}
|
||||
|
||||
if (q_rc != 0) {
|
||||
participant = DDS_ERRNO(DDS_RETCODE_ERROR, "Internal builtin error");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pp = dds_alloc (sizeof (*pp));
|
||||
participant = dds_entity_init (&pp->m_entity, NULL, DDS_KIND_PARTICIPANT, NULL, NULL, 0);
|
||||
if (participant < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pp->m_entity.m_guid = guid;
|
||||
pp->m_entity.m_domain = dds_domain_create (config.domainId);
|
||||
pp->m_entity.m_domainid = config.domainId;
|
||||
pp->m_entity.m_deriver.delete = dds__delete_builtin_participant;
|
||||
|
||||
fail:
|
||||
return participant;
|
||||
}
|
||||
|
||||
static _Must_inspect_result_ dds_entity_t
|
||||
dds__create_builtin_publisher(
|
||||
_In_ dds_entity_t participant)
|
||||
{
|
||||
dds_entity_t pub;
|
||||
dds_qos_t *qos;
|
||||
const char *partition = "__BUILT-IN PARTITION__";
|
||||
|
||||
qos = dds_qos_create();
|
||||
dds_qset_partition(qos, 1, &partition);
|
||||
|
||||
pub = dds_create_publisher(participant, qos, NULL);
|
||||
|
||||
dds_qos_delete(qos);
|
||||
|
||||
return pub;
|
||||
}
|
||||
|
||||
static _Must_inspect_result_ dds_entity_t
|
||||
dds__create_builtin_subscriber(
|
||||
_In_ dds_entity *participant)
|
||||
{
|
||||
dds_entity_t sub;
|
||||
dds_qos_t *qos;
|
||||
const char *partition = "__BUILT-IN PARTITION__";
|
||||
|
||||
qos = dds_qos_create();
|
||||
dds_qset_partition(qos, 1, &partition);
|
||||
|
||||
/* Create builtin-subscriber */
|
||||
sub = dds__create_subscriber_l(participant, qos, NULL);
|
||||
dds_qos_delete(qos);
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
||||
static _Must_inspect_result_ dds_entity_t
|
||||
dds__create_builtin_writer(
|
||||
_In_ dds_entity_t topic)
|
||||
{
|
||||
dds_entity_t wr;
|
||||
dds_entity_t pub = dds__get_builtin_publisher();
|
||||
if (pub > 0) {
|
||||
dds_entity_t top = dds__get_builtin_topic(pub, topic);
|
||||
if (top > 0) {
|
||||
dds_qos_t *qos;
|
||||
// TODO: set builtin qos
|
||||
qos = dds_qos_create();
|
||||
dds_qset_durability(qos, DDS_DURABILITY_TRANSIENT_LOCAL);
|
||||
dds_qset_reliability(qos, DDS_RELIABILITY_RELIABLE, DDS_MSECS(100));
|
||||
wr = dds_create_writer(pub, top, qos, NULL);
|
||||
dds_qos_delete(qos);
|
||||
(void)dds_delete(top);
|
||||
} else {
|
||||
wr = top;
|
||||
}
|
||||
} else {
|
||||
wr = pub;
|
||||
}
|
||||
return wr;
|
||||
}
|
||||
|
||||
|
||||
static _Must_inspect_result_ dds_entity_t
|
||||
dds__get_builtin_participant(
|
||||
void)
|
||||
{
|
||||
if (g_builtin_local_participant == 0) {
|
||||
g_builtin_local_participant = dds__create_builtin_participant();
|
||||
}
|
||||
return g_builtin_local_participant;
|
||||
}
|
||||
|
||||
|
||||
_Must_inspect_result_ dds_entity_t
|
||||
dds__get_builtin_publisher(
|
||||
void)
|
||||
{
|
||||
if (g_builtin_local_publisher == 0) {
|
||||
dds_entity_t par = dds__get_builtin_participant();
|
||||
if (par > 0) {
|
||||
g_builtin_local_publisher = dds__create_builtin_publisher(par);
|
||||
}
|
||||
}
|
||||
return g_builtin_local_publisher;
|
||||
}
|
||||
|
||||
_Must_inspect_result_ dds_entity_t
|
||||
dds__get_builtin_subscriber(
|
||||
_In_ dds_entity_t e)
|
||||
{
|
||||
dds_entity_t sub;
|
||||
dds_return_t ret;
|
||||
dds_entity_t participant;
|
||||
dds_participant *p;
|
||||
dds_entity *part_entity;
|
||||
|
||||
participant = dds_get_participant(e);
|
||||
if (participant <= 0) {
|
||||
/* error already in participant error; no need to repeat error */
|
||||
ret = participant;
|
||||
goto error;
|
||||
}
|
||||
ret = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, (dds_entity **)&part_entity);
|
||||
if (ret != DDS_RETCODE_OK) {
|
||||
goto error;
|
||||
}
|
||||
p = (dds_participant *)part_entity;
|
||||
if(p->m_builtin_subscriber <= 0) {
|
||||
p->m_builtin_subscriber = dds__create_builtin_subscriber(part_entity);
|
||||
}
|
||||
sub = p->m_builtin_subscriber;
|
||||
dds_entity_unlock(part_entity);
|
||||
|
||||
return sub;
|
||||
|
||||
/* Error handling */
|
||||
error:
|
||||
assert(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
_Must_inspect_result_ dds_entity_t
|
||||
dds__get_builtin_topic(
|
||||
_In_ dds_entity_t e,
|
||||
_In_ dds_entity_t topic)
|
||||
{
|
||||
dds_entity_t participant;
|
||||
dds_entity_t ret;
|
||||
|
||||
participant = dds_get_participant(e);
|
||||
if (participant > 0) {
|
||||
const dds_topic_descriptor_t *desc;
|
||||
const char *name;
|
||||
|
||||
if (topic == DDS_BUILTIN_TOPIC_DCPSPARTICIPANT) {
|
||||
desc = &DDS_ParticipantBuiltinTopicData_desc;
|
||||
name = "DCPSParticipant";
|
||||
} else if (topic == DDS_BUILTIN_TOPIC_CMPARTICIPANT) {
|
||||
desc = &DDS_CMParticipantBuiltinTopicData_desc;
|
||||
name = "CMParticipant";
|
||||
} else if (topic == DDS_BUILTIN_TOPIC_DCPSTYPE) {
|
||||
desc = &DDS_TypeBuiltinTopicData_desc;
|
||||
name = "DCPSType";
|
||||
} else if (topic == DDS_BUILTIN_TOPIC_DCPSTOPIC) {
|
||||
desc = &DDS_TopicBuiltinTopicData_desc;
|
||||
name = "DCPSTopic";
|
||||
} else if (topic == DDS_BUILTIN_TOPIC_DCPSPUBLICATION) {
|
||||
desc = &DDS_PublicationBuiltinTopicData_desc;
|
||||
name = "DCPSPublication";
|
||||
} else if (topic == DDS_BUILTIN_TOPIC_CMPUBLISHER) {
|
||||
desc = &DDS_CMPublisherBuiltinTopicData_desc;
|
||||
name = "CMPublisher";
|
||||
} else if (topic == DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION) {
|
||||
desc = &DDS_SubscriptionBuiltinTopicData_desc;
|
||||
name = "DCPSSubscription";
|
||||
} else if (topic == DDS_BUILTIN_TOPIC_CMSUBSCRIBER) {
|
||||
desc = &DDS_CMSubscriberBuiltinTopicData_desc;
|
||||
name = "CMSubscriber";
|
||||
} else if (topic == DDS_BUILTIN_TOPIC_CMDATAWRITER) {
|
||||
desc = &DDS_CMDataWriterBuiltinTopicData_desc;
|
||||
name = "CMDataWriter";
|
||||
} else if (topic == DDS_BUILTIN_TOPIC_CMDATAREADER) {
|
||||
desc = &DDS_CMDataReaderBuiltinTopicData_desc;
|
||||
name = "CMDataReader";
|
||||
} else {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Invalid builtin-topic handle(%d)", topic);
|
||||
goto err_invalid_topic;
|
||||
}
|
||||
|
||||
ret = dds_find_topic(participant, name);
|
||||
if (ret < 0 && dds_err_nr(ret) == DDS_RETCODE_PRECONDITION_NOT_MET) {
|
||||
dds_qos_t *tqos;
|
||||
|
||||
/* drop the precondition-no-met error */
|
||||
DDS_REPORT_FLUSH(0);
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
tqos = dds_qos_create();
|
||||
dds_qset_durability(tqos, DDS_DURABILITY_TRANSIENT_LOCAL);
|
||||
dds_qset_presentation(tqos, DDS_PRESENTATION_TOPIC, false, false);
|
||||
dds_qset_reliability(tqos, DDS_RELIABILITY_RELIABLE, DDS_MSECS(100));
|
||||
ret = dds_create_topic(participant, desc, name, tqos, NULL);
|
||||
dds_qos_delete(tqos);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Failed to get participant of provided entity */
|
||||
ret = participant;
|
||||
}
|
||||
|
||||
err_invalid_topic:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static _Must_inspect_result_ dds_entity_t
|
||||
dds__get_builtin_writer(
|
||||
_In_ dds_entity_t topic)
|
||||
{
|
||||
dds_entity_t wr;
|
||||
if ((topic >= DDS_BUILTIN_TOPIC_DCPSPARTICIPANT) && (topic <= DDS_BUILTIN_TOPIC_CMDATAREADER)) {
|
||||
int index = (int)(topic - DDS_KIND_INTERNAL - 1);
|
||||
os_mutexLock(&g_builtin_mutex);
|
||||
wr = g_builtin_local_writers[index];
|
||||
if (wr == 0) {
|
||||
wr = dds__create_builtin_writer(topic);
|
||||
if (wr > 0) {
|
||||
g_builtin_local_writers[index] = wr;
|
||||
}
|
||||
}
|
||||
os_mutexUnlock(&g_builtin_mutex);
|
||||
} else {
|
||||
wr = DDS_ERRNO(DDS_RETCODE_ERROR, "Given topic is not a builtin topic.");
|
||||
}
|
||||
return wr;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds__builtin_write(
|
||||
_In_ dds_entity_t topic,
|
||||
_In_ const void *data,
|
||||
_In_ dds_time_t timestamp,
|
||||
_In_ int alive)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
if (os_atomic_inc32_nv(&m_call_count) > 1) {
|
||||
dds_entity_t wr;
|
||||
wr = dds__get_builtin_writer(topic);
|
||||
if (wr > 0) {
|
||||
if (alive) {
|
||||
ret = dds_write_ts(wr, data, timestamp);
|
||||
} else {
|
||||
ret = dds_dispose_ts(wr, data, timestamp);
|
||||
}
|
||||
} else {
|
||||
ret = wr;
|
||||
}
|
||||
}
|
||||
os_atomic_dec32(&m_call_count);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
dds__builtin_init(
|
||||
void)
|
||||
{
|
||||
assert(os_atomic_ld32(&m_call_count) == 0);
|
||||
os_mutexInit(&g_builtin_mutex);
|
||||
os_atomic_inc32(&m_call_count);
|
||||
}
|
||||
|
||||
void
|
||||
dds__builtin_fini(
|
||||
void)
|
||||
{
|
||||
assert(os_atomic_ld32(&m_call_count) > 0);
|
||||
while (os_atomic_dec32_nv(&m_call_count) > 0) {
|
||||
os_atomic_inc32_nv(&m_call_count);
|
||||
dds_sleepfor(DDS_MSECS(10));
|
||||
}
|
||||
(void)dds_delete(g_builtin_local_participant);
|
||||
g_builtin_local_participant = 0;
|
||||
g_builtin_local_publisher = 0;
|
||||
memset(g_builtin_local_writers, 0, sizeof(g_builtin_local_writers));
|
||||
os_mutexDestroy(&g_builtin_mutex);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
forward_builtin_participant(
|
||||
_In_ DDS_ParticipantBuiltinTopicData *data,
|
||||
_In_ nn_wctime_t timestamp,
|
||||
_In_ int alive)
|
||||
{
|
||||
dds_return_t ret;
|
||||
DDS_REPORT_STACK();
|
||||
ret = dds__builtin_write(DDS_BUILTIN_TOPIC_DCPSPARTICIPANT, data, timestamp.v, alive);
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
}
|
||||
|
||||
void
|
||||
forward_builtin_cmparticipant(
|
||||
_In_ DDS_CMParticipantBuiltinTopicData *data,
|
||||
_In_ nn_wctime_t timestamp,
|
||||
_In_ int alive)
|
||||
{
|
||||
dds_return_t ret;
|
||||
DDS_REPORT_STACK();
|
||||
ret = dds__builtin_write(DDS_BUILTIN_TOPIC_CMPARTICIPANT, data, timestamp.v, alive);
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
}
|
||||
371
src/core/ddsc/src/dds_builtinTopics.idl
Normal file
371
src/core/ddsc/src/dds_builtinTopics.idl
Normal file
|
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
* 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 OSPL_DDS_BUILTINTOPICS_IDL
|
||||
#define OSPL_DDS_BUILTINTOPICS_IDL
|
||||
|
||||
/*
|
||||
This file was the one orginally in ./src/api/dcps/saj/code/.
|
||||
(and therefore by implication ./src/api/dcps/cj/java/code).
|
||||
*/
|
||||
|
||||
#define BUILTIN_TOPIC_KEY_TYPE_NATIVE long
|
||||
|
||||
module DDS {
|
||||
|
||||
|
||||
// Added octet sequence definition.
|
||||
// Prevents IDL compiler warnings from deprecated anonymous types
|
||||
// on composite type members.
|
||||
typedef sequence<octet> octSeq;
|
||||
|
||||
typedef BUILTIN_TOPIC_KEY_TYPE_NATIVE BuiltinTopicKey_t[3];
|
||||
typedef sequence<string> StringSeq;
|
||||
typedef short DataRepresentationId_t;
|
||||
|
||||
const DataRepresentationId_t XCDR_REPRESENTATION = 0;
|
||||
const DataRepresentationId_t XML_REPRESENTATION = 0x001;
|
||||
const DataRepresentationId_t OSPL_REPRESENTATION = 0x400;
|
||||
const DataRepresentationId_t GPB_REPRESENTATION = 0x401;
|
||||
const DataRepresentationId_t INVALID_REPRESENTATION = 0x7FFF;
|
||||
|
||||
struct Duration_t {
|
||||
long sec;
|
||||
unsigned long nanosec;
|
||||
};
|
||||
|
||||
struct UserDataQosPolicy {
|
||||
octSeq value;
|
||||
// replaced deprecated anonymous sequence<octet> value;
|
||||
};
|
||||
|
||||
struct TopicDataQosPolicy {
|
||||
octSeq value;
|
||||
// replaced deprecated anonymous sequence<octet> value;
|
||||
};
|
||||
|
||||
struct GroupDataQosPolicy {
|
||||
octSeq value;
|
||||
// replaced deprected anonymous sequence<octet> value;
|
||||
};
|
||||
|
||||
struct TransportPriorityQosPolicy {
|
||||
long value;
|
||||
};
|
||||
|
||||
struct LifespanQosPolicy {
|
||||
Duration_t duration;
|
||||
};
|
||||
|
||||
enum DurabilityQosPolicyKind {
|
||||
VOLATILE_DURABILITY_QOS,
|
||||
TRANSIENT_LOCAL_DURABILITY_QOS,
|
||||
TRANSIENT_DURABILITY_QOS,
|
||||
PERSISTENT_DURABILITY_QOS
|
||||
};
|
||||
|
||||
struct DurabilityQosPolicy {
|
||||
DurabilityQosPolicyKind kind;
|
||||
};
|
||||
|
||||
enum PresentationQosPolicyAccessScopeKind {
|
||||
INSTANCE_PRESENTATION_QOS,
|
||||
TOPIC_PRESENTATION_QOS,
|
||||
GROUP_PRESENTATION_QOS
|
||||
};
|
||||
|
||||
struct PresentationQosPolicy {
|
||||
PresentationQosPolicyAccessScopeKind access_scope;
|
||||
boolean coherent_access;
|
||||
boolean ordered_access;
|
||||
};
|
||||
|
||||
struct DeadlineQosPolicy {
|
||||
Duration_t period;
|
||||
};
|
||||
|
||||
struct LatencyBudgetQosPolicy {
|
||||
Duration_t duration;
|
||||
};
|
||||
|
||||
enum OwnershipQosPolicyKind {
|
||||
SHARED_OWNERSHIP_QOS,
|
||||
EXCLUSIVE_OWNERSHIP_QOS
|
||||
};
|
||||
|
||||
struct OwnershipQosPolicy {
|
||||
OwnershipQosPolicyKind kind;
|
||||
};
|
||||
|
||||
struct OwnershipStrengthQosPolicy {
|
||||
long value;
|
||||
};
|
||||
|
||||
enum LivelinessQosPolicyKind {
|
||||
AUTOMATIC_LIVELINESS_QOS,
|
||||
MANUAL_BY_PARTICIPANT_LIVELINESS_QOS,
|
||||
MANUAL_BY_TOPIC_LIVELINESS_QOS
|
||||
};
|
||||
|
||||
struct LivelinessQosPolicy {
|
||||
LivelinessQosPolicyKind kind;
|
||||
Duration_t lease_duration;
|
||||
};
|
||||
|
||||
struct TimeBasedFilterQosPolicy {
|
||||
Duration_t minimum_separation;
|
||||
};
|
||||
|
||||
struct PartitionQosPolicy {
|
||||
StringSeq name;
|
||||
};
|
||||
|
||||
enum ReliabilityQosPolicyKind {
|
||||
BEST_EFFORT_RELIABILITY_QOS,
|
||||
RELIABLE_RELIABILITY_QOS
|
||||
};
|
||||
|
||||
struct ReliabilityQosPolicy {
|
||||
ReliabilityQosPolicyKind kind;
|
||||
Duration_t max_blocking_time;
|
||||
boolean synchronous;
|
||||
};
|
||||
|
||||
enum DestinationOrderQosPolicyKind {
|
||||
BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS,
|
||||
BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS
|
||||
};
|
||||
|
||||
struct DestinationOrderQosPolicy {
|
||||
DestinationOrderQosPolicyKind kind;
|
||||
};
|
||||
|
||||
enum HistoryQosPolicyKind {
|
||||
KEEP_LAST_HISTORY_QOS,
|
||||
KEEP_ALL_HISTORY_QOS
|
||||
};
|
||||
|
||||
struct HistoryQosPolicy {
|
||||
HistoryQosPolicyKind kind;
|
||||
long depth;
|
||||
};
|
||||
|
||||
struct ResourceLimitsQosPolicy {
|
||||
long max_samples;
|
||||
long max_instances;
|
||||
long max_samples_per_instance;
|
||||
};
|
||||
|
||||
struct DurabilityServiceQosPolicy {
|
||||
Duration_t service_cleanup_delay;
|
||||
HistoryQosPolicyKind history_kind;
|
||||
long history_depth;
|
||||
long max_samples;
|
||||
long max_instances;
|
||||
long max_samples_per_instance;
|
||||
};
|
||||
|
||||
struct ProductDataQosPolicy {
|
||||
string value;
|
||||
};
|
||||
|
||||
struct EntityFactoryQosPolicy {
|
||||
boolean autoenable_created_entities;
|
||||
};
|
||||
|
||||
struct ShareQosPolicy {
|
||||
string name;
|
||||
boolean enable;
|
||||
};
|
||||
|
||||
struct WriterDataLifecycleQosPolicy {
|
||||
boolean autodispose_unregistered_instances;
|
||||
Duration_t autopurge_suspended_samples_delay;
|
||||
Duration_t autounregister_instance_delay;
|
||||
};
|
||||
|
||||
enum InvalidSampleVisibilityQosPolicyKind {
|
||||
NO_INVALID_SAMPLES,
|
||||
MINIMUM_INVALID_SAMPLES,
|
||||
ALL_INVALID_SAMPLES
|
||||
};
|
||||
|
||||
struct InvalidSampleVisibilityQosPolicy {
|
||||
InvalidSampleVisibilityQosPolicyKind kind;
|
||||
};
|
||||
|
||||
// @discrepancy The below QoS did not exist in ./etc/idlpp/dds_dcps.idl Retain ?
|
||||
|
||||
struct SubscriptionKeyQosPolicy {
|
||||
boolean use_key_list;
|
||||
StringSeq key_list;
|
||||
};
|
||||
|
||||
// @discrepancy End of above discrepancy
|
||||
|
||||
struct ReaderDataLifecycleQosPolicy {
|
||||
Duration_t autopurge_nowriter_samples_delay;
|
||||
Duration_t autopurge_disposed_samples_delay;
|
||||
boolean autopurge_dispose_all;
|
||||
// @discrepancy The below member existed in this file but did not
|
||||
// in ./etc/idlpp/dds_dcps.idl. Retain ?
|
||||
boolean enable_invalid_samples; // @deprecated Will be replaced by invalid_sample_visibility in due time
|
||||
InvalidSampleVisibilityQosPolicy invalid_sample_visibility;
|
||||
};
|
||||
|
||||
struct UserKeyQosPolicy {
|
||||
boolean enable;
|
||||
string expression;
|
||||
};
|
||||
|
||||
struct ReaderLifespanQosPolicy {
|
||||
boolean use_lifespan;
|
||||
Duration_t duration;
|
||||
};
|
||||
|
||||
struct TypeHash {
|
||||
unsigned long long msb;
|
||||
unsigned long long lsb;
|
||||
};
|
||||
|
||||
struct ParticipantBuiltinTopicData {
|
||||
BuiltinTopicKey_t key;
|
||||
UserDataQosPolicy user_data;
|
||||
};
|
||||
#pragma keylist ParticipantBuiltinTopicData key
|
||||
|
||||
struct TopicBuiltinTopicData {
|
||||
BuiltinTopicKey_t key;
|
||||
string name;
|
||||
string type_name;
|
||||
DurabilityQosPolicy durability;
|
||||
DurabilityServiceQosPolicy durability_service;
|
||||
DeadlineQosPolicy deadline;
|
||||
LatencyBudgetQosPolicy latency_budget;
|
||||
LivelinessQosPolicy liveliness;
|
||||
ReliabilityQosPolicy reliability;
|
||||
TransportPriorityQosPolicy transport_priority;
|
||||
LifespanQosPolicy lifespan;
|
||||
DestinationOrderQosPolicy destination_order;
|
||||
HistoryQosPolicy history;
|
||||
ResourceLimitsQosPolicy resource_limits;
|
||||
OwnershipQosPolicy ownership;
|
||||
TopicDataQosPolicy topic_data;
|
||||
};
|
||||
#pragma keylist TopicBuiltinTopicData key
|
||||
|
||||
struct TypeBuiltinTopicData {
|
||||
string name;
|
||||
DataRepresentationId_t data_representation_id;
|
||||
TypeHash type_hash;
|
||||
octSeq meta_data;
|
||||
octSeq extentions;
|
||||
};
|
||||
#pragma keylist TypeBuiltinTopicData name data_representation_id type_hash.msb type_hash.lsb
|
||||
|
||||
struct PublicationBuiltinTopicData {
|
||||
BuiltinTopicKey_t key;
|
||||
BuiltinTopicKey_t participant_key;
|
||||
string topic_name;
|
||||
string type_name;
|
||||
DurabilityQosPolicy durability;
|
||||
DeadlineQosPolicy deadline;
|
||||
LatencyBudgetQosPolicy latency_budget;
|
||||
LivelinessQosPolicy liveliness;
|
||||
ReliabilityQosPolicy reliability;
|
||||
LifespanQosPolicy lifespan;
|
||||
DestinationOrderQosPolicy destination_order;
|
||||
UserDataQosPolicy user_data;
|
||||
OwnershipQosPolicy ownership;
|
||||
OwnershipStrengthQosPolicy ownership_strength;
|
||||
PresentationQosPolicy presentation;
|
||||
PartitionQosPolicy partition;
|
||||
TopicDataQosPolicy topic_data;
|
||||
GroupDataQosPolicy group_data;
|
||||
};
|
||||
#pragma keylist PublicationBuiltinTopicData key
|
||||
|
||||
struct SubscriptionBuiltinTopicData {
|
||||
BuiltinTopicKey_t key;
|
||||
BuiltinTopicKey_t participant_key;
|
||||
string topic_name;
|
||||
string type_name;
|
||||
DurabilityQosPolicy durability;
|
||||
DeadlineQosPolicy deadline;
|
||||
LatencyBudgetQosPolicy latency_budget;
|
||||
LivelinessQosPolicy liveliness;
|
||||
ReliabilityQosPolicy reliability;
|
||||
OwnershipQosPolicy ownership;
|
||||
DestinationOrderQosPolicy destination_order;
|
||||
UserDataQosPolicy user_data;
|
||||
TimeBasedFilterQosPolicy time_based_filter;
|
||||
PresentationQosPolicy presentation;
|
||||
PartitionQosPolicy partition;
|
||||
TopicDataQosPolicy topic_data;
|
||||
GroupDataQosPolicy group_data;
|
||||
};
|
||||
#pragma keylist SubscriptionBuiltinTopicData key
|
||||
|
||||
struct CMParticipantBuiltinTopicData {
|
||||
BuiltinTopicKey_t key;
|
||||
ProductDataQosPolicy product;
|
||||
};
|
||||
#pragma keylist CMParticipantBuiltinTopicData key
|
||||
|
||||
struct CMPublisherBuiltinTopicData {
|
||||
BuiltinTopicKey_t key;
|
||||
ProductDataQosPolicy product;
|
||||
BuiltinTopicKey_t participant_key;
|
||||
string name;
|
||||
EntityFactoryQosPolicy entity_factory;
|
||||
PartitionQosPolicy partition;
|
||||
};
|
||||
#pragma keylist CMPublisherBuiltinTopicData key
|
||||
|
||||
struct CMSubscriberBuiltinTopicData {
|
||||
BuiltinTopicKey_t key;
|
||||
ProductDataQosPolicy product;
|
||||
BuiltinTopicKey_t participant_key;
|
||||
string name;
|
||||
EntityFactoryQosPolicy entity_factory;
|
||||
ShareQosPolicy share;
|
||||
PartitionQosPolicy partition;
|
||||
};
|
||||
#pragma keylist CMSubscriberBuiltinTopicData key
|
||||
|
||||
struct CMDataWriterBuiltinTopicData {
|
||||
BuiltinTopicKey_t key;
|
||||
ProductDataQosPolicy product;
|
||||
BuiltinTopicKey_t publisher_key;
|
||||
string name;
|
||||
HistoryQosPolicy history;
|
||||
ResourceLimitsQosPolicy resource_limits;
|
||||
WriterDataLifecycleQosPolicy writer_data_lifecycle;
|
||||
};
|
||||
#pragma keylist CMDataWriterBuiltinTopicData key
|
||||
|
||||
struct CMDataReaderBuiltinTopicData {
|
||||
BuiltinTopicKey_t key;
|
||||
ProductDataQosPolicy product;
|
||||
BuiltinTopicKey_t subscriber_key;
|
||||
string name;
|
||||
HistoryQosPolicy history;
|
||||
ResourceLimitsQosPolicy resource_limits;
|
||||
ReaderDataLifecycleQosPolicy reader_data_lifecycle;
|
||||
UserKeyQosPolicy subscription_keys;
|
||||
ReaderLifespanQosPolicy reader_lifespan;
|
||||
ShareQosPolicy share;
|
||||
};
|
||||
#pragma keylist CMDataReaderBuiltinTopicData key
|
||||
|
||||
};
|
||||
|
||||
#endif /* OSPL_DDS_BUILTINTOPICS_IDL */
|
||||
79
src/core/ddsc/src/dds_coherent.c
Normal file
79
src/core/ddsc/src/dds_coherent.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
|
||||
#include "ddsc/dds.h"
|
||||
#include "dds__entity.h"
|
||||
#include "dds__subscriber.h"
|
||||
#include "dds__publisher.h"
|
||||
#include "dds__err.h"
|
||||
#include "dds__report.h"
|
||||
|
||||
_Pre_satisfies_(((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) || \
|
||||
((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_SUBSCRIBER) || \
|
||||
((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER ) || \
|
||||
((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_SUBSCRIBER) )
|
||||
dds_return_t
|
||||
dds_begin_coherent(
|
||||
_In_ dds_entity_t entity)
|
||||
{
|
||||
dds_return_t ret;
|
||||
|
||||
switch(dds_entity_kind(entity)) {
|
||||
case DDS_KIND_READER:
|
||||
case DDS_KIND_WRITER:
|
||||
/* Invoking on a writer/reader behaves as if invoked on
|
||||
* its parent publisher/subscriber. */
|
||||
ret = dds_begin_coherent(dds_get_parent(entity));
|
||||
break;
|
||||
case DDS_KIND_PUBLISHER:
|
||||
ret = dds_publisher_begin_coherent(entity);
|
||||
break;
|
||||
case DDS_KIND_SUBSCRIBER:
|
||||
ret = dds_subscriber_begin_coherent(entity);
|
||||
break;
|
||||
default:
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Given entity can not control coherency");
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) || \
|
||||
((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_SUBSCRIBER) || \
|
||||
((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER ) || \
|
||||
((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_SUBSCRIBER) )
|
||||
dds_return_t
|
||||
dds_end_coherent(
|
||||
_In_ dds_entity_t entity)
|
||||
{
|
||||
dds_return_t ret;
|
||||
|
||||
switch(dds_entity_kind(entity)) {
|
||||
case DDS_KIND_READER:
|
||||
case DDS_KIND_WRITER:
|
||||
/* Invoking on a writer/reader behaves as if invoked on
|
||||
* its parent publisher/subscriber. */
|
||||
ret = dds_end_coherent(dds_get_parent(entity));
|
||||
break;
|
||||
case DDS_KIND_PUBLISHER:
|
||||
ret = dds_publisher_end_coherent(entity);
|
||||
break;
|
||||
case DDS_KIND_SUBSCRIBER:
|
||||
ret = dds_subscriber_end_coherent(entity);
|
||||
break;
|
||||
default:
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Given entity can not control coherency");
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
130
src/core/ddsc/src/dds_dcps_builtintopics.idl
Normal file
130
src/core/ddsc/src/dds_dcps_builtintopics.idl
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* 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 OSPL_DDS_DCPS_BUILTINTOPICS_IDL
|
||||
#define OSPL_DDS_DCPS_BUILTINTOPICS_IDL
|
||||
|
||||
/**
|
||||
*This file (name) was orginally in ./src/api/dcps/ccpp/idl/.
|
||||
*It's been modified to include from another file the base definitions
|
||||
*required for this 'built in topics' superset... :
|
||||
*/
|
||||
|
||||
#include "dds_builtinTopics.idl"
|
||||
|
||||
module DDS {
|
||||
|
||||
struct Time_t {
|
||||
long sec;
|
||||
unsigned long nanosec;
|
||||
};
|
||||
|
||||
enum SchedulingClassQosPolicyKind {
|
||||
SCHEDULE_DEFAULT,
|
||||
SCHEDULE_TIMESHARING,
|
||||
SCHEDULE_REALTIME
|
||||
};
|
||||
|
||||
struct SchedulingClassQosPolicy {
|
||||
SchedulingClassQosPolicyKind kind;
|
||||
};
|
||||
|
||||
enum SchedulingPriorityQosPolicyKind {
|
||||
PRIORITY_RELATIVE,
|
||||
PRIORITY_ABSOLUTE
|
||||
};
|
||||
|
||||
struct SchedulingPriorityQosPolicy {
|
||||
SchedulingPriorityQosPolicyKind kind;
|
||||
};
|
||||
|
||||
struct SchedulingQosPolicy {
|
||||
SchedulingClassQosPolicy scheduling_class;
|
||||
SchedulingPriorityQosPolicy scheduling_priority_kind;
|
||||
long scheduling_priority;
|
||||
};
|
||||
|
||||
struct DomainParticipantQos {
|
||||
UserDataQosPolicy user_data;
|
||||
EntityFactoryQosPolicy entity_factory;
|
||||
SchedulingQosPolicy watchdog_scheduling;
|
||||
SchedulingQosPolicy listener_scheduling;
|
||||
};
|
||||
|
||||
struct TopicQos {
|
||||
TopicDataQosPolicy topic_data;
|
||||
DurabilityQosPolicy durability;
|
||||
DurabilityServiceQosPolicy durability_service;
|
||||
DeadlineQosPolicy deadline;
|
||||
LatencyBudgetQosPolicy latency_budget;
|
||||
LivelinessQosPolicy liveliness;
|
||||
ReliabilityQosPolicy reliability;
|
||||
DestinationOrderQosPolicy destination_order;
|
||||
HistoryQosPolicy history;
|
||||
ResourceLimitsQosPolicy resource_limits;
|
||||
TransportPriorityQosPolicy transport_priority;
|
||||
LifespanQosPolicy lifespan;
|
||||
OwnershipQosPolicy ownership;
|
||||
};
|
||||
|
||||
struct DataWriterQos {
|
||||
DurabilityQosPolicy durability;
|
||||
DeadlineQosPolicy deadline;
|
||||
LatencyBudgetQosPolicy latency_budget;
|
||||
LivelinessQosPolicy liveliness;
|
||||
ReliabilityQosPolicy reliability;
|
||||
DestinationOrderQosPolicy destination_order;
|
||||
HistoryQosPolicy history;
|
||||
ResourceLimitsQosPolicy resource_limits;
|
||||
TransportPriorityQosPolicy transport_priority;
|
||||
LifespanQosPolicy lifespan;
|
||||
UserDataQosPolicy user_data;
|
||||
OwnershipQosPolicy ownership;
|
||||
OwnershipStrengthQosPolicy ownership_strength;
|
||||
WriterDataLifecycleQosPolicy writer_data_lifecycle;
|
||||
};
|
||||
|
||||
struct PublisherQos {
|
||||
PresentationQosPolicy presentation;
|
||||
PartitionQosPolicy partition;
|
||||
GroupDataQosPolicy group_data;
|
||||
EntityFactoryQosPolicy entity_factory;
|
||||
};
|
||||
|
||||
struct DataReaderQos {
|
||||
DurabilityQosPolicy durability;
|
||||
DeadlineQosPolicy deadline;
|
||||
LatencyBudgetQosPolicy latency_budget;
|
||||
LivelinessQosPolicy liveliness;
|
||||
ReliabilityQosPolicy reliability;
|
||||
DestinationOrderQosPolicy destination_order;
|
||||
HistoryQosPolicy history;
|
||||
ResourceLimitsQosPolicy resource_limits;
|
||||
UserDataQosPolicy user_data;
|
||||
OwnershipQosPolicy ownership;
|
||||
TimeBasedFilterQosPolicy time_based_filter;
|
||||
ReaderDataLifecycleQosPolicy reader_data_lifecycle;
|
||||
SubscriptionKeyQosPolicy subscription_keys;
|
||||
ReaderLifespanQosPolicy reader_lifespan;
|
||||
ShareQosPolicy share;
|
||||
};
|
||||
|
||||
struct SubscriberQos {
|
||||
PresentationQosPolicy presentation;
|
||||
PartitionQosPolicy partition;
|
||||
GroupDataQosPolicy group_data;
|
||||
EntityFactoryQosPolicy entity_factory;
|
||||
ShareQosPolicy share;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif /* DDS_DCPS_BUILTINTOPICS_IDL */
|
||||
59
src/core/ddsc/src/dds_domain.c
Normal file
59
src/core/ddsc/src/dds_domain.c
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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 "dds__domain.h"
|
||||
#include "dds__tkmap.h"
|
||||
|
||||
static int dds_domain_compare (const int32_t * a, const int32_t * b)
|
||||
{
|
||||
return (*a == *b) ? 0 : (*a < *b) ? -1 : 1;
|
||||
}
|
||||
|
||||
const ut_avlTreedef_t dds_domaintree_def = UT_AVL_TREEDEF_INITIALIZER
|
||||
(
|
||||
offsetof (dds_domain, m_node),
|
||||
offsetof (dds_domain, m_id),
|
||||
(int (*) (const void *, const void *)) dds_domain_compare,
|
||||
0
|
||||
);
|
||||
|
||||
dds_domain * dds_domain_find_locked (dds_domainid_t id)
|
||||
{
|
||||
return (dds_domain*) ut_avlLookup (&dds_domaintree_def, &dds_global.m_domains, &id);
|
||||
}
|
||||
|
||||
dds_domain * dds_domain_create (dds_domainid_t id)
|
||||
{
|
||||
dds_domain * domain;
|
||||
os_mutexLock (&dds_global.m_mutex);
|
||||
domain = dds_domain_find_locked (id);
|
||||
if (domain == NULL)
|
||||
{
|
||||
domain = dds_alloc (sizeof (*domain));
|
||||
domain->m_id = id;
|
||||
ut_avlInit (&dds_topictree_def, &domain->m_topics);
|
||||
ut_avlInsert (&dds_domaintree_def, &dds_global.m_domains, domain);
|
||||
}
|
||||
domain->m_refc++;
|
||||
os_mutexUnlock (&dds_global.m_mutex);
|
||||
return domain;
|
||||
}
|
||||
|
||||
void dds_domain_free (dds_domain * domain)
|
||||
{
|
||||
os_mutexLock (&dds_global.m_mutex);
|
||||
if (--domain->m_refc == 0)
|
||||
{
|
||||
ut_avlDelete (&dds_domaintree_def, &dds_global.m_domains, domain);
|
||||
dds_free (domain);
|
||||
}
|
||||
os_mutexUnlock (&dds_global.m_mutex);
|
||||
}
|
||||
1291
src/core/ddsc/src/dds_entity.c
Normal file
1291
src/core/ddsc/src/dds_entity.c
Normal file
File diff suppressed because it is too large
Load diff
102
src/core/ddsc/src/dds_err.c
Normal file
102
src/core/ddsc/src/dds_err.c
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include "os/os.h"
|
||||
#include "dds__types.h"
|
||||
#include "dds__err.h"
|
||||
|
||||
#define DDS_ERR_CODE_NUM 12
|
||||
#define DDS_ERR_MSG_MAX 128
|
||||
|
||||
#define DDS_ERR_NR_INDEX(e) (((-e) & DDS_ERR_NR_MASK) -1)
|
||||
|
||||
static const char * dds_err_code_array[DDS_ERR_CODE_NUM] =
|
||||
{
|
||||
"Error",
|
||||
"Unsupported",
|
||||
"Bad Parameter",
|
||||
"Precondition Not Met",
|
||||
"Out Of Resources",
|
||||
"Not Enabled",
|
||||
"Immutable Policy",
|
||||
"Inconsistent Policy",
|
||||
"Already Deleted",
|
||||
"Timeout",
|
||||
"No Data",
|
||||
"Illegal Operation"
|
||||
};
|
||||
|
||||
const char * dds_err_str (dds_return_t err)
|
||||
{
|
||||
unsigned index = DDS_ERR_NR_INDEX (err);
|
||||
if (err >= 0)
|
||||
{
|
||||
return "Success";
|
||||
}
|
||||
if (index >= DDS_ERR_CODE_NUM)
|
||||
{
|
||||
return "Unknown";
|
||||
}
|
||||
return dds_err_code_array[index];
|
||||
}
|
||||
|
||||
bool dds_err_check (dds_return_t err, unsigned flags, const char * where)
|
||||
{
|
||||
if (err < 0)
|
||||
{
|
||||
if (flags & (DDS_CHECK_REPORT | DDS_CHECK_FAIL))
|
||||
{
|
||||
char msg[DDS_ERR_MSG_MAX];
|
||||
(void) snprintf (msg, DDS_ERR_MSG_MAX, "Error %d:M%d:%s", dds_err_file_id(err), dds_err_line(err), dds_err_str(err));
|
||||
if (flags & DDS_CHECK_REPORT)
|
||||
{
|
||||
printf ("%s: %s\n", where, msg);
|
||||
}
|
||||
if (flags & DDS_CHECK_FAIL)
|
||||
{
|
||||
dds_fail (msg, where);
|
||||
}
|
||||
}
|
||||
if (flags & DDS_CHECK_EXIT)
|
||||
{
|
||||
exit (-1);
|
||||
}
|
||||
}
|
||||
return (err >= 0);
|
||||
}
|
||||
|
||||
|
||||
static void dds_fail_default (const char * msg, const char * where)
|
||||
{
|
||||
fprintf (stderr, "Aborting Failure: %s %s\n", where, msg);
|
||||
abort ();
|
||||
}
|
||||
|
||||
static dds_fail_fn dds_fail_func = dds_fail_default;
|
||||
|
||||
void dds_fail_set (dds_fail_fn fn)
|
||||
{
|
||||
dds_fail_func = fn;
|
||||
}
|
||||
|
||||
dds_fail_fn dds_fail_get (void)
|
||||
{
|
||||
return dds_fail_func;
|
||||
}
|
||||
|
||||
void dds_fail (const char * msg, const char * where)
|
||||
{
|
||||
if (dds_fail_func)
|
||||
{
|
||||
(dds_fail_func) (msg, where);
|
||||
}
|
||||
}
|
||||
79
src/core/ddsc/src/dds_iid.c
Normal file
79
src/core/ddsc/src/dds_iid.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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 "dds__iid.h"
|
||||
#include "ddsi/q_time.h"
|
||||
#include "ddsi/q_globals.h"
|
||||
|
||||
static os_mutex dds_iid_lock_g;
|
||||
static dds_iid dds_iid_g;
|
||||
|
||||
static void dds_tea_encrypt (uint32_t v[2], const uint32_t k[4])
|
||||
{
|
||||
/* TEA encryption straight from Wikipedia */
|
||||
uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
|
||||
uint32_t delta=0x9e3779b9; /* a key schedule constant */
|
||||
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
|
||||
for (i=0; i < 32; i++) { /* basic cycle start */
|
||||
sum += delta;
|
||||
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
|
||||
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
|
||||
} /* end cycle */
|
||||
v[0]=v0; v[1]=v1;
|
||||
}
|
||||
|
||||
static void dds_tea_decrypt (uint32_t v[2], const uint32_t k[4])
|
||||
{
|
||||
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
|
||||
uint32_t delta=0x9e3779b9; /* a key schedule constant */
|
||||
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
|
||||
for (i=0; i<32; i++) { /* basic cycle start */
|
||||
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
|
||||
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
|
||||
sum -= delta;
|
||||
} /* end cycle */
|
||||
v[0]=v0; v[1]=v1;
|
||||
}
|
||||
|
||||
uint64_t dds_iid_gen (void)
|
||||
{
|
||||
uint64_t iid;
|
||||
union { uint64_t u64; uint32_t u32[2]; } tmp;
|
||||
|
||||
os_mutexLock (&dds_iid_lock_g);
|
||||
tmp.u64 = ++dds_iid_g.counter;
|
||||
dds_tea_encrypt (tmp.u32, dds_iid_g.key);
|
||||
iid = tmp.u64;
|
||||
os_mutexUnlock (&dds_iid_lock_g);
|
||||
return iid;
|
||||
}
|
||||
|
||||
void dds_iid_init (void)
|
||||
{
|
||||
union { uint64_t u64; uint32_t u32[2]; } tmp;
|
||||
nn_wctime_t tnow = now ();
|
||||
|
||||
os_mutexInit (&dds_iid_lock_g);
|
||||
|
||||
dds_iid_g.key[0] = (uint32_t) ((uintptr_t) &dds_iid_g);
|
||||
dds_iid_g.key[1] = (uint32_t) tnow.v;
|
||||
dds_iid_g.key[2] = (uint32_t) (tnow.v >> 32);
|
||||
dds_iid_g.key[3] = 0xdeadbeef;
|
||||
|
||||
tmp.u64 = 0;
|
||||
dds_tea_decrypt (tmp.u32, dds_iid_g.key);
|
||||
dds_iid_g.counter = tmp.u64;
|
||||
}
|
||||
|
||||
void dds_iid_fini (void)
|
||||
{
|
||||
os_mutexDestroy (&dds_iid_lock_g);
|
||||
}
|
||||
305
src/core/ddsc/src/dds_init.c
Normal file
305
src/core/ddsc/src/dds_init.c
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
* 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 <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <os/os.h>
|
||||
#include <os/os_report.h>
|
||||
#include "dds__init.h"
|
||||
#include "dds__rhc.h"
|
||||
#include "dds__tkmap.h"
|
||||
#include "dds__iid.h"
|
||||
#include "dds__domain.h"
|
||||
#include "dds__err.h"
|
||||
#include "dds__builtin.h"
|
||||
#include "dds__report.h"
|
||||
#include "ddsi/ddsi_ser.h"
|
||||
#include "ddsi/q_servicelease.h"
|
||||
#include "ddsi/q_entity.h"
|
||||
#include <ddsi/q_config.h>
|
||||
#include "ddsc/ddsc_project.h"
|
||||
|
||||
#ifdef _WRS_KERNEL
|
||||
char *os_environ[] = { NULL };
|
||||
#endif
|
||||
|
||||
#define DOMAIN_ID_MIN 0
|
||||
#define DOMAIN_ID_MAX 230
|
||||
|
||||
struct q_globals gv;
|
||||
|
||||
dds_globals dds_global =
|
||||
{
|
||||
DDS_DOMAIN_DEFAULT, 0,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
static struct cfgst * dds_cfgst = NULL;
|
||||
|
||||
|
||||
|
||||
|
||||
os_mutex dds__init_mutex;
|
||||
|
||||
static void
|
||||
dds__fini_once(void)
|
||||
{
|
||||
os_mutexDestroy(&dds__init_mutex);
|
||||
os_osExit();
|
||||
}
|
||||
|
||||
static void
|
||||
dds__init_once(void)
|
||||
{
|
||||
os_osInit();
|
||||
os_mutexInit(&dds__init_mutex);
|
||||
os_procAtExit(dds__fini_once);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
dds__startup(void)
|
||||
{
|
||||
static os_once_t dds__init_control = OS_ONCE_T_STATIC_INIT;
|
||||
os_once(&dds__init_control, dds__init_once);
|
||||
}
|
||||
|
||||
|
||||
dds_return_t
|
||||
dds_init(void)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
const char * uri;
|
||||
char progname[50];
|
||||
char hostname[64];
|
||||
uint32_t len;
|
||||
|
||||
/* Be sure the DDS lifecycle resources are initialized. */
|
||||
dds__startup();
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
os_mutexLock(&dds__init_mutex);
|
||||
|
||||
dds_global.m_init_count++;
|
||||
if (dds_global.m_init_count > 1)
|
||||
{
|
||||
goto skip;
|
||||
}
|
||||
|
||||
if (ut_handleserver_init() != UT_HANDLE_OK)
|
||||
{
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Failed to initialize internal handle server");
|
||||
goto fail_handleserver;
|
||||
}
|
||||
|
||||
gv.tstart = now ();
|
||||
gv.exception = false;
|
||||
gv.static_logbuf_lock_inited = 0;
|
||||
logbuf_init (&gv.static_logbuf);
|
||||
os_mutexInit (&gv.static_logbuf_lock);
|
||||
gv.static_logbuf_lock_inited = 1;
|
||||
os_mutexInit (&dds_global.m_mutex);
|
||||
|
||||
uri = os_getenv (DDSC_PROJECT_NAME_NOSPACE_CAPS"_URI");
|
||||
dds_cfgst = config_init (uri);
|
||||
if (dds_cfgst == NULL)
|
||||
{
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Failed to parse configuration XML file %s", uri);
|
||||
goto fail_config;
|
||||
}
|
||||
/* The config.domainId can change internally in DDSI. So, remember what the
|
||||
* main configured domain id is. */
|
||||
dds_global.m_default_domain = config.domainId;
|
||||
|
||||
dds__builtin_init();
|
||||
|
||||
if (rtps_config_prep(dds_cfgst) != 0)
|
||||
{
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Failed to configure RTPS.");
|
||||
goto fail_rtps_config;
|
||||
}
|
||||
|
||||
ut_avlInit(&dds_domaintree_def, &dds_global.m_domains);
|
||||
|
||||
/* Start monitoring the liveliness of all threads and renewing the
|
||||
service lease if everything seems well. */
|
||||
|
||||
gv.servicelease = nn_servicelease_new(0, 0);
|
||||
if (gv.servicelease == NULL)
|
||||
{
|
||||
ret = DDS_ERRNO(DDS_RETCODE_OUT_OF_RESOURCES, "Failed to create a servicelease.");
|
||||
goto fail_servicelease_new;
|
||||
}
|
||||
if (nn_servicelease_start_renewing(gv.servicelease) < 0)
|
||||
{
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Failed to start the servicelease.");
|
||||
goto fail_servicelease_start;
|
||||
}
|
||||
|
||||
if (rtps_init() < 0)
|
||||
{
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Failed to initialize RTPS.");
|
||||
goto fail_rtps_init;
|
||||
}
|
||||
upgrade_main_thread();
|
||||
|
||||
/* Set additional default participant properties */
|
||||
|
||||
gv.default_plist_pp.process_id = (unsigned)os_procIdSelf();
|
||||
gv.default_plist_pp.present |= PP_PRISMTECH_PROCESS_ID;
|
||||
if (os_procName(progname, sizeof(progname)) > 0)
|
||||
{
|
||||
gv.default_plist_pp.exec_name = dds_string_dup(progname);
|
||||
}
|
||||
else
|
||||
{
|
||||
gv.default_plist_pp.exec_name = dds_string_alloc(32);
|
||||
(void) snprintf(gv.default_plist_pp.exec_name, 32, "%s: %u", DDSC_PROJECT_NAME, gv.default_plist_pp.process_id);
|
||||
}
|
||||
len = (uint32_t) (13 + strlen(gv.default_plist_pp.exec_name));
|
||||
gv.default_plist_pp.present |= PP_PRISMTECH_EXEC_NAME;
|
||||
if (os_gethostname(hostname, sizeof(hostname)) == os_resultSuccess)
|
||||
{
|
||||
gv.default_plist_pp.node_name = dds_string_dup(hostname);
|
||||
gv.default_plist_pp.present |= PP_PRISMTECH_NODE_NAME;
|
||||
}
|
||||
gv.default_plist_pp.entity_name = dds_alloc(len);
|
||||
(void) snprintf(gv.default_plist_pp.entity_name, len, "%s<%u>", progname,
|
||||
gv.default_plist_pp.process_id);
|
||||
gv.default_plist_pp.present |= PP_ENTITY_NAME;
|
||||
|
||||
skip:
|
||||
os_mutexUnlock(&dds__init_mutex);
|
||||
DDS_REPORT_FLUSH(false);
|
||||
return DDS_RETCODE_OK;
|
||||
|
||||
fail_rtps_init:
|
||||
fail_servicelease_start:
|
||||
nn_servicelease_free (gv.servicelease);
|
||||
gv.servicelease = NULL;
|
||||
fail_servicelease_new:
|
||||
thread_states_fini();
|
||||
fail_rtps_config:
|
||||
dds__builtin_fini();
|
||||
dds_global.m_default_domain = DDS_DOMAIN_DEFAULT;
|
||||
config_fini (dds_cfgst);
|
||||
dds_cfgst = NULL;
|
||||
fail_config:
|
||||
gv.static_logbuf_lock_inited = 0;
|
||||
os_mutexDestroy (&gv.static_logbuf_lock);
|
||||
os_mutexDestroy (&dds_global.m_mutex);
|
||||
ut_handleserver_fini();
|
||||
fail_handleserver:
|
||||
dds_global.m_init_count--;
|
||||
os_mutexUnlock(&dds__init_mutex);
|
||||
DDS_REPORT_FLUSH(true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void dds_fini (void)
|
||||
{
|
||||
os_mutexLock(&dds__init_mutex);
|
||||
assert(dds_global.m_init_count > 0);
|
||||
dds_global.m_init_count--;
|
||||
if (dds_global.m_init_count == 0)
|
||||
{
|
||||
dds__builtin_fini();
|
||||
|
||||
ut_handleserver_fini();
|
||||
rtps_term ();
|
||||
nn_servicelease_free (gv.servicelease);
|
||||
gv.servicelease = NULL;
|
||||
downgrade_main_thread ();
|
||||
thread_states_fini ();
|
||||
|
||||
config_fini (dds_cfgst);
|
||||
dds_cfgst = NULL;
|
||||
os_mutexDestroy (&gv.static_logbuf_lock);
|
||||
os_mutexDestroy (&dds_global.m_mutex);
|
||||
dds_global.m_default_domain = DDS_DOMAIN_DEFAULT;
|
||||
}
|
||||
os_mutexUnlock(&dds__init_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int dds__init_plugin (void)
|
||||
{
|
||||
os_mutexInit (&gv.attach_lock);
|
||||
dds_iid_init ();
|
||||
if (dds_global.m_dur_init) (dds_global.m_dur_init) ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dds__fini_plugin (void)
|
||||
{
|
||||
os_mutexDestroy (&gv.attach_lock);
|
||||
if (dds_global.m_dur_fini) (dds_global.m_dur_fini) ();
|
||||
dds_iid_fini ();
|
||||
}
|
||||
|
||||
void ddsi_plugin_init (void)
|
||||
{
|
||||
/* Register initialization/clean functions */
|
||||
|
||||
ddsi_plugin.init_fn = dds__init_plugin;
|
||||
ddsi_plugin.fini_fn = dds__fini_plugin;
|
||||
|
||||
/* Register read cache functions */
|
||||
|
||||
ddsi_plugin.rhc_free_fn = dds_rhc_free;
|
||||
ddsi_plugin.rhc_fini_fn = dds_rhc_fini;
|
||||
ddsi_plugin.rhc_store_fn = dds_rhc_store;
|
||||
ddsi_plugin.rhc_unregister_wr_fn = dds_rhc_unregister_wr;
|
||||
ddsi_plugin.rhc_relinquish_ownership_fn = dds_rhc_relinquish_ownership;
|
||||
ddsi_plugin.rhc_set_qos_fn = dds_rhc_set_qos;
|
||||
ddsi_plugin.rhc_lookup_fn = dds_tkmap_lookup_instance_ref;
|
||||
ddsi_plugin.rhc_unref_fn = dds_tkmap_instance_unref;
|
||||
|
||||
/* Register iid generator */
|
||||
|
||||
ddsi_plugin.iidgen_fn = dds_iid_gen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//provides explicit default domain id.
|
||||
dds_domainid_t dds_domain_default (void)
|
||||
{
|
||||
return dds_global.m_default_domain;
|
||||
}
|
||||
|
||||
|
||||
dds_return_t
|
||||
dds__check_domain(
|
||||
_In_ dds_domainid_t domain)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
/* If domain is default: use configured id. */
|
||||
if (domain != DDS_DOMAIN_DEFAULT)
|
||||
{
|
||||
/* Specific domain has to be the same as the configured domain. */
|
||||
if (domain != dds_global.m_default_domain)
|
||||
{
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR,
|
||||
"Inconsistent domain configuration detected: domain on configuration: %d, domain %d",
|
||||
dds_global.m_default_domain, domain);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
468
src/core/ddsc/src/dds_instance.c
Normal file
468
src/core/ddsc/src/dds_instance.c
Normal file
|
|
@ -0,0 +1,468 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
#include "ddsc/dds.h"
|
||||
#include "dds__entity.h"
|
||||
#include "dds__write.h"
|
||||
#include "dds__writer.h"
|
||||
#include "dds__rhc.h"
|
||||
#include "dds__tkmap.h"
|
||||
#include "dds__err.h"
|
||||
#include "ddsi/ddsi_ser.h"
|
||||
#include "ddsi/q_entity.h"
|
||||
#include "ddsi/q_thread.h"
|
||||
#include "q__osplser.h"
|
||||
#include "dds__report.h"
|
||||
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
dds_return_t
|
||||
dds_writedispose(
|
||||
_In_ dds_entity_t writer,
|
||||
_In_ const void *data)
|
||||
{
|
||||
dds_return_t ret;
|
||||
DDS_REPORT_STACK();
|
||||
ret = dds_writedispose_ts(writer, data, dds_time());
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK );
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
dds_return_t
|
||||
dds_dispose(
|
||||
_In_ dds_entity_t writer,
|
||||
_In_ const void *data)
|
||||
{
|
||||
dds_return_t ret;
|
||||
DDS_REPORT_STACK();
|
||||
ret = dds_dispose_ts(writer, data, dds_time());
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK );
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
dds_return_t
|
||||
dds_dispose_ih(
|
||||
_In_ dds_entity_t writer,
|
||||
_In_ dds_instance_handle_t handle)
|
||||
{
|
||||
dds_return_t ret;
|
||||
DDS_REPORT_STACK();
|
||||
ret = dds_dispose_ih_ts(writer, handle, dds_time());
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct tkmap_instance*
|
||||
dds_instance_find(
|
||||
_In_ const dds_topic *topic,
|
||||
_In_ const void *data,
|
||||
_In_ const bool create)
|
||||
{
|
||||
serdata_t sd = serialize_key (gv.serpool, topic->m_stopic, data);
|
||||
struct tkmap_instance * inst = dds_tkmap_find (topic, sd, false, create);
|
||||
ddsi_serdata_unref (sd);
|
||||
return inst;
|
||||
}
|
||||
|
||||
static void
|
||||
dds_instance_remove(
|
||||
_In_ const dds_topic *topic,
|
||||
_In_opt_ const void *data,
|
||||
_In_ dds_instance_handle_t handle)
|
||||
{
|
||||
struct tkmap_instance * inst;
|
||||
|
||||
if (handle != DDS_HANDLE_NIL) {
|
||||
inst = dds_tkmap_find_by_id (gv.m_tkmap, handle);
|
||||
} else {
|
||||
assert (data);
|
||||
inst = dds_instance_find (topic, data, false);
|
||||
}
|
||||
|
||||
if (inst) {
|
||||
struct thread_state1 * const thr = lookup_thread_state();
|
||||
const bool asleep = thr ? !vtime_awake_p(thr->vtime) : false;
|
||||
if (asleep) {
|
||||
thread_state_awake(thr);
|
||||
}
|
||||
dds_tkmap_instance_unref (inst);
|
||||
if (asleep) {
|
||||
thread_state_asleep(thr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const dds_topic*
|
||||
dds_instance_info(
|
||||
_In_ dds_entity *e)
|
||||
{
|
||||
const dds_topic *topic = NULL;
|
||||
|
||||
assert (e);
|
||||
assert ((dds_entity_kind(e->m_hdl) == DDS_KIND_READER) || (dds_entity_kind(e->m_hdl) == DDS_KIND_WRITER));
|
||||
|
||||
if (dds_entity_kind(e->m_hdl) == DDS_KIND_READER) {
|
||||
topic = ((dds_reader*)e)->m_topic;
|
||||
} else {
|
||||
topic = ((dds_writer*)e)->m_topic;
|
||||
}
|
||||
return topic;
|
||||
}
|
||||
|
||||
static const dds_topic * dds_instance_info_by_hdl (dds_entity_t e)
|
||||
{
|
||||
const dds_topic * topic = NULL;
|
||||
dds__retcode_t rc;
|
||||
dds_entity *w_or_r;
|
||||
|
||||
rc = dds_entity_lock(e, DDS_KIND_WRITER, &w_or_r);
|
||||
if (rc == DDS_RETCODE_ILLEGAL_OPERATION) {
|
||||
rc = dds_entity_lock(e, DDS_KIND_READER, &w_or_r);
|
||||
}
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
topic = dds_instance_info(w_or_r);
|
||||
dds_entity_unlock(w_or_r);
|
||||
}
|
||||
else {
|
||||
DDS_ERROR(rc, "Error occurred on locking entity");
|
||||
}
|
||||
return topic;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
dds_return_t
|
||||
dds_register_instance(
|
||||
_In_ dds_entity_t writer,
|
||||
_Out_ dds_instance_handle_t *handle,
|
||||
_In_ const void *data)
|
||||
{
|
||||
struct tkmap_instance * inst;
|
||||
dds_entity *wr;
|
||||
dds_return_t ret;
|
||||
dds__retcode_t rc;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if(data == NULL){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument data is NULL");
|
||||
goto err;
|
||||
}
|
||||
if(handle == NULL){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument handle is NULL");
|
||||
goto err;
|
||||
}
|
||||
rc = dds_entity_lock(writer, DDS_KIND_WRITER, &wr);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking writer");
|
||||
goto err;
|
||||
}
|
||||
inst = dds_instance_find (((dds_writer*) wr)->m_topic, data, true);
|
||||
if(inst != NULL){
|
||||
*handle = inst->m_iid;
|
||||
ret = DDS_RETCODE_OK;
|
||||
} else{
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Unable to create instance");
|
||||
}
|
||||
dds_entity_unlock(wr);
|
||||
err:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
dds_return_t
|
||||
dds_unregister_instance(
|
||||
_In_ dds_entity_t writer,
|
||||
_In_opt_ const void *data)
|
||||
{
|
||||
dds_return_t ret;
|
||||
DDS_REPORT_STACK();
|
||||
ret = dds_unregister_instance_ts (writer, data, dds_time());
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK );
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
dds_return_t
|
||||
dds_unregister_instance_ih(
|
||||
_In_ dds_entity_t writer,
|
||||
_In_opt_ dds_instance_handle_t handle)
|
||||
{
|
||||
dds_return_t ret;
|
||||
DDS_REPORT_STACK();
|
||||
ret = dds_unregister_instance_ih_ts(writer, handle, dds_time());
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK );
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
dds_return_t
|
||||
dds_unregister_instance_ts(
|
||||
_In_ dds_entity_t writer,
|
||||
_In_opt_ const void *data,
|
||||
_In_ dds_time_t timestamp)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
dds__retcode_t rc;
|
||||
bool autodispose = true;
|
||||
dds_write_action action = DDS_WR_ACTION_UNREGISTER;
|
||||
void * sample = (void*) data;
|
||||
dds_entity *wr;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (data == NULL){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument data is NULL");
|
||||
goto err;
|
||||
}
|
||||
if(timestamp < 0){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument timestamp has negative value");
|
||||
goto err;
|
||||
}
|
||||
rc = dds_entity_lock(writer, DDS_KIND_WRITER, &wr);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking writer");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (wr->m_qos) {
|
||||
dds_qget_writer_data_lifecycle (wr->m_qos, &autodispose);
|
||||
}
|
||||
if (autodispose) {
|
||||
dds_instance_remove (((dds_writer*) wr)->m_topic, data, DDS_HANDLE_NIL);
|
||||
action |= DDS_WR_DISPOSE_BIT;
|
||||
}
|
||||
ret = dds_write_impl ((dds_writer*)wr, sample, timestamp, action);
|
||||
dds_entity_unlock(wr);
|
||||
err:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
dds_return_t
|
||||
dds_unregister_instance_ih_ts(
|
||||
_In_ dds_entity_t writer,
|
||||
_In_opt_ dds_instance_handle_t handle,
|
||||
_In_ dds_time_t timestamp)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
dds__retcode_t rc;
|
||||
bool autodispose = true;
|
||||
dds_write_action action = DDS_WR_ACTION_UNREGISTER;
|
||||
dds_entity *wr;
|
||||
struct tkmap *map;
|
||||
const dds_topic *topic;
|
||||
void *sample;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_entity_lock(writer, DDS_KIND_WRITER, &wr);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking writer");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (wr->m_qos) {
|
||||
dds_qget_writer_data_lifecycle (wr->m_qos, &autodispose);
|
||||
}
|
||||
if (autodispose) {
|
||||
dds_instance_remove (((dds_writer*) wr)->m_topic, NULL, handle);
|
||||
action |= DDS_WR_DISPOSE_BIT;
|
||||
}
|
||||
|
||||
map = gv.m_tkmap;
|
||||
topic = dds_instance_info((dds_entity*)wr);
|
||||
sample = dds_alloc (topic->m_descriptor->m_size);
|
||||
if (dds_tkmap_get_key (map, handle, sample)) {
|
||||
ret = dds_write_impl ((dds_writer*)wr, sample, timestamp, action);
|
||||
} else{
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "No instance related with the provided handle is found");
|
||||
}
|
||||
dds_sample_free (sample, topic->m_descriptor, DDS_FREE_ALL);
|
||||
|
||||
dds_entity_unlock(wr);
|
||||
err:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
dds_return_t
|
||||
dds_writedispose_ts(
|
||||
_In_ dds_entity_t writer,
|
||||
_In_ const void *data,
|
||||
_In_ dds_time_t timestamp)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds__retcode_t rc;
|
||||
dds_writer *wr;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_writer_lock(writer, &wr);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
ret = dds_write_impl (wr, data, timestamp, DDS_WR_ACTION_WRITE_DISPOSE);
|
||||
if (ret == DDS_RETCODE_OK) {
|
||||
dds_instance_remove (wr->m_topic, data, DDS_HANDLE_NIL);
|
||||
}
|
||||
dds_writer_unlock(wr);
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking writer");
|
||||
}
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_dispose_impl(
|
||||
_In_ dds_writer *wr,
|
||||
_In_ const void *data,
|
||||
_In_ dds_instance_handle_t handle,
|
||||
_In_ dds_time_t timestamp)
|
||||
{
|
||||
dds_return_t ret;
|
||||
assert(wr);
|
||||
ret = dds_write_impl(wr, data, timestamp, DDS_WR_ACTION_DISPOSE);
|
||||
if (ret == DDS_RETCODE_OK) {
|
||||
dds_instance_remove (wr->m_topic, data, handle);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
dds_return_t
|
||||
dds_dispose_ts(
|
||||
_In_ dds_entity_t writer,
|
||||
_In_ const void *data,
|
||||
_In_ dds_time_t timestamp)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds__retcode_t rc;
|
||||
dds_writer *wr;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_writer_lock(writer, &wr);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
ret = dds_dispose_impl(wr, data, DDS_HANDLE_NIL, timestamp);
|
||||
dds_writer_unlock(wr);
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking writer");
|
||||
}
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
dds_return_t
|
||||
dds_dispose_ih_ts(
|
||||
_In_ dds_entity_t writer,
|
||||
_In_ dds_instance_handle_t handle,
|
||||
_In_ dds_time_t timestamp)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds__retcode_t rc;
|
||||
dds_writer *wr;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_writer_lock(writer, &wr);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
struct tkmap *map = gv.m_tkmap;
|
||||
const dds_topic *topic = dds_instance_info((dds_entity*)wr);
|
||||
void *sample = dds_alloc (topic->m_descriptor->m_size);
|
||||
if (dds_tkmap_get_key (map, handle, sample)) {
|
||||
ret = dds_dispose_impl(wr, sample, handle, timestamp);
|
||||
} else {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "No instance related with the provided handle is found");
|
||||
}
|
||||
dds_free(sample);
|
||||
dds_writer_unlock(wr);
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking writer");
|
||||
}
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(entity & DDS_ENTITY_KIND_MASK)
|
||||
dds_instance_handle_t
|
||||
dds_instance_lookup(
|
||||
dds_entity_t entity,
|
||||
const void *data)
|
||||
{
|
||||
dds_instance_handle_t ih = DDS_HANDLE_NIL;
|
||||
const dds_topic * topic;
|
||||
struct tkmap * map = gv.m_tkmap;
|
||||
serdata_t sd;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if(data == NULL){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument data is NULL");
|
||||
goto err;
|
||||
}
|
||||
|
||||
topic = dds_instance_info_by_hdl (entity);
|
||||
if (topic) {
|
||||
sd = serialize_key (gv.serpool, topic->m_stopic, data);
|
||||
ih = dds_tkmap_lookup (map, sd);
|
||||
ddsi_serdata_unref (sd);
|
||||
ret = DDS_RETCODE_OK;
|
||||
} else {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Acquired topic is NULL");
|
||||
}
|
||||
err:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ih;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(entity & DDS_ENTITY_KIND_MASK)
|
||||
int
|
||||
dds_instance_get_key(
|
||||
dds_entity_t entity,
|
||||
dds_instance_handle_t inst,
|
||||
void *data)
|
||||
{
|
||||
dds_return_t ret;
|
||||
const dds_topic * topic;
|
||||
struct tkmap * map = gv.m_tkmap;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if(data == NULL){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument data is NULL");
|
||||
goto err;
|
||||
}
|
||||
|
||||
topic = dds_instance_info_by_hdl (entity);
|
||||
if(topic == NULL){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Could not find topic related to the given entity");
|
||||
goto err;
|
||||
}
|
||||
memset (data, 0, topic->m_descriptor->m_size);
|
||||
|
||||
if (dds_tkmap_get_key (map, inst, data)) {
|
||||
ret = DDS_RETCODE_OK;
|
||||
} else{
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "No instance related with the provided entity is found");
|
||||
}
|
||||
|
||||
err:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
166
src/core/ddsc/src/dds_key.c
Normal file
166
src/core/ddsc/src/dds_key.c
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
#include "dds__key.h"
|
||||
#include "dds__stream.h"
|
||||
#include "ddsi/ddsi_ser.h"
|
||||
#include "ddsi/q_bswap.h"
|
||||
#include "ddsi/q_md5.h"
|
||||
|
||||
void dds_key_md5 (dds_key_hash_t * kh)
|
||||
{
|
||||
md5_state_t md5st;
|
||||
md5_init (&md5st);
|
||||
md5_append (&md5st, (md5_byte_t*) kh->m_key_buff, kh->m_key_len);
|
||||
md5_finish (&md5st, (unsigned char *) kh->m_hash);
|
||||
}
|
||||
|
||||
/*
|
||||
dds_key_gen: Generates key and keyhash for a sample.
|
||||
See section 9.6.3.3 of DDSI spec.
|
||||
*/
|
||||
|
||||
void dds_key_gen
|
||||
(
|
||||
const dds_topic_descriptor_t * const desc,
|
||||
dds_key_hash_t * kh,
|
||||
const char * sample
|
||||
)
|
||||
{
|
||||
const char * src;
|
||||
const uint32_t * op;
|
||||
uint32_t i;
|
||||
uint32_t len = 0;
|
||||
char * dst;
|
||||
|
||||
assert (desc->m_nkeys);
|
||||
assert (kh->m_hash[0] == 0 && kh->m_hash[15] == 0);
|
||||
|
||||
kh->m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET;
|
||||
|
||||
/* Select key buffer to use */
|
||||
|
||||
if (desc->m_flagset & DDS_TOPIC_FIXED_KEY)
|
||||
{
|
||||
kh->m_flags |= DDS_KEY_IS_HASH;
|
||||
kh->m_key_len = sizeof (kh->m_hash);
|
||||
dst = kh->m_hash;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate key length */
|
||||
|
||||
for (i = 0; i < desc->m_nkeys; i++)
|
||||
{
|
||||
op = desc->m_ops + desc->m_keys[i].m_index;
|
||||
src = sample + op[1];
|
||||
|
||||
switch (DDS_OP_TYPE (*op))
|
||||
{
|
||||
case DDS_OP_VAL_1BY: len += 1; break;
|
||||
case DDS_OP_VAL_2BY: len += 2; break;
|
||||
case DDS_OP_VAL_4BY: len += 4; break;
|
||||
case DDS_OP_VAL_8BY: len += 8; break;
|
||||
case DDS_OP_VAL_STR: src = *((char**) src); /* Fall-through intentional */
|
||||
case DDS_OP_VAL_BST: len += (uint32_t) (5 + strlen (src)); break;
|
||||
case DDS_OP_VAL_ARR:
|
||||
len += op[2] * dds_op_size[DDS_OP_SUBTYPE (*op)];
|
||||
break;
|
||||
default: assert (0);
|
||||
}
|
||||
}
|
||||
|
||||
kh->m_key_len = len;
|
||||
if (len > kh->m_key_buff_size)
|
||||
{
|
||||
kh->m_key_buff = dds_realloc_zero (kh->m_key_buff, len);
|
||||
kh->m_key_buff_size = len;
|
||||
}
|
||||
dst = kh->m_key_buff;
|
||||
}
|
||||
|
||||
/* Write keys to buffer (Big Endian CDR encoded with no padding) */
|
||||
|
||||
for (i = 0; i < desc->m_nkeys; i++)
|
||||
{
|
||||
op = desc->m_ops + desc->m_keys[i].m_index;
|
||||
src = sample + op[1];
|
||||
assert ((*op & DDS_OP_FLAG_KEY) && ((DDS_OP_MASK & *op) == DDS_OP_ADR));
|
||||
|
||||
switch (DDS_OP_TYPE (*op))
|
||||
{
|
||||
case DDS_OP_VAL_1BY:
|
||||
{
|
||||
*dst = *src;
|
||||
dst++;
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_2BY:
|
||||
{
|
||||
uint16_t u16 = toBE2u (*((const uint16_t*) src));
|
||||
memcpy (dst, &u16, sizeof (u16));
|
||||
dst += sizeof (u16);
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_4BY:
|
||||
{
|
||||
uint32_t u32 = toBE4u (*((const uint32_t*) src));
|
||||
memcpy (dst, &u32, sizeof (u32));
|
||||
dst += sizeof (u32);
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_8BY:
|
||||
{
|
||||
uint64_t u64 = toBE8u (*((const uint64_t*) src));
|
||||
memcpy (dst, &u64, sizeof (u64));
|
||||
dst += sizeof (u64);
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_STR:
|
||||
{
|
||||
src = *((char**) src);
|
||||
} /* Fall-through intentional */
|
||||
case DDS_OP_VAL_BST:
|
||||
{
|
||||
uint32_t u32;
|
||||
len = (uint32_t) (strlen (src) + 1);
|
||||
u32 = toBE4u (len);
|
||||
memcpy (dst, &u32, sizeof (u32));
|
||||
dst += sizeof (u32);
|
||||
memcpy (dst, src, len);
|
||||
dst += len;
|
||||
break;
|
||||
}
|
||||
case DDS_OP_VAL_ARR:
|
||||
{
|
||||
uint32_t size = dds_op_size[DDS_OP_SUBTYPE (*op)];
|
||||
len = size * op[2];
|
||||
memcpy (dst, src, len);
|
||||
if (dds_stream_endian () && (size != 1u))
|
||||
{
|
||||
dds_stream_swap (dst, size, op[2]);
|
||||
}
|
||||
dst += len;
|
||||
break;
|
||||
}
|
||||
default: assert (0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash is md5 of key */
|
||||
|
||||
if ((kh->m_flags & DDS_KEY_IS_HASH) == 0)
|
||||
{
|
||||
dds_key_md5 (kh);
|
||||
}
|
||||
}
|
||||
462
src/core/ddsc/src/dds_listener.c
Normal file
462
src/core/ddsc/src/dds_listener.c
Normal file
|
|
@ -0,0 +1,462 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include "ddsc/dds.h"
|
||||
#include "dds__listener.h"
|
||||
#include "dds__report.h"
|
||||
|
||||
|
||||
|
||||
_Ret_notnull_
|
||||
dds_listener_t*
|
||||
dds_listener_create(_In_opt_ void* arg)
|
||||
{
|
||||
c_listener_t *l = dds_alloc(sizeof(*l));
|
||||
dds_listener_reset(l);
|
||||
l->arg = arg;
|
||||
return l;
|
||||
}
|
||||
|
||||
void
|
||||
dds_listener_delete(_In_ _Post_invalid_ dds_listener_t * __restrict listener)
|
||||
{
|
||||
if (listener) {
|
||||
dds_free(listener);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dds_listener_reset(_Out_ dds_listener_t * __restrict listener)
|
||||
{
|
||||
if (listener) {
|
||||
c_listener_t *l = listener;
|
||||
l->on_data_available = DDS_LUNSET;
|
||||
l->on_data_on_readers = DDS_LUNSET;
|
||||
l->on_inconsistent_topic = DDS_LUNSET;
|
||||
l->on_liveliness_changed = DDS_LUNSET;
|
||||
l->on_liveliness_lost = DDS_LUNSET;
|
||||
l->on_offered_deadline_missed = DDS_LUNSET;
|
||||
l->on_offered_incompatible_qos = DDS_LUNSET;
|
||||
l->on_publication_matched = DDS_LUNSET;
|
||||
l->on_requested_deadline_missed = DDS_LUNSET;
|
||||
l->on_requested_incompatible_qos = DDS_LUNSET;
|
||||
l->on_sample_lost = DDS_LUNSET;
|
||||
l->on_sample_rejected = DDS_LUNSET;
|
||||
l->on_subscription_matched = DDS_LUNSET;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_listener_copy(_Out_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src)
|
||||
{
|
||||
const c_listener_t *srcl = src;
|
||||
c_listener_t *dstl = dst;
|
||||
|
||||
if(!src){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument source(src) is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!dst){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument destination(dst) is NULL");
|
||||
return ;
|
||||
}
|
||||
dstl->on_data_available = srcl->on_data_available;
|
||||
dstl->on_data_on_readers = srcl->on_data_on_readers;
|
||||
dstl->on_inconsistent_topic = srcl->on_inconsistent_topic;
|
||||
dstl->on_liveliness_changed = srcl->on_liveliness_changed;
|
||||
dstl->on_liveliness_lost = srcl->on_liveliness_lost;
|
||||
dstl->on_offered_deadline_missed = srcl->on_offered_deadline_missed;
|
||||
dstl->on_offered_incompatible_qos = srcl->on_offered_incompatible_qos;
|
||||
dstl->on_publication_matched = srcl->on_publication_matched;
|
||||
dstl->on_requested_deadline_missed = srcl->on_requested_deadline_missed;
|
||||
dstl->on_requested_incompatible_qos = srcl->on_requested_incompatible_qos;
|
||||
dstl->on_sample_lost = srcl->on_sample_lost;
|
||||
dstl->on_sample_rejected = srcl->on_sample_rejected;
|
||||
dstl->on_subscription_matched = srcl->on_subscription_matched;
|
||||
}
|
||||
|
||||
void
|
||||
dds_listener_merge (_Inout_ dds_listener_t * __restrict dst, _In_ const dds_listener_t * __restrict src)
|
||||
{
|
||||
const c_listener_t *srcl = src;
|
||||
c_listener_t *dstl = dst;
|
||||
|
||||
if(!src){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument source(src) is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!dst){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument destination(dst) is NULL");
|
||||
return ;
|
||||
}
|
||||
if (dstl->on_data_available == DDS_LUNSET) {
|
||||
dstl->on_data_available = srcl->on_data_available;
|
||||
}
|
||||
if (dstl->on_data_on_readers == DDS_LUNSET) {
|
||||
dstl->on_data_on_readers = srcl->on_data_on_readers;
|
||||
}
|
||||
if (dstl->on_inconsistent_topic == DDS_LUNSET) {
|
||||
dstl->on_inconsistent_topic = srcl->on_inconsistent_topic;
|
||||
}
|
||||
if (dstl->on_liveliness_changed == DDS_LUNSET) {
|
||||
dstl->on_liveliness_changed = srcl->on_liveliness_changed;
|
||||
}
|
||||
if (dstl->on_liveliness_lost == DDS_LUNSET) {
|
||||
dstl->on_liveliness_lost = srcl->on_liveliness_lost;
|
||||
}
|
||||
if (dstl->on_offered_deadline_missed == DDS_LUNSET) {
|
||||
dstl->on_offered_deadline_missed = srcl->on_offered_deadline_missed;
|
||||
}
|
||||
if (dstl->on_offered_incompatible_qos == DDS_LUNSET) {
|
||||
dstl->on_offered_incompatible_qos = srcl->on_offered_incompatible_qos;
|
||||
}
|
||||
if (dstl->on_publication_matched == DDS_LUNSET) {
|
||||
dstl->on_publication_matched = srcl->on_publication_matched;
|
||||
}
|
||||
if (dstl->on_requested_deadline_missed == DDS_LUNSET) {
|
||||
dstl->on_requested_deadline_missed = srcl->on_requested_deadline_missed;
|
||||
}
|
||||
if (dstl->on_requested_incompatible_qos == DDS_LUNSET) {
|
||||
dstl->on_requested_incompatible_qos = srcl->on_requested_incompatible_qos;
|
||||
}
|
||||
if (dstl->on_sample_lost == DDS_LUNSET) {
|
||||
dstl->on_sample_lost = srcl->on_sample_lost;
|
||||
}
|
||||
if (dstl->on_sample_rejected == DDS_LUNSET) {
|
||||
dstl->on_sample_rejected = srcl->on_sample_rejected;
|
||||
}
|
||||
if (dstl->on_subscription_matched == DDS_LUNSET) {
|
||||
dstl->on_subscription_matched = srcl->on_subscription_matched;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************************************
|
||||
* Setters
|
||||
************************************************************************************************/
|
||||
|
||||
void
|
||||
dds_lset_data_available (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_data_available_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
((c_listener_t*)listener)->on_data_available = callback;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_data_on_readers (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_data_on_readers_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
((c_listener_t*)listener)->on_data_on_readers = callback;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_inconsistent_topic (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_inconsistent_topic_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
((c_listener_t*)listener)->on_inconsistent_topic = callback;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_liveliness_changed (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_liveliness_changed_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
((c_listener_t*)listener)->on_liveliness_changed = callback;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_liveliness_lost (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_liveliness_lost_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
((c_listener_t*)listener)->on_liveliness_lost = callback;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_offered_deadline_missed (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_offered_deadline_missed_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
((c_listener_t*)listener)->on_offered_deadline_missed = callback;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_offered_incompatible_qos (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_offered_incompatible_qos_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
((c_listener_t*)listener)->on_offered_incompatible_qos = callback;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_publication_matched (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_publication_matched_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
((c_listener_t*)listener)->on_publication_matched = callback;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_requested_deadline_missed (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_requested_deadline_missed_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
((c_listener_t*)listener)->on_requested_deadline_missed = callback;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_requested_incompatible_qos (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_requested_incompatible_qos_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
((c_listener_t*)listener)->on_requested_incompatible_qos = callback;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_sample_lost (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_sample_lost_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
((c_listener_t*)listener)->on_sample_lost = callback;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_sample_rejected (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_sample_rejected_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
((c_listener_t*)listener)->on_sample_rejected = callback;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_lset_subscription_matched (_Inout_ dds_listener_t * __restrict listener, _In_opt_ dds_on_subscription_matched_fn callback)
|
||||
{
|
||||
if (listener) {
|
||||
((c_listener_t*)listener)->on_subscription_matched = callback;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************************************
|
||||
* Getters
|
||||
************************************************************************************************/
|
||||
|
||||
void
|
||||
dds_lget_data_available (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_data_available_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument callback is NULL");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
return ;
|
||||
}
|
||||
*callback = ((c_listener_t*)listener)->on_data_available;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_data_on_readers (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_data_on_readers_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument callback is NULL");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
return ;
|
||||
}
|
||||
*callback = ((c_listener_t*)listener)->on_data_on_readers;
|
||||
}
|
||||
|
||||
void dds_lget_inconsistent_topic (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_inconsistent_topic_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument callback is NULL");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
return ;
|
||||
}
|
||||
*callback = ((c_listener_t*)listener)->on_inconsistent_topic;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_liveliness_changed (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_liveliness_changed_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument callback is NULL");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
return ;
|
||||
}
|
||||
*callback = ((c_listener_t*)listener)->on_liveliness_changed;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_liveliness_lost (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_liveliness_lost_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument callback is NULL");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
return ;
|
||||
}
|
||||
*callback = ((c_listener_t*)listener)->on_liveliness_lost;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_offered_deadline_missed (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_offered_deadline_missed_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument callback is NULL");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
return ;
|
||||
}
|
||||
*callback = ((c_listener_t*)listener)->on_offered_deadline_missed;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_offered_incompatible_qos (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_offered_incompatible_qos_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument callback is NULL");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
return ;
|
||||
}
|
||||
*callback = ((c_listener_t*)listener)->on_offered_incompatible_qos;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_publication_matched (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_publication_matched_fn *callback)
|
||||
{
|
||||
if(!callback){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument callback is NULL");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
return ;
|
||||
}
|
||||
*callback = ((c_listener_t*)listener)->on_publication_matched;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_requested_deadline_missed (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_requested_deadline_missed_fn *callback)
|
||||
{
|
||||
if(!callback) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument callback is NULL");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
return ;
|
||||
}
|
||||
*callback = ((c_listener_t*)listener)->on_requested_deadline_missed;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_requested_incompatible_qos (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_requested_incompatible_qos_fn *callback)
|
||||
{
|
||||
if(!callback) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument callback is NULL");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
return ;
|
||||
}
|
||||
*callback = ((c_listener_t*)listener)->on_requested_incompatible_qos;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_sample_lost (_In_ const dds_listener_t *__restrict listener, _Outptr_result_maybenull_ dds_on_sample_lost_fn *callback)
|
||||
{
|
||||
if(!callback) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument callback is NULL");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
return ;
|
||||
}
|
||||
*callback = ((c_listener_t*)listener)->on_sample_lost;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_sample_rejected (_In_ const dds_listener_t *__restrict listener, _Outptr_result_maybenull_ dds_on_sample_rejected_fn *callback)
|
||||
{
|
||||
if(!callback) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument callback is NULL");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
return ;
|
||||
}
|
||||
*callback = ((c_listener_t*)listener)->on_sample_rejected;
|
||||
}
|
||||
|
||||
void
|
||||
dds_lget_subscription_matched (_In_ const dds_listener_t * __restrict listener, _Outptr_result_maybenull_ dds_on_subscription_matched_fn *callback)
|
||||
{
|
||||
if(!callback) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument callback is NULL");
|
||||
return ;
|
||||
}
|
||||
if (!listener) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument listener is NULL");
|
||||
return ;
|
||||
}
|
||||
*callback = ((c_listener_t*)listener)->on_subscription_matched;
|
||||
}
|
||||
73
src/core/ddsc/src/dds_log.c
Normal file
73
src/core/ddsc/src/dds_log.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "ddsc/dds.h"
|
||||
#include "ddsi/q_log.h"
|
||||
|
||||
#define DDS_FMT_MAX 128
|
||||
|
||||
void dds_log_info (const char * fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start (args, fmt);
|
||||
nn_vlog (LC_INFO, fmt, args);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
void dds_log_warn (const char * fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char fmt2 [DDS_FMT_MAX];
|
||||
|
||||
strcpy (fmt2, "<Warning> ");
|
||||
strncat (fmt2, fmt, DDS_FMT_MAX - 11);
|
||||
fmt2[DDS_FMT_MAX-1] = 0;
|
||||
fmt = fmt2;
|
||||
|
||||
va_start (args, fmt);
|
||||
nn_vlog (LC_WARNING, fmt, args);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
void dds_log_error (const char * fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char fmt2 [DDS_FMT_MAX];
|
||||
|
||||
strcpy (fmt2, "<Error> ");
|
||||
strncat (fmt2, fmt, DDS_FMT_MAX - 9);
|
||||
fmt2[DDS_FMT_MAX-1] = 0;
|
||||
fmt = fmt2;
|
||||
|
||||
va_start (args, fmt);
|
||||
nn_vlog (LC_ERROR, fmt, args);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
void dds_log_fatal (const char * fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char fmt2 [DDS_FMT_MAX];
|
||||
|
||||
strcpy (fmt2, "<Fatal> ");
|
||||
strncat (fmt2, fmt, DDS_FMT_MAX - 9);
|
||||
fmt2[DDS_FMT_MAX-1] = 0;
|
||||
fmt = fmt2;
|
||||
|
||||
va_start (args, fmt);
|
||||
nn_vlog (LC_FATAL, fmt, args);
|
||||
va_end (args);
|
||||
DDS_FAIL (fmt);
|
||||
}
|
||||
289
src/core/ddsc/src/dds_participant.c
Normal file
289
src/core/ddsc/src/dds_participant.c
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include "ddsi/q_entity.h"
|
||||
#include "ddsi/q_thread.h"
|
||||
#include "ddsi/q_config.h"
|
||||
#include "q__osplser.h"
|
||||
#include "dds__init.h"
|
||||
#include "dds__qos.h"
|
||||
#include "dds__domain.h"
|
||||
#include "dds__participant.h"
|
||||
#include "dds__err.h"
|
||||
#include "dds__report.h"
|
||||
|
||||
#define DDS_PARTICIPANT_STATUS_MASK 0
|
||||
|
||||
/* List of created participants */
|
||||
|
||||
static dds_entity * dds_pp_head = NULL;
|
||||
|
||||
static dds_return_t
|
||||
dds_participant_status_validate(
|
||||
uint32_t mask)
|
||||
{
|
||||
return (mask & ~(DDS_PARTICIPANT_STATUS_MASK)) ?
|
||||
DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument mask is invalid") :
|
||||
DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_participant_delete(
|
||||
dds_entity *e)
|
||||
{
|
||||
struct thread_state1 * const thr = lookup_thread_state ();
|
||||
const bool asleep = !vtime_awake_p (thr->vtime);
|
||||
dds_entity *prev = NULL;
|
||||
dds_entity *iter;
|
||||
|
||||
assert(e);
|
||||
assert(thr);
|
||||
assert(dds_entity_kind(e->m_hdl) == DDS_KIND_PARTICIPANT);
|
||||
|
||||
if (asleep) {
|
||||
thread_state_awake(thr);
|
||||
}
|
||||
|
||||
dds_domain_free (e->m_domain);
|
||||
|
||||
os_mutexLock (&dds_global.m_mutex);
|
||||
iter = dds_pp_head;
|
||||
while (iter) {
|
||||
if (iter == e) {
|
||||
if (prev) {
|
||||
prev->m_next = iter->m_next;
|
||||
} else {
|
||||
dds_pp_head = iter->m_next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
prev = iter;
|
||||
iter = iter->m_next;
|
||||
}
|
||||
os_mutexUnlock (&dds_global.m_mutex);
|
||||
|
||||
assert (iter);
|
||||
|
||||
if (asleep) {
|
||||
thread_state_asleep(thr);
|
||||
}
|
||||
|
||||
/* Every dds_init needs a dds_fini. */
|
||||
dds_fini();
|
||||
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_participant_instance_hdl(
|
||||
dds_entity *e,
|
||||
dds_instance_handle_t *i)
|
||||
{
|
||||
assert(e);
|
||||
assert(i);
|
||||
*i = (dds_instance_handle_t)participant_instance_id(&e->m_guid);
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_participant_qos_validate(
|
||||
const dds_qos_t *qos,
|
||||
bool enabled)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
assert(qos);
|
||||
|
||||
/* Check consistency. */
|
||||
if ((qos->present & QP_USER_DATA) && !validate_octetseq(&qos->user_data)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "User data QoS policy is inconsistent and caused an error");
|
||||
}
|
||||
if ((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy(&qos->entity_factory)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Prismtech entity factory QoS policy is inconsistent and caused an error");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static dds_return_t
|
||||
dds_participant_qos_set(
|
||||
dds_entity *e,
|
||||
const dds_qos_t *qos,
|
||||
bool enabled)
|
||||
{
|
||||
dds_return_t ret = dds_participant_qos_validate(qos, enabled);
|
||||
if (ret == DDS_RETCODE_OK) {
|
||||
if (enabled) {
|
||||
/* TODO: CHAM-95: DDSI does not support changing QoS policies. */
|
||||
ret = DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, "Changing the participant QoS is not supported.");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Must_inspect_result_ dds_entity_t
|
||||
dds_create_participant(
|
||||
_In_ const dds_domainid_t domain,
|
||||
_In_opt_ const dds_qos_t *qos,
|
||||
_In_opt_ const dds_listener_t *listener)
|
||||
{
|
||||
int q_rc;
|
||||
dds_return_t ret;
|
||||
dds_entity_t e;
|
||||
nn_guid_t guid;
|
||||
dds_participant * pp;
|
||||
nn_plist_t plist;
|
||||
dds_qos_t * new_qos = NULL;
|
||||
struct thread_state1 * thr;
|
||||
bool asleep;
|
||||
|
||||
/* Be sure the DDS lifecycle resources are initialized. */
|
||||
dds__startup();
|
||||
|
||||
/* Make sure DDS instance is initialized. */
|
||||
ret = dds_init();
|
||||
if (ret != DDS_RETCODE_OK) {
|
||||
e = (dds_entity_t)ret;
|
||||
goto fail_dds_init;
|
||||
}
|
||||
|
||||
/* Report stack is only useful after dds (and thus os) init. */
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
/* Check domain id */
|
||||
ret = dds__check_domain (domain);
|
||||
if (ret != DDS_RETCODE_OK) {
|
||||
e = (dds_entity_t)ret;
|
||||
goto fail_domain_check;
|
||||
}
|
||||
|
||||
/* Validate qos */
|
||||
if (qos) {
|
||||
ret = dds_participant_qos_validate (qos, false);
|
||||
if (ret != DDS_RETCODE_OK) {
|
||||
e = (dds_entity_t)ret;
|
||||
goto fail_qos_validation;
|
||||
}
|
||||
new_qos = dds_qos_create ();
|
||||
/* Only returns failure when one of the qos args is NULL, which
|
||||
* is not the case here. */
|
||||
(void)dds_qos_copy(new_qos, qos);
|
||||
} else {
|
||||
/* Use default qos. */
|
||||
new_qos = dds_qos_create ();
|
||||
}
|
||||
|
||||
/* Translate qos */
|
||||
nn_plist_init_empty(&plist);
|
||||
dds_qos_merge (&plist.qos, new_qos);
|
||||
|
||||
thr = lookup_thread_state ();
|
||||
asleep = !vtime_awake_p (thr->vtime);
|
||||
if (asleep) {
|
||||
thread_state_awake (thr);
|
||||
}
|
||||
q_rc = new_participant (&guid, 0, &plist);
|
||||
if (asleep) {
|
||||
thread_state_asleep (thr);
|
||||
}
|
||||
nn_plist_fini (&plist);
|
||||
if (q_rc != 0) {
|
||||
e = DDS_ERRNO(DDS_RETCODE_ERROR, "Internal error");
|
||||
goto fail_new_participant;
|
||||
}
|
||||
|
||||
pp = dds_alloc (sizeof (*pp));
|
||||
e = dds_entity_init (&pp->m_entity, NULL, DDS_KIND_PARTICIPANT, new_qos, listener, DDS_PARTICIPANT_STATUS_MASK);
|
||||
if (e < 0) {
|
||||
goto fail_entity_init;
|
||||
}
|
||||
|
||||
pp->m_entity.m_guid = guid;
|
||||
pp->m_entity.m_domain = dds_domain_create (dds_domain_default());
|
||||
pp->m_entity.m_domainid = dds_domain_default();
|
||||
pp->m_entity.m_deriver.delete = dds_participant_delete;
|
||||
pp->m_entity.m_deriver.set_qos = dds_participant_qos_set;
|
||||
pp->m_entity.m_deriver.get_instance_hdl = dds_participant_instance_hdl;
|
||||
pp->m_entity.m_deriver.validate_status = dds_participant_status_validate;
|
||||
pp->m_builtin_subscriber = 0;
|
||||
|
||||
/* Add participant to extent */
|
||||
os_mutexLock (&dds_global.m_mutex);
|
||||
pp->m_entity.m_next = dds_pp_head;
|
||||
dds_pp_head = &pp->m_entity;
|
||||
os_mutexUnlock (&dds_global.m_mutex);
|
||||
|
||||
DDS_REPORT_FLUSH(false);
|
||||
return e;
|
||||
|
||||
fail_entity_init:
|
||||
dds_free(pp);
|
||||
fail_new_participant:
|
||||
dds_qos_delete(new_qos);
|
||||
fail_qos_validation:
|
||||
fail_domain_check:
|
||||
DDS_REPORT_FLUSH(true);
|
||||
dds_fini();
|
||||
fail_dds_init:
|
||||
return e;
|
||||
}
|
||||
|
||||
_Check_return_ dds_return_t
|
||||
dds_lookup_participant(
|
||||
_In_ dds_domainid_t domain_id,
|
||||
_Out_opt_ dds_entity_t *participants,
|
||||
_In_ size_t size)
|
||||
{
|
||||
dds_return_t ret = 0;
|
||||
|
||||
/* Be sure the DDS lifecycle resources are initialized. */
|
||||
dds__startup();
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if ((participants != NULL) && ((size <= 0) || (size >= INT32_MAX))) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Array is given, but with invalid size");
|
||||
goto err;
|
||||
}
|
||||
if ((participants == NULL) && (size != 0)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Size is given, but no array");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if(participants){
|
||||
participants[0] = 0;
|
||||
}
|
||||
|
||||
os_mutexLock (&dds__init_mutex);
|
||||
|
||||
/* Check if dds is intialized. */
|
||||
if (dds_global.m_init_count > 0) {
|
||||
dds_entity* iter;
|
||||
os_mutexLock (&dds_global.m_mutex);
|
||||
iter = dds_pp_head;
|
||||
while (iter) {
|
||||
if(iter->m_domainid == domain_id) {
|
||||
if((size_t)ret < size) {
|
||||
participants[ret] = iter->m_hdl;
|
||||
}
|
||||
ret++;
|
||||
}
|
||||
iter = iter->m_next;
|
||||
}
|
||||
os_mutexUnlock (&dds_global.m_mutex);
|
||||
}
|
||||
|
||||
os_mutexUnlock (&dds__init_mutex);
|
||||
|
||||
err:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
220
src/core/ddsc/src/dds_publisher.c
Normal file
220
src/core/ddsc/src/dds_publisher.c
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
#include "dds__listener.h"
|
||||
#include "dds__qos.h"
|
||||
#include "dds__err.h"
|
||||
#include "ddsi/q_entity.h"
|
||||
#include "dds__report.h"
|
||||
#include "ddsc/ddsc_project.h"
|
||||
|
||||
#define DDS_PUBLISHER_STATUS_MASK 0
|
||||
|
||||
static dds_return_t
|
||||
dds_publisher_instance_hdl(
|
||||
dds_entity *e,
|
||||
dds_instance_handle_t *i)
|
||||
{
|
||||
assert(e);
|
||||
assert(i);
|
||||
/* TODO: Get/generate proper handle. */
|
||||
return DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, "Getting publisher instance handle is not supported");
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_publisher_qos_validate(
|
||||
_In_ const dds_qos_t *qos,
|
||||
_In_ bool enabled)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
assert(qos);
|
||||
|
||||
/* Check consistency. */
|
||||
if((qos->present & QP_GROUP_DATA) && !validate_octetseq(&qos->group_data)){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Group data policy is inconsistent and caused an error");
|
||||
}
|
||||
if((qos->present & QP_PRESENTATION) && (validate_presentation_qospolicy(&qos->presentation) != 0)){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Presentation policy is inconsistent and caused an error");
|
||||
}
|
||||
if((qos->present & QP_PARTITION) && !validate_stringseq(&qos->partition)){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Partition policy is inconsistent and caused an error");
|
||||
}
|
||||
if((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy(&qos->entity_factory)){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Prismtech entity factory policy is inconsistent and caused an error");
|
||||
}
|
||||
if(ret == DDS_RETCODE_OK && enabled && (qos->present & QP_PRESENTATION)){
|
||||
/* TODO: Improve/check immutable check. */
|
||||
ret = DDS_ERRNO(DDS_RETCODE_IMMUTABLE_POLICY, "Presentation policy is immutable");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_publisher_qos_set(
|
||||
dds_entity *e,
|
||||
const dds_qos_t *qos,
|
||||
bool enabled)
|
||||
{
|
||||
dds_return_t ret = dds_publisher_qos_validate(qos, enabled);
|
||||
if (ret == DDS_RETCODE_OK) {
|
||||
if (enabled) {
|
||||
/* TODO: CHAM-95: DDSI does not support changing QoS policies. */
|
||||
ret = DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, DDSC_PROJECT_NAME" does not support changing QoS policies yet");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static dds_return_t dds_publisher_status_validate (uint32_t mask)
|
||||
{
|
||||
return (mask & ~(DDS_PUBLISHER_STATUS_MASK)) ?
|
||||
DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Invalid status mask") :
|
||||
DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((participant & DDS_ENTITY_KIND_MASK) == DDS_KIND_PARTICIPANT)
|
||||
_Must_inspect_result_ dds_entity_t
|
||||
dds_create_publisher(
|
||||
_In_ dds_entity_t participant,
|
||||
_In_opt_ const dds_qos_t *qos,
|
||||
_In_opt_ const dds_listener_t *listener)
|
||||
{
|
||||
dds_entity * par;
|
||||
dds_publisher * pub;
|
||||
dds_entity_t hdl;
|
||||
dds_qos_t * new_qos = NULL;
|
||||
dds_return_t ret;
|
||||
dds__retcode_t rc;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &par);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
hdl = DDS_ERRNO(rc, "Error occurred on locking participant");
|
||||
goto lock_err;
|
||||
}
|
||||
|
||||
/* Validate qos */
|
||||
if (qos) {
|
||||
ret = dds_publisher_qos_validate(qos, false);
|
||||
if (ret != DDS_RETCODE_OK) {
|
||||
hdl = ret;
|
||||
goto qos_err;
|
||||
}
|
||||
new_qos = dds_qos_create ();
|
||||
/* Only returns failure when one of the qos args is NULL, which
|
||||
* is not the case here. */
|
||||
(void)dds_qos_copy(new_qos, qos);
|
||||
}
|
||||
|
||||
/* Create publisher */
|
||||
pub = dds_alloc (sizeof (*pub));
|
||||
hdl = dds_entity_init (&pub->m_entity, par, DDS_KIND_PUBLISHER, new_qos, listener, DDS_PUBLISHER_STATUS_MASK);
|
||||
pub->m_entity.m_deriver.set_qos = dds_publisher_qos_set;
|
||||
pub->m_entity.m_deriver.get_instance_hdl = dds_publisher_instance_hdl;
|
||||
pub->m_entity.m_deriver.validate_status = dds_publisher_status_validate;
|
||||
|
||||
qos_err:
|
||||
dds_entity_unlock(par);
|
||||
lock_err:
|
||||
DDS_REPORT_FLUSH(hdl <= 0);
|
||||
return hdl;
|
||||
}
|
||||
|
||||
|
||||
_Pre_satisfies_((publisher & DDS_ENTITY_KIND_MASK) == DDS_KIND_PUBLISHER)
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_suspend(
|
||||
_In_ dds_entity_t publisher)
|
||||
{
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if(dds_entity_kind(publisher) != DDS_KIND_PUBLISHER) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Provided entity is not a publisher kind");
|
||||
goto err;
|
||||
}
|
||||
/* TODO: CHAM-123 Currently unsupported. */
|
||||
ret = DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, "Suspend publication operation does not being supported yet");
|
||||
err:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
_Pre_satisfies_((publisher & DDS_ENTITY_KIND_MASK) == DDS_KIND_PUBLISHER)
|
||||
dds_return_t
|
||||
dds_resume(
|
||||
_In_ dds_entity_t publisher)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if(dds_entity_kind(publisher) != DDS_KIND_PUBLISHER) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER,"Provided entity is not a publisher kind");
|
||||
goto err;
|
||||
}
|
||||
/* TODO: CHAM-123 Currently unsupported. */
|
||||
ret = DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, "Suspend publication operation does not being supported yet");
|
||||
err:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
_Pre_satisfies_(((publisher_or_writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER ) ||\
|
||||
((publisher_or_writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_PUBLISHER) )
|
||||
dds_return_t
|
||||
dds_wait_for_acks(
|
||||
_In_ dds_entity_t publisher_or_writer,
|
||||
_In_ dds_duration_t timeout)
|
||||
{
|
||||
dds_return_t ret;
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
/* TODO: CHAM-125 Currently unsupported. */
|
||||
OS_UNUSED_ARG(timeout);
|
||||
|
||||
switch(dds_entity_kind(publisher_or_writer)) {
|
||||
case DDS_KIND_WRITER:
|
||||
ret = DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, "Wait for acknowledgments on a writer is not being supported yet");
|
||||
break;
|
||||
case DDS_KIND_PUBLISHER:
|
||||
ret = DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, "Wait for acknowledgments on a publisher is not being supported yet");
|
||||
break;
|
||||
default:
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Provided entity is not a publisher nor a writer");
|
||||
break;
|
||||
}
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_publisher_begin_coherent(
|
||||
_In_ dds_entity_t e)
|
||||
{
|
||||
/* TODO: CHAM-124 Currently unsupported. */
|
||||
return DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, "Using coherency to get a coherent data set is not being supported yet");
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_publisher_end_coherent(
|
||||
_In_ dds_entity_t e)
|
||||
{
|
||||
/* TODO: CHAM-124 Currently unsupported. */
|
||||
return DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, "Using coherency to get a coherent data set is not being supported yet");
|
||||
}
|
||||
|
||||
996
src/core/ddsc/src/dds_qos.c
Normal file
996
src/core/ddsc/src/dds_qos.c
Normal file
|
|
@ -0,0 +1,996 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
#include "dds__qos.h"
|
||||
#include "dds__err.h"
|
||||
#include "ddsi/q_config.h"
|
||||
#include "dds__report.h"
|
||||
|
||||
/* TODO: dd_duration_t is converted to nn_ddsi_time_t declared in q_time.h
|
||||
This structure contain seconds and fractions.
|
||||
Revisit on the conversion as default values are { 0x7fffffff, 0xffffffff }
|
||||
*/
|
||||
|
||||
static void
|
||||
dds_qos_data_copy_in(
|
||||
_Inout_ nn_octetseq_t * data,
|
||||
_In_reads_bytes_opt_(sz) const void * __restrict value,
|
||||
_In_ size_t sz)
|
||||
{
|
||||
if (data->value) {
|
||||
dds_free (data->value);
|
||||
data->value = NULL;
|
||||
}
|
||||
data->length = (uint32_t) sz;
|
||||
if (sz && value) {
|
||||
data->value = dds_alloc (sz);
|
||||
memcpy (data->value, value, sz);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dds_qos_data_copy_out(
|
||||
_In_ const nn_octetseq_t * data,
|
||||
_When_(*sz == 0, _At_(*value, _Post_null_))
|
||||
_When_(*sz > 0, _At_(*value, _Post_notnull_))
|
||||
_Outptr_result_bytebuffer_all_maybenull_(*sz) void ** value,
|
||||
_Out_ size_t * sz)
|
||||
{
|
||||
if ((*sz = data->length) != 0) {
|
||||
assert(data->value);
|
||||
*value = dds_alloc(data->length);
|
||||
memcpy(*value, data->value, data->length);
|
||||
} else {
|
||||
*value = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
validate_octetseq(
|
||||
const nn_octetseq_t* seq)
|
||||
{
|
||||
/* default value is NULL with length 0 */
|
||||
return (((seq->length == 0) && (seq->value == NULL)) || (seq->length > 0));
|
||||
}
|
||||
|
||||
bool
|
||||
validate_stringseq(
|
||||
const nn_stringseq_t* seq)
|
||||
{
|
||||
if (seq->n != 0) {
|
||||
unsigned i;
|
||||
for (i = 0; i < seq->n; i++) {
|
||||
if (!seq->strs[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (seq->n == i);
|
||||
} else {
|
||||
return (seq->strs == NULL);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
validate_entityfactory_qospolicy(
|
||||
const nn_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 nn_reliability_qospolicy_t * reliability)
|
||||
{
|
||||
return (
|
||||
(reliability->kind == NN_BEST_EFFORT_RELIABILITY_QOS || reliability->kind == NN_RELIABLE_RELIABILITY_QOS) &&
|
||||
(validate_duration(&reliability->max_blocking_time) == 0)
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
validate_deadline_and_timebased_filter(
|
||||
const nn_duration_t deadline,
|
||||
const nn_duration_t minimum_separation)
|
||||
{
|
||||
return (
|
||||
(validate_duration(&deadline) == 0) &&
|
||||
(validate_duration(&minimum_separation) == 0) &&
|
||||
(nn_from_ddsi_duration(minimum_separation) <= nn_from_ddsi_duration(deadline))
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
dds_qos_validate_common (
|
||||
const dds_qos_t *qos)
|
||||
{
|
||||
return !(
|
||||
((qos->present & QP_DURABILITY) && (validate_durability_qospolicy (&qos->durability) != 0)) ||
|
||||
((qos->present & QP_DEADLINE) && (validate_duration (&qos->deadline.deadline) != 0)) ||
|
||||
((qos->present & QP_LATENCY_BUDGET) && (validate_duration (&qos->latency_budget.duration) != 0)) ||
|
||||
((qos->present & QP_OWNERSHIP) && (validate_ownership_qospolicy (&qos->ownership) != 0)) ||
|
||||
((qos->present & QP_LIVELINESS) && (validate_liveliness_qospolicy (&qos->liveliness) != 0)) ||
|
||||
((qos->present & QP_RELIABILITY) && ! validate_reliability_qospolicy (&qos->reliability)) ||
|
||||
((qos->present & QP_DESTINATION_ORDER) && (validate_destination_order_qospolicy (&qos->destination_order) != 0)) ||
|
||||
((qos->present & QP_HISTORY) && (validate_history_qospolicy (&qos->history) != 0)) ||
|
||||
((qos->present & QP_RESOURCE_LIMITS) && (validate_resource_limits_qospolicy (&qos->resource_limits) != 0))
|
||||
);
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_qos_validate_mutable_common (
|
||||
_In_ const dds_qos_t *qos)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
/* TODO: Check whether immutable QoS are changed should actually incorporate change to current QoS */
|
||||
if (qos->present & QP_DEADLINE) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_IMMUTABLE_POLICY, "Deadline QoS policy caused immutable error");
|
||||
}
|
||||
if (qos->present & QP_OWNERSHIP) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_IMMUTABLE_POLICY, "Ownership QoS policy caused immutable error");
|
||||
}
|
||||
if (qos->present & QP_LIVELINESS) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_IMMUTABLE_POLICY, "Liveliness QoS policy caused immutable error");
|
||||
}
|
||||
if (qos->present & QP_RELIABILITY) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_IMMUTABLE_POLICY, "Reliability QoS policy caused immutable error");
|
||||
}
|
||||
if (qos->present & QP_DESTINATION_ORDER) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_IMMUTABLE_POLICY, "Destination order QoS policy caused immutable error");
|
||||
}
|
||||
if (qos->present & QP_HISTORY) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_IMMUTABLE_POLICY, "History QoS policy caused immutable error");
|
||||
}
|
||||
if (qos->present & QP_RESOURCE_LIMITS) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_IMMUTABLE_POLICY, "Resource limits QoS policy caused immutable error");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
dds_qos_init_defaults (
|
||||
_Inout_ dds_qos_t * __restrict qos)
|
||||
{
|
||||
assert (qos);
|
||||
memset (qos, 0, sizeof (*qos));
|
||||
qos->durability.kind = (nn_durability_kind_t) DDS_DURABILITY_VOLATILE;
|
||||
qos->deadline.deadline = nn_to_ddsi_duration (DDS_INFINITY);
|
||||
qos->durability_service.service_cleanup_delay = nn_to_ddsi_duration (0);
|
||||
qos->durability_service.history.kind = (nn_history_kind_t) 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 = (nn_presentation_access_scope_kind_t) DDS_PRESENTATION_INSTANCE;
|
||||
qos->latency_budget.duration = nn_to_ddsi_duration (0);
|
||||
qos->ownership.kind = (nn_ownership_kind_t) DDS_OWNERSHIP_SHARED;
|
||||
qos->liveliness.kind = (nn_liveliness_kind_t) DDS_LIVELINESS_AUTOMATIC;
|
||||
qos->liveliness.lease_duration = nn_to_ddsi_duration (DDS_INFINITY);
|
||||
qos->time_based_filter.minimum_separation = nn_to_ddsi_duration (0);
|
||||
qos->reliability.kind = (nn_reliability_kind_t) DDS_RELIABILITY_BEST_EFFORT;
|
||||
qos->reliability.max_blocking_time = nn_to_ddsi_duration (DDS_MSECS (100));
|
||||
qos->lifespan.duration = nn_to_ddsi_duration (DDS_INFINITY);
|
||||
qos->destination_order.kind = (nn_destination_order_kind_t) DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP;
|
||||
qos->history.kind = (nn_history_kind_t) 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 = nn_to_ddsi_duration (DDS_INFINITY);
|
||||
qos->reader_data_lifecycle.autopurge_disposed_samples_delay = nn_to_ddsi_duration (DDS_INFINITY);
|
||||
}
|
||||
|
||||
_Ret_notnull_
|
||||
dds_qos_t * dds_qos_create (void)
|
||||
{
|
||||
dds_qos_t *qos = dds_alloc (sizeof (dds_qos_t));
|
||||
dds_qos_init_defaults (qos);
|
||||
return qos;
|
||||
}
|
||||
|
||||
void
|
||||
dds_qos_reset(
|
||||
_Out_ dds_qos_t * __restrict qos)
|
||||
{
|
||||
if (qos) {
|
||||
nn_xqos_fini (qos);
|
||||
dds_qos_init_defaults (qos);
|
||||
} else {
|
||||
DDS_WARNING(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dds_qos_delete(
|
||||
_In_ _Post_invalid_ dds_qos_t * __restrict qos)
|
||||
{
|
||||
if (qos) {
|
||||
dds_qos_reset(qos);
|
||||
dds_free(qos);
|
||||
}
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_qos_copy (
|
||||
_Out_ dds_qos_t * __restrict dst,
|
||||
_In_ const dds_qos_t * __restrict src)
|
||||
{
|
||||
if(!src){
|
||||
return DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument source(src) is NULL");
|
||||
}
|
||||
if(!dst){
|
||||
return DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument destination(dst) is NULL");
|
||||
}
|
||||
nn_xqos_copy (dst, src);
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
void dds_qos_merge (
|
||||
_Inout_ dds_qos_t * __restrict dst,
|
||||
_In_ const dds_qos_t * __restrict src)
|
||||
{
|
||||
if(!src){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument source(src) is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!dst){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument destination(dst) is NULL");
|
||||
return ;
|
||||
}
|
||||
/* Copy qos from source to destination unless already set */
|
||||
nn_xqos_mergein_missing (dst, src);
|
||||
}
|
||||
|
||||
void dds_qset_userdata(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_reads_bytes_opt_(sz) const void * __restrict value,
|
||||
_In_ size_t sz)
|
||||
{
|
||||
if (!qos) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
return ;
|
||||
}
|
||||
dds_qos_data_copy_in(&qos->user_data, value, sz);
|
||||
qos->present |= QP_USER_DATA;
|
||||
}
|
||||
|
||||
void dds_qset_topicdata(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_reads_bytes_opt_(sz) const void * __restrict value,
|
||||
_In_ size_t sz)
|
||||
{
|
||||
if (!qos) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
return ;
|
||||
}
|
||||
dds_qos_data_copy_in (&qos->topic_data, value, sz);
|
||||
qos->present |= QP_TOPIC_DATA;
|
||||
}
|
||||
|
||||
void dds_qset_groupdata(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_reads_bytes_opt_(sz) const void * __restrict value,
|
||||
_In_ size_t sz)
|
||||
{
|
||||
if (!qos) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
return ;
|
||||
}
|
||||
dds_qos_data_copy_in (&qos->group_data, value, sz);
|
||||
qos->present |= QP_GROUP_DATA;
|
||||
}
|
||||
|
||||
void dds_qset_durability
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(DDS_DURABILITY_VOLATILE, DDS_DURABILITY_PERSISTENT) dds_durability_kind_t kind
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->durability.kind = (nn_durability_kind_t) kind;
|
||||
qos->present |= QP_DURABILITY;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_history
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(DDS_HISTORY_KEEP_LAST, DDS_HISTORY_KEEP_ALL) dds_history_kind_t kind,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t depth
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->history.kind = (nn_history_kind_t) kind;
|
||||
qos->history.depth = depth;
|
||||
qos->present |= QP_HISTORY;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_resource_limits
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t max_samples,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t max_instances,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t max_samples_per_instance
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
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;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_presentation
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(DDS_PRESENTATION_INSTANCE, DDS_PRESENTATION_GROUP) dds_presentation_access_scope_kind_t access_scope,
|
||||
_In_ bool coherent_access,
|
||||
_In_ bool ordered_access
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->presentation.access_scope = (nn_presentation_access_scope_kind_t) access_scope;
|
||||
qos->presentation.coherent_access = coherent_access;
|
||||
qos->presentation.ordered_access = ordered_access;
|
||||
qos->present |= QP_PRESENTATION;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_lifespan
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t lifespan
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->lifespan.duration = nn_to_ddsi_duration (lifespan);
|
||||
qos->present |= QP_LIFESPAN;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_deadline
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t deadline
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->deadline.deadline = nn_to_ddsi_duration (deadline);
|
||||
qos->present |= QP_DEADLINE;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_latency_budget
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t duration
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->latency_budget.duration = nn_to_ddsi_duration (duration);
|
||||
qos->present |= QP_LATENCY_BUDGET;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_ownership
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(DDS_OWNERSHIP_SHARED, DDS_OWNERSHIP_EXCLUSIVE) dds_ownership_kind_t kind
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->ownership.kind = (nn_ownership_kind_t) kind;
|
||||
qos->present |= QP_OWNERSHIP;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_ownership_strength
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_ int32_t value
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->ownership_strength.value = value;
|
||||
qos->present |= QP_OWNERSHIP_STRENGTH;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_liveliness
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(DDS_LIVELINESS_AUTOMATIC, DDS_LIVELINESS_MANUAL_BY_TOPIC) dds_liveliness_kind_t kind,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t lease_duration
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->liveliness.kind = (nn_liveliness_kind_t) kind;
|
||||
qos->liveliness.lease_duration = nn_to_ddsi_duration (lease_duration);
|
||||
qos->present |= QP_LIVELINESS;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_time_based_filter
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t minimum_separation
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->time_based_filter.minimum_separation = nn_to_ddsi_duration (minimum_separation);
|
||||
qos->present |= QP_TIME_BASED_FILTER;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_partition
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_ uint32_t n,
|
||||
_In_count_(n) _Deref_pre_z_ const char ** __restrict ps
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
size_t len;
|
||||
|
||||
if(!qos) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos may not be NULL");
|
||||
return ;
|
||||
}
|
||||
if(n && !ps) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument ps is NULL, but n (%u) > 0", n);
|
||||
return ;
|
||||
}
|
||||
|
||||
if (qos->partition.strs != NULL){
|
||||
for (i = 0; i < qos->partition.n; i++) {
|
||||
dds_free(qos->partition.strs[i]);
|
||||
}
|
||||
dds_free(qos->partition.strs);
|
||||
qos->partition.strs = NULL;
|
||||
}
|
||||
|
||||
qos->partition.n = n;
|
||||
if(n){
|
||||
qos->partition.strs = dds_alloc (sizeof (char*) * n);
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
len = strlen (ps[i]) + 1;
|
||||
qos->partition.strs[i] = dds_alloc (len);
|
||||
strncpy (qos->partition.strs[i], ps[i], len);
|
||||
}
|
||||
qos->present |= QP_PARTITION;
|
||||
}
|
||||
|
||||
void dds_qset_reliability
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(DDS_RELIABILITY_BEST_EFFORT, DDS_RELIABILITY_RELIABLE) dds_reliability_kind_t kind,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t max_blocking_time
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->reliability.kind = (nn_reliability_kind_t) kind;
|
||||
qos->reliability.max_blocking_time = nn_to_ddsi_duration (max_blocking_time);
|
||||
qos->present |= QP_RELIABILITY;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_transport_priority
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_ int32_t value
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->transport_priority.value = value;
|
||||
qos->present |= QP_TRANSPORT_PRIORITY;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_destination_order
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP,
|
||||
DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP) dds_destination_order_kind_t kind
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->destination_order.kind = (nn_destination_order_kind_t) kind;
|
||||
qos->present |= QP_DESTINATION_ORDER;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_writer_data_lifecycle
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_ bool autodispose
|
||||
)
|
||||
{
|
||||
if(qos) {
|
||||
qos->writer_data_lifecycle.autodispose_unregistered_instances = autodispose;
|
||||
qos->present |= QP_PRISMTECH_WRITER_DATA_LIFECYCLE;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_reader_data_lifecycle
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t autopurge_nowriter_samples_delay,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t autopurge_disposed_samples_delay
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->reader_data_lifecycle.autopurge_nowriter_samples_delay = \
|
||||
nn_to_ddsi_duration (autopurge_nowriter_samples_delay);
|
||||
qos->reader_data_lifecycle.autopurge_disposed_samples_delay = \
|
||||
nn_to_ddsi_duration (autopurge_disposed_samples_delay);
|
||||
qos->present |= QP_PRISMTECH_READER_DATA_LIFECYCLE;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_durability_service
|
||||
(
|
||||
_Inout_ dds_qos_t * __restrict qos,
|
||||
_In_range_(0, DDS_INFINITY) dds_duration_t service_cleanup_delay,
|
||||
_In_range_(DDS_HISTORY_KEEP_LAST, DDS_HISTORY_KEEP_ALL) dds_history_kind_t history_kind,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t history_depth,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t max_samples,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t max_instances,
|
||||
_In_range_(>=, DDS_LENGTH_UNLIMITED) int32_t max_samples_per_instance
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
qos->durability_service.service_cleanup_delay = nn_to_ddsi_duration (service_cleanup_delay);
|
||||
qos->durability_service.history.kind = (nn_history_kind_t) 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;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qget_userdata
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Outptr_result_bytebuffer_maybenull_(*sz) void ** value,
|
||||
_Out_ size_t * sz
|
||||
)
|
||||
{
|
||||
if(!qos) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!value) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument value is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!sz) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument sz is NULL");
|
||||
return ;
|
||||
}
|
||||
dds_qos_data_copy_out (&qos->user_data, value, sz);
|
||||
}
|
||||
|
||||
void dds_qget_topicdata
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Outptr_result_bytebuffer_maybenull_(*sz) void ** value,
|
||||
_Out_ size_t * sz
|
||||
)
|
||||
{
|
||||
if(!qos) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!value) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument value is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!sz) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument sz is NULL");
|
||||
return ;
|
||||
}
|
||||
dds_qos_data_copy_out (&qos->topic_data, value, sz);
|
||||
}
|
||||
|
||||
void dds_qget_groupdata
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Outptr_result_bytebuffer_maybenull_(*sz) void ** value,
|
||||
_Out_ size_t * sz
|
||||
)
|
||||
{
|
||||
if(!qos) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!value) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument value is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!sz) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument sz is NULL");
|
||||
return ;
|
||||
}
|
||||
dds_qos_data_copy_out (&qos->group_data, value, sz);
|
||||
}
|
||||
|
||||
void dds_qget_durability
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ dds_durability_kind_t *kind
|
||||
)
|
||||
{
|
||||
if(!qos) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!kind) {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument kind is NULL");
|
||||
return ;
|
||||
}
|
||||
*kind = (dds_durability_kind_t) qos->durability.kind;
|
||||
}
|
||||
|
||||
void dds_qget_history
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_opt_ dds_history_kind_t * kind,
|
||||
_Out_opt_ int32_t *depth
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
if (kind) *kind = (dds_history_kind_t) qos->history.kind;
|
||||
if (depth) *depth = qos->history.depth;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qget_resource_limits
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_opt_ int32_t *max_samples,
|
||||
_Out_opt_ int32_t *max_instances,
|
||||
_Out_opt_ int32_t *max_samples_per_instance
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
if (max_samples) *max_samples = qos->resource_limits.max_samples;
|
||||
if (max_instances) *max_instances = qos->resource_limits.max_instances;
|
||||
if (max_samples_per_instance) {
|
||||
*max_samples_per_instance = qos->resource_limits.max_samples_per_instance;
|
||||
}
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qget_presentation
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_opt_ dds_presentation_access_scope_kind_t *access_scope,
|
||||
_Out_opt_ bool *coherent_access,
|
||||
_Out_opt_ bool *ordered_access
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
if (access_scope) *access_scope = (dds_presentation_access_scope_kind_t) qos->presentation.access_scope;
|
||||
if (coherent_access) *coherent_access = qos->presentation.coherent_access;
|
||||
if (ordered_access) *ordered_access = qos->presentation.ordered_access;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qget_lifespan
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ dds_duration_t * lifespan
|
||||
)
|
||||
{
|
||||
if(!qos){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!lifespan){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument lifespan is NULL");
|
||||
return ;
|
||||
}
|
||||
*lifespan = nn_from_ddsi_duration (qos->lifespan.duration);
|
||||
}
|
||||
|
||||
void dds_qget_deadline
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ dds_duration_t * deadline
|
||||
)
|
||||
{
|
||||
if(!qos){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!deadline){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument deadline is NULL");
|
||||
return ;
|
||||
}
|
||||
*deadline = nn_from_ddsi_duration (qos->deadline.deadline);
|
||||
}
|
||||
|
||||
void dds_qget_latency_budget
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ dds_duration_t *duration
|
||||
)
|
||||
{
|
||||
if(!qos){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!duration){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument duration is NULL");
|
||||
return ;
|
||||
}
|
||||
*duration = nn_from_ddsi_duration (qos->latency_budget.duration);
|
||||
}
|
||||
|
||||
void dds_qget_ownership
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ dds_ownership_kind_t *kind
|
||||
)
|
||||
{
|
||||
if(!qos){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!kind){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument kind is NULL");
|
||||
return ;
|
||||
}
|
||||
*kind = (dds_ownership_kind_t) qos->ownership.kind;
|
||||
}
|
||||
|
||||
void dds_qget_ownership_strength
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ int32_t *value
|
||||
)
|
||||
{
|
||||
if(!qos){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!value){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument value is NULL");
|
||||
return ;
|
||||
}
|
||||
*value = qos->ownership_strength.value;
|
||||
}
|
||||
|
||||
void dds_qget_liveliness
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_opt_ dds_liveliness_kind_t *kind,
|
||||
_Out_opt_ dds_duration_t *lease_duration
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
if (kind) *kind = (dds_liveliness_kind_t) qos->liveliness.kind;
|
||||
if (lease_duration) *lease_duration = nn_from_ddsi_duration (qos->liveliness.lease_duration);
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qget_time_based_filter
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ dds_duration_t *minimum_separation
|
||||
)
|
||||
{
|
||||
if(!qos){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!minimum_separation){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument minimum_separation is NULL");
|
||||
return ;
|
||||
}
|
||||
*minimum_separation = nn_from_ddsi_duration (qos->time_based_filter.minimum_separation);
|
||||
}
|
||||
|
||||
void dds_qget_partition
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ uint32_t *n,
|
||||
_Outptr_opt_result_buffer_all_maybenull_(*n) char *** ps
|
||||
)
|
||||
{
|
||||
size_t len;
|
||||
uint32_t i;
|
||||
|
||||
if(!qos){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!n){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument n is NULL");
|
||||
return ;
|
||||
}
|
||||
|
||||
*n = qos->partition.n;
|
||||
if ( ps ) {
|
||||
if ( qos->partition.n != 0 ) {
|
||||
*ps = dds_alloc(sizeof(char*) * qos->partition.n);
|
||||
for ( i = 0; i < qos->partition.n; i++ ) {
|
||||
len = strlen(qos->partition.strs[i]) + 1;
|
||||
(*ps)[i] = dds_alloc(len);
|
||||
strncpy((*ps)[i], qos->partition.strs[i], len);
|
||||
}
|
||||
} else {
|
||||
*ps = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qget_reliability
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_opt_ dds_reliability_kind_t *kind,
|
||||
_Out_opt_ dds_duration_t *max_blocking_time
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
if (kind) *kind = (dds_reliability_kind_t) qos->reliability.kind;
|
||||
if (max_blocking_time) *max_blocking_time = nn_from_ddsi_duration (qos->reliability.max_blocking_time);
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qget_transport_priority
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ int32_t *value
|
||||
)
|
||||
{
|
||||
if(!qos){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!value){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument value is NULL");
|
||||
return ;
|
||||
}
|
||||
*value = qos->transport_priority.value;
|
||||
}
|
||||
|
||||
void dds_qget_destination_order
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ dds_destination_order_kind_t *kind
|
||||
)
|
||||
{
|
||||
if(!qos){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!kind){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument kind is NULL");
|
||||
return ;
|
||||
}
|
||||
*kind = (dds_destination_order_kind_t) qos->destination_order.kind;
|
||||
}
|
||||
|
||||
void dds_qget_writer_data_lifecycle
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_ bool * autodispose
|
||||
)
|
||||
{
|
||||
if(!qos){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
return ;
|
||||
}
|
||||
if(!autodispose){
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument autodispose is NULL");
|
||||
return ;
|
||||
}
|
||||
*autodispose = qos->writer_data_lifecycle.autodispose_unregistered_instances;
|
||||
}
|
||||
|
||||
void dds_qget_reader_data_lifecycle
|
||||
(
|
||||
_In_ const dds_qos_t * __restrict qos,
|
||||
_Out_opt_ dds_duration_t *autopurge_nowriter_samples_delay,
|
||||
_Out_opt_ dds_duration_t *autopurge_disposed_samples_delay
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
if (autopurge_nowriter_samples_delay) {
|
||||
*autopurge_nowriter_samples_delay = \
|
||||
nn_from_ddsi_duration (qos->reader_data_lifecycle.autopurge_nowriter_samples_delay);
|
||||
}
|
||||
if (autopurge_disposed_samples_delay) {
|
||||
*autopurge_disposed_samples_delay = \
|
||||
nn_from_ddsi_duration (qos->reader_data_lifecycle.autopurge_disposed_samples_delay);
|
||||
}
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qget_durability_service
|
||||
(
|
||||
_In_ const dds_qos_t * qos,
|
||||
_Out_opt_ dds_duration_t * service_cleanup_delay,
|
||||
_Out_opt_ dds_history_kind_t * history_kind,
|
||||
_Out_opt_ int32_t * history_depth,
|
||||
_Out_opt_ int32_t * max_samples,
|
||||
_Out_opt_ int32_t * max_instances,
|
||||
_Out_opt_ int32_t * max_samples_per_instance
|
||||
)
|
||||
{
|
||||
if (qos) {
|
||||
if (service_cleanup_delay) *service_cleanup_delay = nn_from_ddsi_duration (qos->durability_service.service_cleanup_delay);
|
||||
if (history_kind) *history_kind = (dds_history_kind_t) qos->durability_service.history.kind;
|
||||
if (history_depth) *history_depth = qos->durability_service.history.depth;
|
||||
if (max_samples) *max_samples = qos->durability_service.resource_limits.max_samples;
|
||||
if (max_instances) *max_instances = qos->durability_service.resource_limits.max_instances;
|
||||
if (max_samples_per_instance) *max_samples_per_instance = qos->durability_service.resource_limits.max_samples_per_instance;
|
||||
} else {
|
||||
DDS_ERROR(DDS_RETCODE_BAD_PARAMETER, "Argument qos is NULL");
|
||||
}
|
||||
}
|
||||
60
src/core/ddsc/src/dds_querycond.c
Normal file
60
src/core/ddsc/src/dds_querycond.c
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include "dds__entity.h"
|
||||
#include "dds__reader.h"
|
||||
#include "dds__topic.h"
|
||||
#include "dds__querycond.h"
|
||||
#include "dds__readcond.h"
|
||||
#include "dds__err.h"
|
||||
#include "ddsi/ddsi_ser.h"
|
||||
#include "dds__report.h"
|
||||
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
DDS_EXPORT dds_entity_t
|
||||
dds_create_querycondition(
|
||||
_In_ dds_entity_t reader,
|
||||
_In_ uint32_t mask,
|
||||
_In_ dds_querycondition_filter_fn filter)
|
||||
{
|
||||
dds_entity_t topic;
|
||||
dds_entity_t hdl;
|
||||
dds__retcode_t rc;
|
||||
dds_reader *r;
|
||||
dds_topic *t;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_reader_lock(reader, &r);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
dds_readcond *cond = dds_create_readcond(r, DDS_KIND_COND_QUERY, mask);
|
||||
assert(cond);
|
||||
hdl = cond->m_entity.m_hdl;
|
||||
cond->m_query.m_filter = filter;
|
||||
topic = r->m_topic->m_entity.m_hdl;
|
||||
dds_reader_unlock(r);
|
||||
rc = dds_topic_lock(topic, &t);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
if (t->m_stopic->filter_sample == NULL) {
|
||||
t->m_stopic->filter_sample = dds_alloc(t->m_descriptor->m_size);
|
||||
}
|
||||
dds_topic_unlock(t);
|
||||
} else {
|
||||
(void)dds_delete(hdl);
|
||||
hdl = DDS_ERRNO(rc, "Error occurred on locking topic");
|
||||
}
|
||||
} else {
|
||||
hdl = DDS_ERRNO(rc, "Error occurred on locking reader");
|
||||
}
|
||||
DDS_REPORT_FLUSH(hdl <= 0);
|
||||
return hdl;
|
||||
}
|
||||
865
src/core/ddsc/src/dds_read.c
Normal file
865
src/core/ddsc/src/dds_read.c
Normal file
|
|
@ -0,0 +1,865 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
#include "dds__entity.h"
|
||||
#include "dds__reader.h"
|
||||
#include "dds__tkmap.h"
|
||||
#include "dds__rhc.h"
|
||||
#include "dds__err.h"
|
||||
#include "ddsi/q_thread.h"
|
||||
#include "ddsi/q_ephash.h"
|
||||
#include "ddsi/q_entity.h"
|
||||
#include "dds__report.h"
|
||||
|
||||
|
||||
static _Check_return_ dds__retcode_t
|
||||
dds_read_lock(
|
||||
_In_ dds_entity_t hdl,
|
||||
_Out_ dds_reader **reader,
|
||||
_Out_ dds_readcond **condition,
|
||||
_In_ bool only_reader)
|
||||
{
|
||||
dds__retcode_t rc = hdl;
|
||||
assert(reader);
|
||||
assert(condition);
|
||||
*reader = NULL;
|
||||
*condition = NULL;
|
||||
|
||||
rc = dds_entity_lock(hdl, DDS_KIND_READER, (dds_entity**)reader);
|
||||
if (rc == DDS_RETCODE_ILLEGAL_OPERATION) {
|
||||
if (!only_reader) {
|
||||
if ((dds_entity_kind(hdl) == DDS_KIND_COND_READ ) || (dds_entity_kind(hdl) == DDS_KIND_COND_QUERY) ){
|
||||
rc = dds_entity_lock(hdl, DDS_KIND_DONTCARE, (dds_entity**)condition);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
dds_entity *parent = ((dds_entity*)*condition)->m_parent;
|
||||
assert(parent);
|
||||
rc = dds_entity_lock(parent->m_hdl, DDS_KIND_READER, (dds_entity**)reader);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
dds_entity_unlock((dds_entity*)*condition);
|
||||
DDS_ERROR(rc, "Failed to lock condition reader.");
|
||||
}
|
||||
} else {
|
||||
DDS_ERROR(rc, "Failed to lock condition.");
|
||||
}
|
||||
} else {
|
||||
DDS_ERROR(rc, "Given entity is not a reader nor a condition.");
|
||||
}
|
||||
} else {
|
||||
DDS_ERROR(rc, "Given entity is not a reader.");
|
||||
}
|
||||
} else if (rc != DDS_RETCODE_OK) {
|
||||
DDS_ERROR(rc, "Failed to lock reader.");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
dds_read_unlock(
|
||||
_In_ dds_reader *reader,
|
||||
_In_ dds_readcond *condition)
|
||||
{
|
||||
assert(reader);
|
||||
dds_entity_unlock((dds_entity*)reader);
|
||||
if (condition) {
|
||||
dds_entity_unlock((dds_entity*)condition);
|
||||
}
|
||||
}
|
||||
/*
|
||||
dds_read_impl: Core read/take function. Usually maxs is size of buf and si
|
||||
into which samples/status are written, when set to zero is special case
|
||||
indicating that size set from number of samples in cache and also that cache
|
||||
has been locked. This is used to support C++ API reading length unlimited
|
||||
which is interpreted as "all relevant samples in cache".
|
||||
*/
|
||||
static dds_return_t
|
||||
dds_read_impl(
|
||||
_In_ bool take,
|
||||
_In_ dds_entity_t reader_or_condition,
|
||||
_Inout_ void **buf,
|
||||
_In_ size_t bufsz,
|
||||
_In_ uint32_t maxs,
|
||||
_Out_ dds_sample_info_t *si,
|
||||
_In_ uint32_t mask,
|
||||
_In_ dds_instance_handle_t hand,
|
||||
_In_ bool lock,
|
||||
_In_ bool only_reader)
|
||||
{
|
||||
uint32_t i;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
dds__retcode_t rc;
|
||||
struct dds_reader * rd;
|
||||
struct dds_readcond * cond;
|
||||
struct thread_state1 * const thr = lookup_thread_state ();
|
||||
const bool asleep = !vtime_awake_p (thr->vtime);
|
||||
|
||||
if (asleep) {
|
||||
thread_state_awake (thr);
|
||||
}
|
||||
if (buf == NULL) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "The provided buffer is NULL");
|
||||
goto fail;
|
||||
}
|
||||
if (si == NULL) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Provided pointer to an array of dds_sample_info_t is NULL");
|
||||
goto fail;
|
||||
}
|
||||
if (maxs == 0) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "The maximum number of samples to read is zero");
|
||||
goto fail;
|
||||
}
|
||||
if (bufsz == 0) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "The size of buffer is zero");
|
||||
goto fail;
|
||||
}
|
||||
if (bufsz < maxs) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "The provided size of buffer is smaller than the maximum number of samples to read");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = dds_read_lock(reader_or_condition, &rd, &cond, only_reader);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking entity");
|
||||
goto fail;
|
||||
}
|
||||
if (hand != DDS_HANDLE_NIL) {
|
||||
if (dds_tkmap_find_by_id(gv.m_tkmap, hand) == NULL) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "Could not find instance");
|
||||
dds_read_unlock(rd, cond);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
/* Allocate samples if not provided (assuming all or none provided) */
|
||||
if (buf[0] == NULL) {
|
||||
char * loan;
|
||||
const size_t sz = rd->m_topic->m_descriptor->m_size;
|
||||
const uint32_t loan_size = (uint32_t) (sz * maxs);
|
||||
/* Allocate, use or reallocate loan cached on reader */
|
||||
if (rd->m_loan_out) {
|
||||
loan = dds_alloc (loan_size);
|
||||
} else {
|
||||
if (rd->m_loan) {
|
||||
if (rd->m_loan_size < loan_size) {
|
||||
rd->m_loan = dds_realloc_zero (rd->m_loan, loan_size);
|
||||
rd->m_loan_size = loan_size;
|
||||
}
|
||||
} else {
|
||||
rd->m_loan = dds_alloc (loan_size);
|
||||
rd->m_loan_size = loan_size;
|
||||
}
|
||||
loan = rd->m_loan;
|
||||
rd->m_loan_out = true;
|
||||
}
|
||||
for (i = 0; i < maxs; i++) {
|
||||
buf[i] = loan;
|
||||
loan += sz;
|
||||
}
|
||||
}
|
||||
if (take) {
|
||||
ret = (dds_return_t)dds_rhc_take(rd->m_rd->rhc, lock, buf, si, maxs, mask, hand, cond);
|
||||
} else {
|
||||
ret = (dds_return_t)dds_rhc_read(rd->m_rd->rhc, lock, buf, si, maxs, mask, hand, cond);
|
||||
}
|
||||
/* read/take resets data available status */
|
||||
dds_entity_status_reset(rd, DDS_DATA_AVAILABLE_STATUS);
|
||||
/* reset DATA_ON_READERS status on subscriber after successful read/take */
|
||||
if (dds_entity_kind(((dds_entity*)rd)->m_parent->m_hdl) == DDS_KIND_SUBSCRIBER) {
|
||||
dds_entity_status_reset(((dds_entity*)rd)->m_parent, DDS_DATA_ON_READERS_STATUS);
|
||||
}
|
||||
dds_read_unlock(rd, cond);
|
||||
|
||||
fail:
|
||||
if (asleep) {
|
||||
thread_state_asleep (thr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_readcdr_impl(
|
||||
_In_ bool take,
|
||||
_In_ dds_entity_t reader_or_condition,
|
||||
_Out_ struct serdata ** buf,
|
||||
_In_ uint32_t maxs,
|
||||
_Out_ dds_sample_info_t * si,
|
||||
_In_ uint32_t mask,
|
||||
_In_ dds_instance_handle_t hand,
|
||||
_In_ bool lock)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
dds__retcode_t rc;
|
||||
struct dds_reader * rd;
|
||||
struct dds_readcond * cond;
|
||||
struct thread_state1 * const thr = lookup_thread_state ();
|
||||
const bool asleep = !vtime_awake_p (thr->vtime);
|
||||
|
||||
assert (take);
|
||||
assert (buf);
|
||||
assert (si);
|
||||
assert (hand == DDS_HANDLE_NIL);
|
||||
assert (maxs > 0);
|
||||
|
||||
if (asleep)
|
||||
{
|
||||
thread_state_awake (thr);
|
||||
}
|
||||
rc = dds_read_lock(reader_or_condition, &rd, &cond, false);
|
||||
if (rc >= DDS_RETCODE_OK) {
|
||||
ret = dds_rhc_takecdr
|
||||
(
|
||||
rd->m_rd->rhc, lock, buf, si, maxs,
|
||||
mask & DDS_ANY_SAMPLE_STATE,
|
||||
mask & DDS_ANY_VIEW_STATE,
|
||||
mask & DDS_ANY_INSTANCE_STATE,
|
||||
hand
|
||||
);
|
||||
|
||||
/* read/take resets data available status */
|
||||
dds_entity_status_reset(rd, DDS_DATA_AVAILABLE_STATUS);
|
||||
|
||||
/* reset DATA_ON_READERS status on subscriber after successful read/take */
|
||||
|
||||
if (dds_entity_kind(((dds_entity*)rd)->m_parent->m_hdl) == DDS_KIND_SUBSCRIBER)
|
||||
{
|
||||
dds_entity_status_reset(((dds_entity*)rd)->m_parent, DDS_DATA_ON_READERS_STATUS);
|
||||
}
|
||||
dds_read_unlock(rd, cond);
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking entity");
|
||||
}
|
||||
|
||||
if (asleep)
|
||||
{
|
||||
thread_state_asleep (thr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_read(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void ** buf,
|
||||
_Out_ dds_sample_info_t * si,
|
||||
_In_ size_t bufsz,
|
||||
_In_ uint32_t maxs)
|
||||
{
|
||||
bool lock = true;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs, so use bufsz instead.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = (uint32_t)bufsz;
|
||||
}
|
||||
ret = dds_read_impl (false, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, DDS_HANDLE_NIL, lock, false);
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_read_wl(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void ** buf,
|
||||
_Out_ dds_sample_info_t * si,
|
||||
_In_ uint32_t maxs)
|
||||
{
|
||||
bool lock = true;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs. Just an arbitrarily number.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = 100;
|
||||
}
|
||||
ret = dds_read_impl (false, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, DDS_HANDLE_NIL, lock, false);
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_read_mask(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void ** buf,
|
||||
_Out_ dds_sample_info_t * si,
|
||||
_In_ size_t bufsz,
|
||||
_In_ uint32_t maxs,
|
||||
_In_ uint32_t mask)
|
||||
{
|
||||
bool lock = true;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs, so use bufsz instead.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = (uint32_t)bufsz;
|
||||
}
|
||||
ret = dds_read_impl (false, rd_or_cnd, buf, bufsz, maxs, si, mask, DDS_HANDLE_NIL, lock, false);
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_read_mask_wl(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void ** buf,
|
||||
_Out_ dds_sample_info_t * si,
|
||||
_In_ uint32_t maxs,
|
||||
_In_ uint32_t mask)
|
||||
{
|
||||
bool lock = true;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs. Just an arbitrarily number.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = 100;
|
||||
}
|
||||
ret = dds_read_impl (false, rd_or_cnd, buf, maxs, maxs, si, mask, DDS_HANDLE_NIL, lock, false);
|
||||
DDS_REPORT_FLUSH(ret < 0 );
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_read_instance(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void **buf,
|
||||
_Out_ dds_sample_info_t *si,
|
||||
_In_ size_t bufsz,
|
||||
_In_ uint32_t maxs,
|
||||
_In_ dds_instance_handle_t handle)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
bool lock = true;
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (handle == DDS_HANDLE_NIL) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "DDS_HANDLE_NIL was provided");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs. Just an arbitrarily number.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = 100;
|
||||
}
|
||||
ret = dds_read_impl(false, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret < 0 );
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_read_instance_wl(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void **buf,
|
||||
_Out_ dds_sample_info_t *si,
|
||||
_In_ uint32_t maxs,
|
||||
_In_ dds_instance_handle_t handle)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
bool lock = true;
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (handle == DDS_HANDLE_NIL) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "DDS_HANDLE_NIL was provided");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs. Just an arbitrarily number.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = 100;
|
||||
}
|
||||
ret = dds_read_impl(false, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_read_instance_mask(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void **buf,
|
||||
_Out_ dds_sample_info_t *si,
|
||||
_In_ size_t bufsz,
|
||||
_In_ uint32_t maxs,
|
||||
_In_ dds_instance_handle_t handle,
|
||||
_In_ uint32_t mask)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
bool lock = true;
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (handle == DDS_HANDLE_NIL) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "DDS_HANDLE_NIL was provided");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs. Just an arbitrarily number.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = 100;
|
||||
}
|
||||
ret = dds_read_impl(false, rd_or_cnd, buf, bufsz, maxs, si, mask, handle, lock, false);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_read_instance_mask_wl(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void **buf,
|
||||
_Out_ dds_sample_info_t *si,
|
||||
_In_ uint32_t maxs,
|
||||
_In_ dds_instance_handle_t handle,
|
||||
_In_ uint32_t mask)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
bool lock = true;
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (handle == DDS_HANDLE_NIL) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "DDS_HANDLE_NIL was provided");
|
||||
goto fail;
|
||||
}
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs. Just an arbitrarily number.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = 100;
|
||||
}
|
||||
ret = dds_read_impl(false, rd_or_cnd, buf, maxs, maxs, si, mask, handle, lock, false);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER )
|
||||
dds_return_t
|
||||
dds_read_next(
|
||||
_In_ dds_entity_t reader,
|
||||
_Inout_ void **buf,
|
||||
_Out_ dds_sample_info_t *si)
|
||||
{
|
||||
uint32_t mask = DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
ret = dds_read_impl (false, reader, buf, 1u, 1u, si, mask, DDS_HANDLE_NIL, true, true);
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER )
|
||||
dds_return_t
|
||||
dds_read_next_wl(
|
||||
_In_ dds_entity_t reader,
|
||||
_Inout_ void **buf,
|
||||
_Out_ dds_sample_info_t *si)
|
||||
{
|
||||
uint32_t mask = DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
ret = dds_read_impl (false, reader, buf, 1u, 1u, si, mask, DDS_HANDLE_NIL, true, true);
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_take(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void ** buf,
|
||||
_Out_ dds_sample_info_t * si,
|
||||
_In_ size_t bufsz,
|
||||
_In_ uint32_t maxs)
|
||||
{
|
||||
bool lock = true;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs, so use bufsz instead.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = (uint32_t)bufsz;
|
||||
}
|
||||
ret = dds_read_impl (true, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, DDS_HANDLE_NIL, lock, false);
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_take_wl(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void ** buf,
|
||||
_Out_ dds_sample_info_t * si,
|
||||
_In_ uint32_t maxs)
|
||||
{
|
||||
bool lock = true;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs. Just an arbitrarily number.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = 100;
|
||||
}
|
||||
ret = dds_read_impl (true, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, DDS_HANDLE_NIL, lock, false);
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_take_mask(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void ** buf,
|
||||
_Out_ dds_sample_info_t * si,
|
||||
_In_ size_t bufsz,
|
||||
_In_ uint32_t maxs,
|
||||
_In_ uint32_t mask)
|
||||
{
|
||||
bool lock = true;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs, so use bufsz instead.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = (uint32_t)bufsz;
|
||||
}
|
||||
ret = dds_read_impl (true, rd_or_cnd, buf, bufsz, maxs, si, mask, DDS_HANDLE_NIL, lock, false);
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_take_mask_wl(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void ** buf,
|
||||
_Out_ dds_sample_info_t * si,
|
||||
_In_ uint32_t maxs,
|
||||
_In_ uint32_t mask)
|
||||
{
|
||||
bool lock = true;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs. Just an arbitrarily number.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = 100;
|
||||
}
|
||||
ret = dds_read_impl (true, rd_or_cnd, buf, maxs, maxs, si, mask, DDS_HANDLE_NIL, lock, false);
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dds_takecdr(
|
||||
dds_entity_t rd_or_cnd,
|
||||
struct serdata **buf,
|
||||
uint32_t maxs,
|
||||
dds_sample_info_t *si,
|
||||
uint32_t mask)
|
||||
{
|
||||
bool lock = true;
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs. Just an arbitrarily number.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = 100;
|
||||
}
|
||||
return dds_readcdr_impl (true, rd_or_cnd, buf, maxs, si, mask, DDS_HANDLE_NIL, lock);
|
||||
}
|
||||
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_take_instance(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void **buf,
|
||||
_Out_ dds_sample_info_t *si,
|
||||
_In_ size_t bufsz,
|
||||
_In_ uint32_t maxs,
|
||||
_In_ dds_instance_handle_t handle)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
bool lock = true;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (handle == DDS_HANDLE_NIL) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "DDS_HANDLE_NIL was provided");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs. Just an arbitrarily number.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = 100;
|
||||
}
|
||||
ret = dds_read_impl(true, rd_or_cnd, buf, bufsz, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_take_instance_wl(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void **buf,
|
||||
_Out_ dds_sample_info_t *si,
|
||||
_In_ uint32_t maxs,
|
||||
_In_ dds_instance_handle_t handle)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
bool lock = true;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (handle == DDS_HANDLE_NIL) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "DDS_HANDLE_NIL was provided");
|
||||
goto fail;
|
||||
}
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs. Just an arbitrarily number.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = 100;
|
||||
}
|
||||
ret = dds_read_impl(true, rd_or_cnd, buf, maxs, maxs, si, NO_STATE_MASK_SET, handle, lock, false);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_take_instance_mask(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void **buf,
|
||||
_Out_ dds_sample_info_t *si,
|
||||
_In_ size_t bufsz,
|
||||
_In_ uint32_t maxs,
|
||||
_In_ dds_instance_handle_t handle,
|
||||
_In_ uint32_t mask)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
bool lock = true;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (handle == DDS_HANDLE_NIL) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "DDS_HANDLE_NIL was provided");
|
||||
goto fail;
|
||||
}
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs. Just an arbitrarily number.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = 100;
|
||||
}
|
||||
ret = dds_read_impl(true, rd_or_cnd, buf, bufsz, maxs, si, mask, handle, lock, false);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
_Pre_satisfies_(((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((rd_or_cnd & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
dds_return_t
|
||||
dds_take_instance_mask_wl(
|
||||
_In_ dds_entity_t rd_or_cnd,
|
||||
_Inout_ void **buf,
|
||||
_Out_ dds_sample_info_t *si,
|
||||
_In_ uint32_t maxs,
|
||||
_In_ dds_instance_handle_t handle,
|
||||
_In_ uint32_t mask)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
bool lock = true;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (handle == DDS_HANDLE_NIL) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "DDS_HANDLE_NIL was provided");
|
||||
goto fail;
|
||||
}
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK) {
|
||||
lock = false;
|
||||
/* Use a more sensible maxs. Just an arbitrarily number.
|
||||
* CHAM-306 will remove this ugly piece of code. */
|
||||
maxs = 100;
|
||||
}
|
||||
ret = dds_read_impl(true, rd_or_cnd, buf, maxs, maxs, si, mask, handle, lock, false);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER )
|
||||
dds_return_t
|
||||
dds_take_next(
|
||||
_In_ dds_entity_t reader,
|
||||
_Inout_ void **buf,
|
||||
_Out_ dds_sample_info_t *si)
|
||||
{
|
||||
uint32_t mask = DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE;
|
||||
dds_return_t ret;
|
||||
DDS_REPORT_STACK();
|
||||
ret = dds_read_impl (true, reader, buf, 1u, 1u, si, mask, DDS_HANDLE_NIL, true, true);
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER )
|
||||
dds_return_t
|
||||
dds_take_next_wl(
|
||||
_In_ dds_entity_t reader,
|
||||
_Inout_ void **buf,
|
||||
_Out_ dds_sample_info_t *si)
|
||||
{
|
||||
uint32_t mask = DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE;
|
||||
dds_return_t ret;
|
||||
DDS_REPORT_STACK();
|
||||
ret = dds_read_impl (true, reader, buf, 1u, 1u, si, mask, DDS_HANDLE_NIL, true, true);
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((reader_or_condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) ||\
|
||||
((reader_or_condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((reader_or_condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY ))
|
||||
_Must_inspect_result_ dds_return_t
|
||||
dds_return_loan(
|
||||
_In_ dds_entity_t reader_or_condition,
|
||||
_Inout_updates_(bufsz) void **buf,
|
||||
_In_ size_t bufsz)
|
||||
{
|
||||
dds__retcode_t rc;
|
||||
const dds_topic_descriptor_t * desc;
|
||||
dds_reader *rd;
|
||||
dds_readcond *cond;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (!buf ) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument buf is NULL");
|
||||
goto fail;
|
||||
}
|
||||
if(*buf == NULL && bufsz > 0){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument buf is NULL");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = dds_read_lock(reader_or_condition, &rd, &cond, false);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking entity");
|
||||
goto fail;
|
||||
}
|
||||
desc = rd->m_topic->m_descriptor;
|
||||
|
||||
/* Only free sample contents if they have been allocated */
|
||||
if (desc->m_flagset & DDS_TOPIC_NO_OPTIMIZE) {
|
||||
size_t i = 0;
|
||||
for (i = 0; i < bufsz; i++) {
|
||||
dds_sample_free(buf[i], desc, DDS_FREE_CONTENTS);
|
||||
}
|
||||
}
|
||||
|
||||
/* If possible return loan buffer to reader */
|
||||
if (rd->m_loan != 0 && (buf[0] == rd->m_loan)) {
|
||||
rd->m_loan_out = false;
|
||||
memset (rd->m_loan, 0, rd->m_loan_size);
|
||||
buf[0] = NULL;
|
||||
}
|
||||
|
||||
dds_read_unlock(rd, cond);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
129
src/core/ddsc/src/dds_readcond.c
Normal file
129
src/core/ddsc/src/dds_readcond.c
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include "dds__reader.h"
|
||||
#include "dds__readcond.h"
|
||||
#include "dds__rhc.h"
|
||||
#include "dds__entity.h"
|
||||
#include "dds__err.h"
|
||||
#include "ddsi/q_ephash.h"
|
||||
#include "ddsi/q_entity.h"
|
||||
#include "ddsi/q_thread.h"
|
||||
#include "dds__report.h"
|
||||
|
||||
static dds_return_t
|
||||
dds_readcond_delete(
|
||||
dds_entity *e)
|
||||
{
|
||||
dds_rhc_remove_readcondition((dds_readcond*)e);
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
_Must_inspect_result_ dds_readcond*
|
||||
dds_create_readcond(
|
||||
_In_ dds_reader *rd,
|
||||
_In_ dds_entity_kind_t kind,
|
||||
_In_ uint32_t mask)
|
||||
{
|
||||
dds_readcond * cond = dds_alloc(sizeof(*cond));
|
||||
assert(kind == DDS_KIND_COND_READ || kind == DDS_KIND_COND_QUERY);
|
||||
cond->m_entity.m_hdl = dds_entity_init(&cond->m_entity, (dds_entity*)rd, kind, NULL, NULL, 0);
|
||||
cond->m_entity.m_deriver.delete = dds_readcond_delete;
|
||||
cond->m_rhc = rd->m_rd->rhc;
|
||||
cond->m_sample_states = mask & DDS_ANY_SAMPLE_STATE;
|
||||
cond->m_view_states = mask & DDS_ANY_VIEW_STATE;
|
||||
cond->m_instance_states = mask & DDS_ANY_INSTANCE_STATE;
|
||||
cond->m_rd_guid = ((dds_entity*)rd)->m_guid;
|
||||
dds_rhc_add_readcondition (cond);
|
||||
return cond;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
_Must_inspect_result_ dds_entity_t
|
||||
dds_create_readcondition(
|
||||
_In_ dds_entity_t reader,
|
||||
_In_ uint32_t mask)
|
||||
{
|
||||
dds_entity_t hdl;
|
||||
dds_reader * rd;
|
||||
dds__retcode_t rc;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_reader_lock(reader, &rd);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
dds_readcond *cond = dds_create_readcond(rd, DDS_KIND_COND_READ, mask);
|
||||
assert(cond);
|
||||
hdl = cond->m_entity.m_hdl;
|
||||
dds_reader_unlock(rd);
|
||||
} else {
|
||||
hdl = DDS_ERRNO(rc, "Error occurred on locking reader");
|
||||
}
|
||||
DDS_REPORT_FLUSH(hdl <= 0);
|
||||
return hdl;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY) )
|
||||
dds_entity_t
|
||||
dds_get_datareader(
|
||||
_In_ dds_entity_t condition)
|
||||
{
|
||||
dds_entity_t hdl;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
if (dds_entity_kind(condition) == DDS_KIND_COND_READ) {
|
||||
hdl = dds_get_parent(condition);
|
||||
} else if (dds_entity_kind(condition) == DDS_KIND_COND_QUERY) {
|
||||
hdl = dds_get_parent(condition);
|
||||
} else {
|
||||
hdl = DDS_ERRNO(dds_valid_hdl(condition, DDS_KIND_COND_READ), "Argument condition is not valid");
|
||||
}
|
||||
DDS_REPORT_FLUSH(hdl <= 0);
|
||||
return hdl;
|
||||
}
|
||||
|
||||
|
||||
_Pre_satisfies_(((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((condition & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY) )
|
||||
_Check_return_ dds_return_t
|
||||
dds_get_mask(
|
||||
_In_ dds_entity_t condition,
|
||||
_Out_ uint32_t *mask)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds_readcond *cond;
|
||||
dds__retcode_t rc;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (mask != NULL) {
|
||||
*mask = 0;
|
||||
if ((dds_entity_kind(condition) == DDS_KIND_COND_READ ) ||
|
||||
(dds_entity_kind(condition) == DDS_KIND_COND_QUERY) ){
|
||||
rc = dds_entity_lock(condition, DDS_KIND_DONTCARE, (dds_entity**)&cond);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
*mask = (cond->m_sample_states | cond->m_view_states | cond->m_instance_states);
|
||||
dds_entity_unlock((dds_entity*)cond);
|
||||
ret = DDS_RETCODE_OK;
|
||||
} else{
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking condition");
|
||||
}
|
||||
} else {
|
||||
ret = DDS_ERRNO(dds_valid_hdl(condition, DDS_KIND_COND_READ), "Argument condition is not valid");
|
||||
}
|
||||
} else {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument mask is NULL");
|
||||
}
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
791
src/core/ddsc/src/dds_reader.c
Normal file
791
src/core/ddsc/src/dds_reader.c
Normal file
|
|
@ -0,0 +1,791 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
#include "ddsc/dds.h"
|
||||
#include "dds__subscriber.h"
|
||||
#include "dds__reader.h"
|
||||
#include "dds__listener.h"
|
||||
#include "dds__qos.h"
|
||||
#include "dds__init.h"
|
||||
#include "dds__rhc.h"
|
||||
#include "dds__err.h"
|
||||
#include "ddsi/q_entity.h"
|
||||
#include "ddsi/q_thread.h"
|
||||
#include "dds__report.h"
|
||||
#include "dds__builtin.h"
|
||||
#include "ddsc/ddsc_project.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "os/os.h"
|
||||
|
||||
|
||||
#define DDS_READER_STATUS_MASK \
|
||||
DDS_SAMPLE_REJECTED_STATUS |\
|
||||
DDS_LIVELINESS_CHANGED_STATUS |\
|
||||
DDS_REQUESTED_DEADLINE_MISSED_STATUS |\
|
||||
DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS |\
|
||||
DDS_DATA_AVAILABLE_STATUS |\
|
||||
DDS_SAMPLE_LOST_STATUS |\
|
||||
DDS_SUBSCRIPTION_MATCHED_STATUS
|
||||
|
||||
static dds_return_t
|
||||
dds_reader_instance_hdl(
|
||||
dds_entity *e,
|
||||
dds_instance_handle_t *i)
|
||||
{
|
||||
assert(e);
|
||||
assert(i);
|
||||
*i = (dds_instance_handle_t)reader_instance_id(&e->m_guid);
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_reader_close(
|
||||
dds_entity *e)
|
||||
{
|
||||
dds__retcode_t rc;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
struct thread_state1 * const thr = lookup_thread_state();
|
||||
const bool asleep = !vtime_awake_p(thr->vtime);
|
||||
|
||||
assert(e);
|
||||
assert(thr);
|
||||
|
||||
if (asleep) {
|
||||
thread_state_awake(thr);
|
||||
}
|
||||
if (delete_reader(&e->m_guid) != 0) {
|
||||
rc = DDS_RETCODE_ERROR;
|
||||
ret = DDS_ERRNO(rc, "Internal error");
|
||||
}
|
||||
if (asleep) {
|
||||
thread_state_asleep(thr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_reader_delete(
|
||||
dds_entity *e)
|
||||
{
|
||||
dds_reader *rd = (dds_reader*)e;
|
||||
dds_return_t ret;
|
||||
assert(e);
|
||||
ret = dds_delete(rd->m_topic->m_entity.m_hdl);
|
||||
if(ret == DDS_RETCODE_OK){
|
||||
ret = dds_delete_impl(e->m_parent->m_hdl, true);
|
||||
if(dds_err_nr(ret) == DDS_RETCODE_ALREADY_DELETED){
|
||||
ret = DDS_RETCODE_OK;
|
||||
}
|
||||
}
|
||||
dds_free(rd->m_loan);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_reader_qos_validate(
|
||||
const dds_qos_t *qos,
|
||||
bool enabled)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
assert(qos);
|
||||
|
||||
/* Check consistency. */
|
||||
if(!dds_qos_validate_common(qos)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Argument Qos is not valid");
|
||||
}
|
||||
if((qos->present & QP_USER_DATA) && !(validate_octetseq (&qos->user_data))) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "User data policy is inconsistent and caused an error");
|
||||
}
|
||||
if((qos->present & QP_PRISMTECH_READER_DATA_LIFECYCLE) && (validate_reader_data_lifecycle (&qos->reader_data_lifecycle) != 0)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Prismtech reader data lifecycle policy is inconsistent and caused an error");
|
||||
}
|
||||
if((qos->present & QP_TIME_BASED_FILTER) && (validate_duration (&qos->time_based_filter.minimum_separation) != 0)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Time based filter policy is inconsistent and caused an error");
|
||||
}
|
||||
if((qos->present & QP_HISTORY) && (qos->present & QP_RESOURCE_LIMITS) && (validate_history_and_resource_limits (&qos->history, &qos->resource_limits) != 0)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "History and resource limits policy is inconsistent and caused an error");
|
||||
}
|
||||
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))) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Time based filter and deadline policy is inconsistent and caused an error");
|
||||
}
|
||||
if(ret == DDS_RETCODE_OK && enabled) {
|
||||
ret = dds_qos_validate_mutable_common(qos);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_reader_qos_set(
|
||||
dds_entity *e,
|
||||
const dds_qos_t *qos,
|
||||
bool enabled)
|
||||
{
|
||||
dds_return_t ret = dds_reader_qos_validate(qos, enabled);
|
||||
if (ret == DDS_RETCODE_OK) {
|
||||
if (enabled) {
|
||||
/* TODO: CHAM-95: DDSI does not support changing QoS policies. */
|
||||
ret = DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, DDSC_PROJECT_NAME" does not support changing QoS policies");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_reader_status_validate(
|
||||
uint32_t mask)
|
||||
{
|
||||
return (mask & ~(DDS_READER_STATUS_MASK)) ?
|
||||
DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Invalid status mask") :
|
||||
DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
void
|
||||
dds_reader_status_cb(
|
||||
void *entity,
|
||||
const status_cb_data_t *data)
|
||||
{
|
||||
dds_reader *rd;
|
||||
dds__retcode_t rc;
|
||||
void *metrics = NULL;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
/* When data is NULL, it means that the DDSI reader is deleted. */
|
||||
if (data == NULL) {
|
||||
/* Release the initial claim that was done during the create. This
|
||||
* will indicate that further API deletion is now possible. */
|
||||
ut_handle_release(((dds_entity*)entity)->m_hdl, ((dds_entity*)entity)->m_hdllink);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dds_reader_lock(((dds_entity*)entity)->m_hdl, &rd) != DDS_RETCODE_OK) {
|
||||
/* There's a deletion or closing going on. */
|
||||
DDS_REPORT_FLUSH(false);
|
||||
return;
|
||||
}
|
||||
assert(rd == entity);
|
||||
|
||||
/* Reset the status for possible Listener call.
|
||||
* When a listener is not called, the status will be set (again). */
|
||||
dds_entity_status_reset(entity, data->status);
|
||||
|
||||
/* Update status metrics. */
|
||||
switch (data->status) {
|
||||
case DDS_REQUESTED_DEADLINE_MISSED_STATUS: {
|
||||
rd->m_requested_deadline_missed_status.total_count++;
|
||||
rd->m_requested_deadline_missed_status.total_count_change++;
|
||||
rd->m_requested_deadline_missed_status.last_instance_handle = data->handle;
|
||||
metrics = (void*)&(rd->m_requested_deadline_missed_status);
|
||||
break;
|
||||
}
|
||||
case DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS: {
|
||||
rd->m_requested_incompatible_qos_status.total_count++;
|
||||
rd->m_requested_incompatible_qos_status.total_count_change++;
|
||||
rd->m_requested_incompatible_qos_status.last_policy_id = data->extra;
|
||||
metrics = (void*)&(rd->m_requested_incompatible_qos_status);
|
||||
break;
|
||||
}
|
||||
case DDS_SAMPLE_LOST_STATUS: {
|
||||
rd->m_sample_lost_status.total_count++;
|
||||
rd->m_sample_lost_status.total_count_change++;
|
||||
metrics = (void*)&(rd->m_sample_lost_status);
|
||||
break;
|
||||
}
|
||||
case DDS_SAMPLE_REJECTED_STATUS: {
|
||||
rd->m_sample_rejected_status.total_count++;
|
||||
rd->m_sample_rejected_status.total_count_change++;
|
||||
rd->m_sample_rejected_status.last_reason = data->extra;
|
||||
rd->m_sample_rejected_status.last_instance_handle = data->handle;
|
||||
metrics = (void*)&(rd->m_sample_rejected_status);
|
||||
break;
|
||||
}
|
||||
case DDS_DATA_AVAILABLE_STATUS: {
|
||||
metrics = NULL;
|
||||
break;
|
||||
}
|
||||
case DDS_LIVELINESS_CHANGED_STATUS: {
|
||||
if (data->add) {
|
||||
rd->m_liveliness_changed_status.alive_count++;
|
||||
rd->m_liveliness_changed_status.alive_count_change++;
|
||||
if (rd->m_liveliness_changed_status.not_alive_count > 0) {
|
||||
rd->m_liveliness_changed_status.not_alive_count--;
|
||||
}
|
||||
} else {
|
||||
rd->m_liveliness_changed_status.alive_count--;
|
||||
rd->m_liveliness_changed_status.not_alive_count++;
|
||||
rd->m_liveliness_changed_status.not_alive_count_change++;
|
||||
}
|
||||
rd->m_liveliness_changed_status.last_publication_handle = data->handle;
|
||||
metrics = (void*)&(rd->m_liveliness_changed_status);
|
||||
break;
|
||||
}
|
||||
case DDS_SUBSCRIPTION_MATCHED_STATUS: {
|
||||
if (data->add) {
|
||||
rd->m_subscription_matched_status.total_count++;
|
||||
rd->m_subscription_matched_status.total_count_change++;
|
||||
rd->m_subscription_matched_status.current_count++;
|
||||
rd->m_subscription_matched_status.current_count_change++;
|
||||
} else {
|
||||
rd->m_subscription_matched_status.current_count--;
|
||||
rd->m_subscription_matched_status.current_count_change--;
|
||||
}
|
||||
rd->m_subscription_matched_status.last_publication_handle = data->handle;
|
||||
metrics = (void*)&(rd->m_subscription_matched_status);
|
||||
break;
|
||||
}
|
||||
default: assert (0);
|
||||
}
|
||||
|
||||
/* The reader needs to be unlocked when propagating the (possible) listener
|
||||
* call because the application should be able to call this reader within
|
||||
* the callback function. */
|
||||
dds_reader_unlock(rd);
|
||||
|
||||
/* DATA_AVAILABLE is handled differently to normal status changes. */
|
||||
if (data->status == DDS_DATA_AVAILABLE_STATUS) {
|
||||
dds_entity *parent = rd->m_entity.m_parent;
|
||||
/* First, try to ship it off to its parent(s) DDS_DATA_ON_READERS_STATUS. */
|
||||
rc = dds_entity_listener_propagation(parent, parent, DDS_DATA_ON_READERS_STATUS, NULL, true);
|
||||
|
||||
if (rc == DDS_RETCODE_NO_DATA) {
|
||||
/* No parent was interested (NO_DATA == NO_CALL).
|
||||
* What about myself with DDS_DATA_AVAILABLE_STATUS? */
|
||||
rc = dds_entity_listener_propagation(entity, entity, DDS_DATA_AVAILABLE_STATUS, NULL, false);
|
||||
}
|
||||
|
||||
if ( rc == DDS_RETCODE_NO_DATA ) {
|
||||
/* Nobody was interested (NO_DATA == NO_CALL). Set the status on the subscriber. */
|
||||
dds_entity_status_set(parent, DDS_DATA_ON_READERS_STATUS);
|
||||
/* Notify possible interested observers of the subscriber. */
|
||||
dds_entity_status_signal(parent);
|
||||
}
|
||||
} else {
|
||||
/* Is anybody interested within the entity hierarchy through listeners? */
|
||||
rc = dds_entity_listener_propagation(entity, entity, data->status, metrics, true);
|
||||
}
|
||||
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
/* Event was eaten by a listener. */
|
||||
if (dds_reader_lock(((dds_entity*)entity)->m_hdl, &rd) == DDS_RETCODE_OK) {
|
||||
assert(rd == entity);
|
||||
|
||||
/* Reset the change counts of the metrics. */
|
||||
switch (data->status) {
|
||||
case DDS_REQUESTED_DEADLINE_MISSED_STATUS: {
|
||||
rd->m_requested_deadline_missed_status.total_count_change = 0;
|
||||
break;
|
||||
}
|
||||
case DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS: {
|
||||
rd->m_requested_incompatible_qos_status.total_count_change = 0;
|
||||
break;
|
||||
}
|
||||
case DDS_SAMPLE_LOST_STATUS: {
|
||||
rd->m_sample_lost_status.total_count_change = 0;
|
||||
break;
|
||||
}
|
||||
case DDS_SAMPLE_REJECTED_STATUS: {
|
||||
rd->m_sample_rejected_status.total_count_change = 0;
|
||||
break;
|
||||
}
|
||||
case DDS_DATA_AVAILABLE_STATUS: {
|
||||
/* Nothing to reset. */;
|
||||
break;
|
||||
}
|
||||
case DDS_LIVELINESS_CHANGED_STATUS: {
|
||||
rd->m_liveliness_changed_status.alive_count_change = 0;
|
||||
rd->m_liveliness_changed_status.not_alive_count_change = 0;
|
||||
break;
|
||||
}
|
||||
case DDS_SUBSCRIPTION_MATCHED_STATUS: {
|
||||
rd->m_subscription_matched_status.total_count_change = 0;
|
||||
rd->m_subscription_matched_status.current_count_change = 0;
|
||||
break;
|
||||
}
|
||||
default: assert (0);
|
||||
}
|
||||
dds_reader_unlock(rd);
|
||||
} else {
|
||||
/* There's a deletion or closing going on. */
|
||||
}
|
||||
} else if (rc == DDS_RETCODE_NO_DATA) {
|
||||
/* Nobody was interested through a listener (NO_DATA == NO_CALL): set the status. */
|
||||
dds_entity_status_set(entity, data->status);
|
||||
/* Notify possible interested observers. */
|
||||
dds_entity_status_signal(entity);
|
||||
rc = DDS_RETCODE_OK;
|
||||
} else if (rc == DDS_RETCODE_ALREADY_DELETED) {
|
||||
/* An entity up the hierarchy is being deleted. */
|
||||
rc = DDS_RETCODE_OK;
|
||||
} else {
|
||||
/* Something went wrong up the hierarchy. */
|
||||
}
|
||||
|
||||
DDS_REPORT_FLUSH(rc != DDS_RETCODE_OK);
|
||||
}
|
||||
|
||||
|
||||
_Pre_satisfies_(((participant_or_subscriber & DDS_ENTITY_KIND_MASK) == DDS_KIND_SUBSCRIBER ) ||\
|
||||
((participant_or_subscriber & DDS_ENTITY_KIND_MASK) == DDS_KIND_PARTICIPANT) )
|
||||
_Pre_satisfies_(((topic & DDS_ENTITY_KIND_MASK) == DDS_KIND_TOPIC ) ||\
|
||||
((topic & DDS_ENTITY_KIND_MASK) == DDS_KIND_INTERNAL) )
|
||||
dds_entity_t
|
||||
dds_create_reader(
|
||||
_In_ dds_entity_t participant_or_subscriber,
|
||||
_In_ dds_entity_t topic,
|
||||
_In_opt_ const dds_qos_t *qos,
|
||||
_In_opt_ const dds_listener_t *listener)
|
||||
{
|
||||
dds_qos_t * rqos;
|
||||
dds__retcode_t rc;
|
||||
dds_entity * sub = NULL;
|
||||
dds_entity_t subscriber;
|
||||
dds_reader * rd;
|
||||
struct rhc * rhc;
|
||||
dds_entity * tp;
|
||||
dds_entity_t reader;
|
||||
dds_entity_t t;
|
||||
struct thread_state1 * const thr = lookup_thread_state ();
|
||||
const bool asleep = !vtime_awake_p (thr->vtime);
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (dds_entity_kind(topic) != DDS_KIND_INTERNAL) {
|
||||
/* Try claiming a participant. If that's not working, then it could be a subscriber. */
|
||||
if (dds_entity_kind(participant_or_subscriber) == DDS_KIND_PARTICIPANT) {
|
||||
subscriber = dds_create_subscriber(participant_or_subscriber, qos, NULL);
|
||||
} else {
|
||||
subscriber = participant_or_subscriber;
|
||||
}
|
||||
t = topic;
|
||||
} else {
|
||||
/* TODO If qos is provided, we need to compare with writer qos to determine compatibility */
|
||||
subscriber = dds__get_builtin_subscriber(participant_or_subscriber);
|
||||
t = dds__get_builtin_topic(subscriber, topic);
|
||||
}
|
||||
|
||||
rc = dds_entity_lock(subscriber, DDS_KIND_SUBSCRIBER, &sub);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
reader = DDS_ERRNO(rc, "Error occurred on locking subscriber");
|
||||
goto err_sub_lock;
|
||||
}
|
||||
|
||||
if ((subscriber != participant_or_subscriber) &&
|
||||
(dds_entity_kind(topic) != DDS_KIND_INTERNAL)) {
|
||||
/* Delete implicit subscriber if reader creation fails */
|
||||
sub->m_flags |= DDS_ENTITY_IMPLICIT;
|
||||
}
|
||||
|
||||
rc = dds_entity_lock(t, DDS_KIND_TOPIC, &tp);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
reader = DDS_ERRNO(rc, "Error occurred on locking topic");
|
||||
goto err_tp_lock;
|
||||
}
|
||||
assert (((dds_topic*)tp)->m_stopic);
|
||||
assert (sub->m_domain == tp->m_domain);
|
||||
|
||||
/* Merge qos from topic and subscriber */
|
||||
rqos = dds_qos_create ();
|
||||
if (qos) {
|
||||
/* Only returns failure when one of the qos args is NULL, which
|
||||
* is not the case here. */
|
||||
(void)dds_qos_copy(rqos, qos);
|
||||
}
|
||||
|
||||
if(sub->m_qos){
|
||||
dds_qos_merge (rqos, sub->m_qos);
|
||||
}
|
||||
|
||||
if (tp->m_qos) {
|
||||
dds_qos_merge (rqos, tp->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);
|
||||
|
||||
ret = dds_reader_qos_validate (rqos, false);
|
||||
if (ret != 0) {
|
||||
dds_qos_delete(rqos);
|
||||
reader = ret;
|
||||
goto err_bad_qos;
|
||||
}
|
||||
|
||||
/* Create reader and associated read cache */
|
||||
rd = dds_alloc (sizeof (*rd));
|
||||
reader = dds_entity_init (&rd->m_entity, sub, DDS_KIND_READER, rqos, listener, DDS_READER_STATUS_MASK);
|
||||
rd->m_sample_rejected_status.last_reason = DDS_NOT_REJECTED;
|
||||
rd->m_topic = (dds_topic*)tp;
|
||||
rhc = dds_rhc_new (rd, ((dds_topic*)tp)->m_stopic);
|
||||
dds_entity_add_ref_nolock (tp);
|
||||
rd->m_entity.m_deriver.close = dds_reader_close;
|
||||
rd->m_entity.m_deriver.delete = dds_reader_delete;
|
||||
rd->m_entity.m_deriver.set_qos = dds_reader_qos_set;
|
||||
rd->m_entity.m_deriver.validate_status = dds_reader_status_validate;
|
||||
rd->m_entity.m_deriver.get_instance_hdl = dds_reader_instance_hdl;
|
||||
|
||||
/* Extra claim of this reader to make sure that the delete waits until DDSI
|
||||
* has deleted its reader as well. This can be known through the callback. */
|
||||
if (ut_handle_claim(rd->m_entity.m_hdl, rd->m_entity.m_hdllink, DDS_KIND_READER, NULL) != UT_HANDLE_OK) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
os_mutexUnlock(&tp->m_mutex);
|
||||
os_mutexUnlock(&sub->m_mutex);
|
||||
|
||||
if (asleep) {
|
||||
thread_state_awake (thr);
|
||||
}
|
||||
rd->m_rd = new_reader(&rd->m_entity.m_guid, NULL, &sub->m_participant->m_guid, ((dds_topic*)tp)->m_stopic,
|
||||
rqos, rhc, dds_reader_status_cb, rd);
|
||||
os_mutexLock(&sub->m_mutex);
|
||||
os_mutexLock(&tp->m_mutex);
|
||||
assert (rd->m_rd);
|
||||
if (asleep) {
|
||||
thread_state_asleep (thr);
|
||||
}
|
||||
|
||||
/* For persistent data register reader with durability */
|
||||
if (dds_global.m_dur_reader && (rd->m_entity.m_qos->durability.kind > NN_TRANSIENT_LOCAL_DURABILITY_QOS)) {
|
||||
(dds_global.m_dur_reader) (rd, rhc);
|
||||
}
|
||||
dds_entity_unlock(tp);
|
||||
dds_entity_unlock(sub);
|
||||
|
||||
if (dds_entity_kind(topic) == DDS_KIND_INTERNAL) {
|
||||
/* If topic is builtin, then the topic entity is local and should
|
||||
* be deleted because the application won't. */
|
||||
dds_delete(t);
|
||||
}
|
||||
|
||||
DDS_REPORT_FLUSH(reader <= 0);
|
||||
return reader;
|
||||
|
||||
err_bad_qos:
|
||||
dds_entity_unlock(tp);
|
||||
err_tp_lock:
|
||||
dds_entity_unlock(sub);
|
||||
if((sub->m_flags & DDS_ENTITY_IMPLICIT) != 0){
|
||||
(void)dds_delete(subscriber);
|
||||
}
|
||||
err_sub_lock:
|
||||
DDS_REPORT_FLUSH(reader <= 0);
|
||||
return reader;
|
||||
}
|
||||
|
||||
void
|
||||
dds_reader_ddsi2direct(
|
||||
dds_entity_t entity,
|
||||
ddsi2direct_directread_cb_t cb,
|
||||
void *cbarg)
|
||||
{
|
||||
dds_reader *dds_rd;
|
||||
|
||||
if (ut_handle_claim(entity, NULL, DDS_KIND_READER, (void**)&dds_rd) == UT_HANDLE_OK)
|
||||
{
|
||||
struct reader *rd = dds_rd->m_rd;
|
||||
nn_guid_t pwrguid;
|
||||
struct proxy_writer *pwr;
|
||||
struct rd_pwr_match *m;
|
||||
memset (&pwrguid, 0, sizeof (pwrguid));
|
||||
os_mutexLock (&rd->e.lock);
|
||||
|
||||
rd->ddsi2direct_cb = cb;
|
||||
rd->ddsi2direct_cbarg = cbarg;
|
||||
while ((m = ut_avlLookupSuccEq (&rd_writers_treedef, &rd->writers, &pwrguid)) != NULL)
|
||||
{
|
||||
/* have to be careful walking the tree -- pretty is different, but
|
||||
I want to check this before I write a lookup_succ function. */
|
||||
struct rd_pwr_match *m_next;
|
||||
nn_guid_t pwrguid_next;
|
||||
pwrguid = m->pwr_guid;
|
||||
if ((m_next = ut_avlFindSucc (&rd_writers_treedef, &rd->writers, m)) != NULL)
|
||||
pwrguid_next = m_next->pwr_guid;
|
||||
else
|
||||
{
|
||||
memset (&pwrguid_next, 0xff, sizeof (pwrguid_next));
|
||||
pwrguid_next.entityid.u = (pwrguid_next.entityid.u & ~0xff) | NN_ENTITYID_KIND_WRITER_NO_KEY;
|
||||
}
|
||||
os_mutexUnlock (&rd->e.lock);
|
||||
if ((pwr = ephash_lookup_proxy_writer_guid (&pwrguid)) != NULL)
|
||||
{
|
||||
os_mutexLock (&pwr->e.lock);
|
||||
pwr->ddsi2direct_cb = cb;
|
||||
pwr->ddsi2direct_cbarg = cbarg;
|
||||
os_mutexUnlock (&pwr->e.lock);
|
||||
}
|
||||
pwrguid = pwrguid_next;
|
||||
os_mutexLock (&rd->e.lock);
|
||||
}
|
||||
os_mutexUnlock (&rd->e.lock);
|
||||
ut_handle_release(entity, ((dds_entity*)rd)->m_hdllink);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dds_reader_lock_samples(
|
||||
dds_entity_t reader)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
dds_reader *rd;
|
||||
|
||||
ret = dds_reader_lock(reader, &rd);
|
||||
if (ret == DDS_RETCODE_OK) {
|
||||
ret = dds_rhc_lock_samples(rd->m_rd->rhc);
|
||||
dds_reader_unlock(rd);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
int
|
||||
dds_reader_wait_for_historical_data(
|
||||
dds_entity_t reader,
|
||||
dds_duration_t max_wait)
|
||||
{
|
||||
int ret;
|
||||
dds_reader *rd;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
assert (reader);
|
||||
|
||||
ret = dds_reader_lock(reader, &rd);
|
||||
if (ret == DDS_RETCODE_OK) {
|
||||
if (((dds_entity*)rd)->m_qos->durability.kind > NN_TRANSIENT_LOCAL_DURABILITY_QOS) {
|
||||
ret = (dds_global.m_dur_wait) (rd, max_wait);
|
||||
} else {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Can not wait for historical data on a reader with volatile durability");
|
||||
}
|
||||
dds_reader_unlock(rd);
|
||||
} else {
|
||||
ret = DDS_ERRNO(ret, "Error occurred on locking reader");
|
||||
}
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER ) || \
|
||||
((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_READ ) || \
|
||||
((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_COND_QUERY) )
|
||||
dds_entity_t
|
||||
dds_get_subscriber(
|
||||
_In_ dds_entity_t entity)
|
||||
{
|
||||
dds_entity_t hdl;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (dds_entity_kind(entity) == DDS_KIND_READER) {
|
||||
hdl = dds_get_parent(entity);
|
||||
} else if (dds_entity_kind(entity) == DDS_KIND_COND_READ || dds_entity_kind(entity) == DDS_KIND_COND_QUERY) {
|
||||
hdl = dds_get_parent(entity);
|
||||
if(hdl > 0){
|
||||
hdl = dds_get_subscriber(hdl);
|
||||
} else {
|
||||
DDS_ERROR(hdl, "Reader of this condition is already deleted");
|
||||
}
|
||||
} else {
|
||||
hdl = DDS_ERRNO(dds_valid_hdl(entity, DDS_KIND_READER), "Provided entity is not a reader nor a condition");
|
||||
}
|
||||
DDS_REPORT_FLUSH(hdl <= 0);
|
||||
return hdl;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
dds_return_t
|
||||
dds_get_subscription_matched_status (
|
||||
_In_ dds_entity_t reader,
|
||||
_Out_opt_ dds_subscription_matched_status_t * status)
|
||||
{
|
||||
dds__retcode_t rc;
|
||||
dds_reader *rd;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_reader_lock(reader, &rd);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking reader");
|
||||
goto fail;
|
||||
}
|
||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
||||
if (status) {
|
||||
*status = rd->m_subscription_matched_status;
|
||||
}
|
||||
if (((dds_entity*)rd)->m_status_enable & DDS_SUBSCRIPTION_MATCHED_STATUS) {
|
||||
rd->m_subscription_matched_status.total_count_change = 0;
|
||||
rd->m_subscription_matched_status.current_count_change = 0;
|
||||
dds_entity_status_reset(rd, DDS_SUBSCRIPTION_MATCHED_STATUS);
|
||||
}
|
||||
dds_reader_unlock(rd);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
dds_return_t
|
||||
dds_get_liveliness_changed_status (
|
||||
_In_ dds_entity_t reader,
|
||||
_Out_opt_ dds_liveliness_changed_status_t * status)
|
||||
{
|
||||
dds__retcode_t rc;
|
||||
dds_reader *rd;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_reader_lock(reader, &rd);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking reader");
|
||||
goto fail;
|
||||
}
|
||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
||||
if (status) {
|
||||
*status = rd->m_liveliness_changed_status;
|
||||
}
|
||||
if (((dds_entity*)rd)->m_status_enable & DDS_LIVELINESS_CHANGED_STATUS) {
|
||||
rd->m_liveliness_changed_status.alive_count_change = 0;
|
||||
rd->m_liveliness_changed_status.not_alive_count_change = 0;
|
||||
dds_entity_status_reset(rd, DDS_LIVELINESS_CHANGED_STATUS);
|
||||
}
|
||||
dds_reader_unlock(rd);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
dds_return_t dds_get_sample_rejected_status (
|
||||
_In_ dds_entity_t reader,
|
||||
_Out_opt_ dds_sample_rejected_status_t * status)
|
||||
{
|
||||
dds__retcode_t rc;
|
||||
dds_reader *rd;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_reader_lock(reader, &rd);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking reader");
|
||||
goto fail;
|
||||
}
|
||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
||||
if (status) {
|
||||
*status = rd->m_sample_rejected_status;
|
||||
}
|
||||
if (((dds_entity*)rd)->m_status_enable & DDS_SAMPLE_REJECTED_STATUS) {
|
||||
rd->m_sample_rejected_status.total_count_change = 0;
|
||||
rd->m_sample_rejected_status.last_reason = DDS_NOT_REJECTED;
|
||||
dds_entity_status_reset(rd, DDS_SAMPLE_REJECTED_STATUS);
|
||||
}
|
||||
dds_reader_unlock(rd);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
dds_return_t dds_get_sample_lost_status (
|
||||
_In_ dds_entity_t reader,
|
||||
_Out_opt_ dds_sample_lost_status_t * status)
|
||||
{
|
||||
dds__retcode_t rc;
|
||||
dds_reader *rd;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_reader_lock(reader, &rd);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking reader");
|
||||
goto fail;
|
||||
}
|
||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
||||
if (status) {
|
||||
*status = rd->m_sample_lost_status;
|
||||
}
|
||||
if (((dds_entity*)rd)->m_status_enable & DDS_SAMPLE_LOST_STATUS) {
|
||||
rd->m_sample_lost_status.total_count_change = 0;
|
||||
dds_entity_status_reset(rd, DDS_SAMPLE_LOST_STATUS);
|
||||
}
|
||||
dds_reader_unlock(rd);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
dds_return_t dds_get_requested_deadline_missed_status (
|
||||
_In_ dds_entity_t reader,
|
||||
_Out_opt_ dds_requested_deadline_missed_status_t * status)
|
||||
{
|
||||
dds__retcode_t rc;
|
||||
dds_reader *rd;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
rc = dds_reader_lock(reader, &rd);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking reader");
|
||||
goto fail;
|
||||
}
|
||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
||||
if (status) {
|
||||
*status = rd->m_requested_deadline_missed_status;
|
||||
}
|
||||
if (((dds_entity*)rd)->m_status_enable & DDS_REQUESTED_DEADLINE_MISSED_STATUS) {
|
||||
rd->m_requested_deadline_missed_status.total_count_change = 0;
|
||||
dds_entity_status_reset(rd, DDS_REQUESTED_DEADLINE_MISSED_STATUS);
|
||||
}
|
||||
dds_reader_unlock(rd);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((reader & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER)
|
||||
dds_return_t dds_get_requested_incompatible_qos_status (
|
||||
_In_ dds_entity_t reader,
|
||||
_Out_opt_ dds_requested_incompatible_qos_status_t * status)
|
||||
{
|
||||
dds__retcode_t rc;
|
||||
dds_reader *rd;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_reader_lock(reader, &rd);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking reader");
|
||||
goto fail;
|
||||
}
|
||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
||||
if (status) {
|
||||
*status = rd->m_requested_incompatible_qos_status;
|
||||
}
|
||||
if (((dds_entity*)rd)->m_status_enable & DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS) {
|
||||
rd->m_requested_incompatible_qos_status.total_count_change = 0;
|
||||
dds_entity_status_reset(rd, DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS);
|
||||
}
|
||||
dds_reader_unlock(rd);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
53
src/core/ddsc/src/dds_report.c
Normal file
53
src/core/ddsc/src/dds_report.c
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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 "ddsc/dds.h"
|
||||
#include "os/os.h"
|
||||
#include "os/os_report.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "dds__report.h"
|
||||
|
||||
void
|
||||
dds_report(
|
||||
os_reportType reportType,
|
||||
const char *function,
|
||||
int32_t line,
|
||||
const char *file,
|
||||
dds_return_t code,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
const char *retcode = NULL;
|
||||
/* os_report truncates messages to <OS_REPORT_BUFLEN> bytes */
|
||||
char buffer[OS_REPORT_BUFLEN];
|
||||
size_t offset = 0;
|
||||
va_list args;
|
||||
|
||||
assert (function != NULL);
|
||||
assert (file != NULL);
|
||||
assert (format != NULL);
|
||||
/* probably never happens, but you can never be to sure */
|
||||
assert (OS_REPORT_BUFLEN > 0);
|
||||
|
||||
retcode = dds_err_str(code*-1);
|
||||
offset = strlen(retcode);
|
||||
assert (offset < OS_REPORT_BUFLEN);
|
||||
(void)memcpy(buffer, retcode, offset);
|
||||
buffer[offset] = ' ';
|
||||
offset++;
|
||||
|
||||
va_start (args, format);
|
||||
(void)os_vsnprintf (buffer + offset, sizeof(buffer) - offset, format, args);
|
||||
va_end (args);
|
||||
os_report (reportType, function, file, line, code, "%s", buffer);
|
||||
}
|
||||
|
||||
2411
src/core/ddsc/src/dds_rhc.c
Normal file
2411
src/core/ddsc/src/dds_rhc.c
Normal file
File diff suppressed because it is too large
Load diff
1670
src/core/ddsc/src/dds_stream.c
Normal file
1670
src/core/ddsc/src/dds_stream.c
Normal file
File diff suppressed because it is too large
Load diff
223
src/core/ddsc/src/dds_subscriber.c
Normal file
223
src/core/ddsc/src/dds_subscriber.c
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* 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 <string.h>
|
||||
#include "dds__listener.h"
|
||||
#include "dds__qos.h"
|
||||
#include "dds__err.h"
|
||||
#include "ddsi/q_entity.h"
|
||||
#include "dds__report.h"
|
||||
#include "ddsc/ddsc_project.h"
|
||||
|
||||
#define DDS_SUBSCRIBER_STATUS_MASK \
|
||||
DDS_DATA_ON_READERS_STATUS
|
||||
|
||||
static dds_return_t
|
||||
dds_subscriber_instance_hdl(
|
||||
dds_entity *e,
|
||||
dds_instance_handle_t *i)
|
||||
{
|
||||
assert(e);
|
||||
assert(i);
|
||||
/* TODO: Get/generate proper handle. */
|
||||
return DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, "Generating subscriber instance handle is not supported");
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds__subscriber_qos_validate(
|
||||
_In_ const dds_qos_t *qos,
|
||||
_In_ bool enabled)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
assert(qos);
|
||||
|
||||
if((qos->present & QP_GROUP_DATA) && !validate_octetseq(&qos->group_data)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Group data policy is inconsistent and caused an error");
|
||||
}
|
||||
if((qos->present & QP_PARTITION) && !validate_stringseq(&qos->partition)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Partition policy is inconsistent and caused an error");
|
||||
}
|
||||
if((qos->present & QP_PRESENTATION) && validate_presentation_qospolicy(&qos->presentation)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Presentation policy is inconsistent and caused an error");
|
||||
}
|
||||
if((qos->present & QP_PRISMTECH_ENTITY_FACTORY) && !validate_entityfactory_qospolicy(&qos->entity_factory)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Prismtech entity factory policy is inconsistent and caused an error");
|
||||
}
|
||||
if(ret == DDS_RETCODE_OK && enabled && (qos->present & QP_PRESENTATION)) {
|
||||
/* TODO: Improve/check immutable check. */
|
||||
ret = DDS_ERRNO(DDS_RETCODE_IMMUTABLE_POLICY, "Presentation QoS policy is immutable");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_subscriber_qos_set(
|
||||
dds_entity *e,
|
||||
const dds_qos_t *qos,
|
||||
bool enabled)
|
||||
{
|
||||
dds_return_t ret = dds__subscriber_qos_validate(qos, enabled);
|
||||
if (ret == DDS_RETCODE_OK) {
|
||||
if (enabled) {
|
||||
/* TODO: CHAM-95: DDSI does not support changing QoS policies. */
|
||||
ret = DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, DDSC_PROJECT_NAME" does not support changing QoS policies yet");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_subscriber_status_validate(
|
||||
uint32_t mask)
|
||||
{
|
||||
return (mask & ~(DDS_SUBSCRIBER_STATUS_MASK)) ?
|
||||
DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Invalid status mask") :
|
||||
DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Set boolean on readers that indicates state of DATA_ON_READERS
|
||||
status on parent subscriber
|
||||
*/
|
||||
static dds_return_t
|
||||
dds_subscriber_status_propagate(
|
||||
dds_entity *sub,
|
||||
uint32_t mask,
|
||||
bool set)
|
||||
{
|
||||
if (mask & DDS_DATA_ON_READERS_STATUS) {
|
||||
dds_entity *iter = sub->m_children;
|
||||
while (iter) {
|
||||
os_mutexLock (&iter->m_mutex);
|
||||
((dds_reader*) iter)->m_data_on_readers = set;
|
||||
os_mutexUnlock (&iter->m_mutex);
|
||||
iter = iter->m_next;
|
||||
}
|
||||
}
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
_Requires_exclusive_lock_held_(participant)
|
||||
_Check_return_ dds_entity_t
|
||||
dds__create_subscriber_l(
|
||||
_Inout_ dds_entity *participant, /* entity-lock must be held */
|
||||
_In_opt_ const dds_qos_t *qos,
|
||||
_In_opt_ const dds_listener_t *listener)
|
||||
{
|
||||
dds_subscriber * sub;
|
||||
dds_entity_t subscriber;
|
||||
dds_return_t ret;
|
||||
dds_qos_t * new_qos;
|
||||
|
||||
/* Validate qos */
|
||||
if (qos) {
|
||||
if ((ret = dds__subscriber_qos_validate(qos, false)) != DDS_RETCODE_OK) {
|
||||
goto err_param;
|
||||
}
|
||||
new_qos = dds_qos_create();
|
||||
/* Only returns failure when one of the qos args is NULL, which
|
||||
* is not the case here. */
|
||||
(void)dds_qos_copy(new_qos, qos);
|
||||
} else {
|
||||
new_qos = NULL;
|
||||
}
|
||||
|
||||
/* Create subscriber */
|
||||
sub = dds_alloc(sizeof(*sub));
|
||||
subscriber = dds_entity_init(&sub->m_entity, participant, DDS_KIND_SUBSCRIBER, new_qos, listener, DDS_SUBSCRIBER_STATUS_MASK);
|
||||
sub->m_entity.m_deriver.set_qos = dds_subscriber_qos_set;
|
||||
sub->m_entity.m_deriver.validate_status = dds_subscriber_status_validate;
|
||||
sub->m_entity.m_deriver.propagate_status = dds_subscriber_status_propagate;
|
||||
sub->m_entity.m_deriver.get_instance_hdl = dds_subscriber_instance_hdl;
|
||||
|
||||
return subscriber;
|
||||
|
||||
/* Error handling */
|
||||
err_param:
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((participant & DDS_ENTITY_KIND_MASK) == DDS_KIND_PARTICIPANT)
|
||||
_Must_inspect_result_ dds_entity_t
|
||||
dds_create_subscriber(
|
||||
_In_ dds_entity_t participant,
|
||||
_In_opt_ const dds_qos_t *qos,
|
||||
_In_opt_ const dds_listener_t *listener)
|
||||
{
|
||||
dds_entity * par;
|
||||
dds_entity_t hdl;
|
||||
dds__retcode_t errnr;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
errnr = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &par);
|
||||
if (errnr != DDS_RETCODE_OK) {
|
||||
hdl = DDS_ERRNO(errnr, "Error occurred on locking participant");
|
||||
return hdl;
|
||||
}
|
||||
|
||||
hdl = dds__create_subscriber_l(par, qos, listener);
|
||||
dds_entity_unlock(par);
|
||||
|
||||
DDS_REPORT_FLUSH(hdl <= 0);
|
||||
return hdl;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((subscriber & DDS_ENTITY_KIND_MASK) == DDS_KIND_SUBSCRIBER)
|
||||
dds_return_t
|
||||
dds_notify_readers(
|
||||
_In_ dds_entity_t subscriber)
|
||||
{
|
||||
dds_entity *iter;
|
||||
dds_entity *sub;
|
||||
dds__retcode_t errnr;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
errnr = dds_entity_lock(subscriber, DDS_KIND_SUBSCRIBER, &sub);
|
||||
if (errnr == DDS_RETCODE_OK) {
|
||||
errnr = DDS_RETCODE_UNSUPPORTED;
|
||||
ret = DDS_ERRNO(errnr, "Unsupported operation");
|
||||
iter = sub->m_children;
|
||||
while (iter) {
|
||||
os_mutexLock(&iter->m_mutex);
|
||||
// TODO: check if reader has data available, call listener
|
||||
os_mutexUnlock(&iter->m_mutex);
|
||||
iter = iter->m_next;
|
||||
}
|
||||
dds_entity_unlock(sub);
|
||||
} else {
|
||||
ret = DDS_ERRNO(errnr, "Error occurred on locking subscriber");
|
||||
}
|
||||
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_subscriber_begin_coherent(
|
||||
_In_ dds_entity_t e)
|
||||
{
|
||||
/* TODO: CHAM-124 Currently unsupported. */
|
||||
return DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, "Using coherency to get a coherent data set is not currently being supported");
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_subscriber_end_coherent(
|
||||
_In_ dds_entity_t e)
|
||||
{
|
||||
/* TODO: CHAM-124 Currently unsupported. */
|
||||
return DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, "Using coherency to get a coherent data set is not currently being supported");
|
||||
}
|
||||
|
||||
41
src/core/ddsc/src/dds_time.c
Normal file
41
src/core/ddsc/src/dds_time.c
Normal 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
|
||||
*/
|
||||
#include "ddsc/dds.h"
|
||||
#include "os/os.h"
|
||||
|
||||
dds_time_t dds_time (void)
|
||||
{
|
||||
os_time time;
|
||||
|
||||
/* Get the current time */
|
||||
time = os_timeGet ();
|
||||
|
||||
/* convert os_time to dds_time_t */
|
||||
dds_time_t dds_time = time.tv_nsec + (time.tv_sec * DDS_NSECS_IN_SEC);
|
||||
|
||||
return dds_time;
|
||||
}
|
||||
|
||||
void dds_sleepfor (dds_duration_t n)
|
||||
{
|
||||
os_time interval = { (os_timeSec) (n / DDS_NSECS_IN_SEC), (uint32_t) (n % DDS_NSECS_IN_SEC) };
|
||||
os_nanoSleep (interval);
|
||||
}
|
||||
|
||||
void dds_sleepuntil (dds_time_t n)
|
||||
{
|
||||
dds_time_t interval = n - dds_time ();
|
||||
if (interval > 0)
|
||||
{
|
||||
dds_sleepfor (interval);
|
||||
}
|
||||
}
|
||||
393
src/core/ddsc/src/dds_tkmap.c
Normal file
393
src/core/ddsc/src/dds_tkmap.c
Normal file
|
|
@ -0,0 +1,393 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
#include "ddsi/q_thread.h"
|
||||
#include "ddsi/q_unused.h"
|
||||
#include "ddsi/q_gc.h"
|
||||
#include "ddsi/q_globals.h"
|
||||
#include "ddsi/q_config.h"
|
||||
#include "ddsi/sysdeps.h"
|
||||
#include "dds__tkmap.h"
|
||||
#include "dds__iid.h"
|
||||
#include "util/ut_hopscotch.h"
|
||||
#include "dds__stream.h"
|
||||
#include "os/os.h"
|
||||
#include "q__osplser.h"
|
||||
|
||||
#define REFC_DELETE 0x80000000
|
||||
#define REFC_MASK 0x0fffffff
|
||||
|
||||
struct tkmap
|
||||
{
|
||||
struct ut_chh * m_hh;
|
||||
os_mutex m_lock;
|
||||
os_cond m_cond;
|
||||
};
|
||||
|
||||
static void gc_buckets_impl (struct gcreq *gcreq)
|
||||
{
|
||||
os_free (gcreq->arg);
|
||||
gcreq_free (gcreq);
|
||||
}
|
||||
|
||||
static void gc_buckets (void *a)
|
||||
{
|
||||
struct gcreq *gcreq = gcreq_new (gv.gcreq_queue, gc_buckets_impl);
|
||||
gcreq->arg = a;
|
||||
gcreq_enqueue (gcreq);
|
||||
}
|
||||
|
||||
static void gc_tkmap_instance_impl (struct gcreq *gcreq)
|
||||
{
|
||||
struct tkmap_instance *tk = gcreq->arg;
|
||||
ddsi_serdata_unref (tk->m_sample);
|
||||
dds_free (tk);
|
||||
gcreq_free (gcreq);
|
||||
}
|
||||
|
||||
static void gc_tkmap_instance (struct tkmap_instance *tk)
|
||||
{
|
||||
struct gcreq *gcreq = gcreq_new (gv.gcreq_queue, gc_tkmap_instance_impl);
|
||||
gcreq->arg = tk;
|
||||
gcreq_enqueue (gcreq);
|
||||
}
|
||||
|
||||
/* Fixed seed and length */
|
||||
|
||||
#define DDS_MH3_LEN 16
|
||||
#define DDS_MH3_SEED 0
|
||||
|
||||
#define DDS_MH3_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
|
||||
|
||||
/* Really
|
||||
http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp,
|
||||
MurmurHash3_x86_32
|
||||
*/
|
||||
|
||||
static uint32_t dds_mh3 (const void * key)
|
||||
{
|
||||
const uint8_t *data = (const uint8_t *) key;
|
||||
const intptr_t nblocks = (intptr_t) (DDS_MH3_LEN / 4);
|
||||
const uint32_t c1 = 0xcc9e2d51;
|
||||
const uint32_t c2 = 0x1b873593;
|
||||
|
||||
uint32_t h1 = DDS_MH3_SEED;
|
||||
|
||||
const uint32_t *blocks = (const uint32_t *) (data + nblocks * 4);
|
||||
register intptr_t i;
|
||||
|
||||
for (i = -nblocks; i; i++)
|
||||
{
|
||||
uint32_t k1 = blocks[i];
|
||||
|
||||
k1 *= c1;
|
||||
k1 = DDS_MH3_ROTL32 (k1, 15);
|
||||
k1 *= c2;
|
||||
|
||||
h1 ^= k1;
|
||||
h1 = DDS_MH3_ROTL32 (h1, 13);
|
||||
h1 = h1 * 5+0xe6546b64;
|
||||
}
|
||||
|
||||
/* finalization */
|
||||
|
||||
h1 ^= DDS_MH3_LEN;
|
||||
h1 ^= h1 >> 16;
|
||||
h1 *= 0x85ebca6b;
|
||||
h1 ^= h1 >> 13;
|
||||
h1 *= 0xc2b2ae35;
|
||||
h1 ^= h1 >> 16;
|
||||
|
||||
return h1;
|
||||
}
|
||||
|
||||
static uint32_t dds_tk_hash (const struct tkmap_instance * inst)
|
||||
{
|
||||
volatile struct serdata * sd = (volatile struct serdata *) inst->m_sample;
|
||||
|
||||
if (! sd->v.hash_valid)
|
||||
{
|
||||
const uint32_t * k = (const uint32_t *) sd->v.keyhash.m_hash;
|
||||
const uint32_t hash0 = sd->v.st->topic ? sd->v.st->topic->hash : 0;
|
||||
sd->v.hash = ((sd->v.keyhash.m_flags & DDS_KEY_IS_HASH) ? dds_mh3 (k) : (*k)) ^ hash0;
|
||||
sd->v.hash_valid = 1;
|
||||
}
|
||||
|
||||
return sd->v.hash;
|
||||
}
|
||||
|
||||
static uint32_t dds_tk_hash_void (const void * inst)
|
||||
{
|
||||
return dds_tk_hash (inst);
|
||||
}
|
||||
|
||||
static int dds_tk_equals (const struct tkmap_instance *a, const struct tkmap_instance *b)
|
||||
{
|
||||
return serdata_cmp (a->m_sample, b->m_sample) == 0;
|
||||
}
|
||||
|
||||
static int dds_tk_equals_void (const void *a, const void *b)
|
||||
{
|
||||
return dds_tk_equals (a, b);
|
||||
}
|
||||
|
||||
struct tkmap * dds_tkmap_new (void)
|
||||
{
|
||||
struct tkmap *tkmap = dds_alloc (sizeof (*tkmap));
|
||||
tkmap->m_hh = ut_chhNew (1, dds_tk_hash_void, dds_tk_equals_void, gc_buckets);
|
||||
os_mutexInit (&tkmap->m_lock);
|
||||
os_condInit (&tkmap->m_cond, &tkmap->m_lock);
|
||||
return tkmap;
|
||||
}
|
||||
|
||||
static void free_tkmap_instance (void *vtk, UNUSED_ARG(void *f_arg))
|
||||
{
|
||||
struct tkmap_instance *tk = vtk;
|
||||
ddsi_serdata_unref (tk->m_sample);
|
||||
os_free (tk);
|
||||
}
|
||||
|
||||
void dds_tkmap_free (_Inout_ _Post_invalid_ struct tkmap * map)
|
||||
{
|
||||
ut_chhEnumUnsafe (map->m_hh, free_tkmap_instance, NULL);
|
||||
ut_chhFree (map->m_hh);
|
||||
os_condDestroy (&map->m_cond);
|
||||
os_mutexDestroy (&map->m_lock);
|
||||
dds_free (map);
|
||||
}
|
||||
|
||||
uint64_t dds_tkmap_lookup (_In_ struct tkmap * map, _In_ const struct serdata * sd)
|
||||
{
|
||||
struct tkmap_instance dummy;
|
||||
struct tkmap_instance * tk;
|
||||
dummy.m_sample = (struct serdata *) sd;
|
||||
tk = ut_chhLookup (map->m_hh, &dummy);
|
||||
return (tk) ? tk->m_iid : DDS_HANDLE_NIL;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t m_iid;
|
||||
void * m_sample;
|
||||
bool m_ret;
|
||||
}
|
||||
tkmap_get_key_arg;
|
||||
|
||||
static void dds_tkmap_get_key_fn (void * vtk, void * varg)
|
||||
{
|
||||
struct tkmap_instance * tk = vtk;
|
||||
tkmap_get_key_arg * arg = (tkmap_get_key_arg*) varg;
|
||||
if (tk->m_iid == arg->m_iid)
|
||||
{
|
||||
deserialize_into (arg->m_sample, tk->m_sample);
|
||||
arg->m_ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
_Check_return_
|
||||
bool dds_tkmap_get_key (_In_ struct tkmap * map, _In_ uint64_t iid, _Out_ void * sample)
|
||||
{
|
||||
tkmap_get_key_arg arg = { iid, sample, false };
|
||||
os_mutexLock (&map->m_lock);
|
||||
ut_chhEnumUnsafe (map->m_hh, dds_tkmap_get_key_fn, &arg);
|
||||
os_mutexUnlock (&map->m_lock);
|
||||
return arg.m_ret;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t m_iid;
|
||||
struct tkmap_instance * m_inst;
|
||||
}
|
||||
tkmap_get_inst_arg;
|
||||
|
||||
static void dds_tkmap_get_inst_fn (void * vtk, void * varg)
|
||||
{
|
||||
struct tkmap_instance * tk = vtk;
|
||||
tkmap_get_inst_arg * arg = (tkmap_get_inst_arg*) varg;
|
||||
if (tk->m_iid == arg->m_iid)
|
||||
{
|
||||
arg->m_inst = tk;
|
||||
}
|
||||
}
|
||||
|
||||
_Check_return_
|
||||
struct tkmap_instance * dds_tkmap_find_by_id (_In_ struct tkmap * map, _In_ uint64_t iid)
|
||||
{
|
||||
tkmap_get_inst_arg arg = { iid, NULL };
|
||||
ut_chhEnumUnsafe (map->m_hh, dds_tkmap_get_inst_fn, &arg);
|
||||
return arg.m_inst;
|
||||
}
|
||||
|
||||
/* Debug keyhash generation for debug and coverage builds */
|
||||
|
||||
#ifdef NDEBUG
|
||||
#if VL_BUILD_LCOV
|
||||
#define DDS_DEBUG_KEYHASH 1
|
||||
#else
|
||||
#define DDS_DEBUG_KEYHASH 0
|
||||
#endif
|
||||
#else
|
||||
#define DDS_DEBUG_KEYHASH 1
|
||||
#endif
|
||||
|
||||
_Check_return_
|
||||
struct tkmap_instance * dds_tkmap_find(
|
||||
_In_opt_ const struct dds_topic * topic,
|
||||
_In_ struct serdata * sd,
|
||||
_In_ const bool rd,
|
||||
_In_ const bool create)
|
||||
{
|
||||
struct tkmap_instance dummy;
|
||||
struct tkmap_instance * tk;
|
||||
struct tkmap * map = gv.m_tkmap;
|
||||
|
||||
dummy.m_sample = sd;
|
||||
|
||||
/* Generate key hash if required and not provided */
|
||||
|
||||
if (topic && topic->m_descriptor->m_nkeys)
|
||||
{
|
||||
if ((sd->v.keyhash.m_flags & DDS_KEY_HASH_SET) == 0)
|
||||
{
|
||||
dds_stream_t is;
|
||||
dds_stream_from_serstate (&is, sd->v.st);
|
||||
dds_stream_read_keyhash (&is, &sd->v.keyhash, topic->m_descriptor, sd->v.st->kind == STK_KEY);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (topic->m_descriptor->m_flagset & DDS_TOPIC_FIXED_KEY)
|
||||
{
|
||||
sd->v.keyhash.m_flags |= DDS_KEY_IS_HASH;
|
||||
}
|
||||
|
||||
#if DDS_DEBUG_KEYHASH
|
||||
|
||||
{
|
||||
dds_stream_t is;
|
||||
dds_key_hash_t kh;
|
||||
|
||||
/* Check that we generate same keyhash as provided */
|
||||
|
||||
memset (&kh, 0, sizeof (kh));
|
||||
dds_stream_from_serstate (&is, sd->v.st);
|
||||
dds_stream_read_keyhash (&is, &kh, topic->m_descriptor, sd->v.st->kind == STK_KEY);
|
||||
assert (memcmp (kh.m_hash, sd->v.keyhash.m_hash, 16) == 0);
|
||||
if (kh.m_key_buff_size)
|
||||
{
|
||||
dds_free (kh.m_key_buff);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
retry:
|
||||
if ((tk = ut_chhLookup(map->m_hh, &dummy)) != NULL)
|
||||
{
|
||||
uint32_t new;
|
||||
new = os_atomic_inc32_nv(&tk->m_refc);
|
||||
if (new & REFC_DELETE)
|
||||
{
|
||||
/* for the unlikely case of spinning 2^31 times across all threads ... */
|
||||
os_atomic_dec32(&tk->m_refc);
|
||||
|
||||
/* simplest action would be to just spin, but that can potentially take a long time;
|
||||
we can block until someone signals some entry is removed from the map if we take
|
||||
some lock & wait for some condition */
|
||||
os_mutexLock(&map->m_lock);
|
||||
while ((tk = ut_chhLookup(map->m_hh, &dummy)) != NULL && (os_atomic_ld32(&tk->m_refc) & REFC_DELETE))
|
||||
os_condWait(&map->m_cond, &map->m_lock);
|
||||
os_mutexUnlock(&map->m_lock);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
else if (create)
|
||||
{
|
||||
if ((tk = dds_alloc (sizeof (*tk))) == NULL)
|
||||
return NULL;
|
||||
|
||||
tk->m_sample = ddsi_serdata_ref (sd);
|
||||
tk->m_map = map;
|
||||
os_atomic_st32 (&tk->m_refc, 1);
|
||||
tk->m_iid = dds_iid_gen ();
|
||||
if (!ut_chhAdd (map->m_hh, tk))
|
||||
{
|
||||
/* Lost a race from another thread, retry */
|
||||
ddsi_serdata_unref (tk->m_sample);
|
||||
dds_free (tk);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
if (tk && rd)
|
||||
{
|
||||
TRACE (("tk=%p iid=%"PRIx64"", &tk, tk->m_iid));
|
||||
}
|
||||
return tk;
|
||||
}
|
||||
|
||||
_Check_return_
|
||||
struct tkmap_instance * dds_tkmap_lookup_instance_ref (_In_ struct serdata * sd)
|
||||
{
|
||||
dds_topic * topic = sd->v.st->topic ? sd->v.st->topic->status_cb_entity : NULL;
|
||||
|
||||
assert (vtime_awake_p (lookup_thread_state ()->vtime));
|
||||
|
||||
#if 0
|
||||
/* Topic might have been deleted -- FIXME: no way the topic may be deleted when there're still users out there */
|
||||
if (topic == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return dds_tkmap_find (topic, sd, true, true);
|
||||
}
|
||||
|
||||
void dds_tkmap_instance_ref (_In_ struct tkmap_instance *tk)
|
||||
{
|
||||
os_atomic_inc32 (&tk->m_refc);
|
||||
}
|
||||
|
||||
void dds_tkmap_instance_unref (_In_ struct tkmap_instance * tk)
|
||||
{
|
||||
uint32_t old, new;
|
||||
assert (vtime_awake_p(lookup_thread_state()->vtime));
|
||||
do {
|
||||
old = os_atomic_ld32(&tk->m_refc);
|
||||
if (old == 1)
|
||||
new = REFC_DELETE;
|
||||
else
|
||||
{
|
||||
assert(!(old & REFC_DELETE));
|
||||
new = old - 1;
|
||||
}
|
||||
} while (!os_atomic_cas32(&tk->m_refc, old, new));
|
||||
if (new == REFC_DELETE)
|
||||
{
|
||||
struct tkmap *map = tk->m_map;
|
||||
|
||||
/* Remove from hash table */
|
||||
(void)ut_chhRemove(map->m_hh, tk);
|
||||
|
||||
/* Signal any threads blocked in their retry loops in lookup */
|
||||
os_mutexLock(&map->m_lock);
|
||||
os_condBroadcast(&map->m_cond);
|
||||
os_mutexUnlock(&map->m_lock);
|
||||
|
||||
/* Schedule freeing of memory until after all those who may have found a pointer have
|
||||
progressed to where they no longer hold that pointer */
|
||||
gc_tkmap_instance(tk);
|
||||
}
|
||||
}
|
||||
631
src/core/ddsc/src/dds_topic.c
Normal file
631
src/core/ddsc/src/dds_topic.c
Normal file
|
|
@ -0,0 +1,631 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "dds__topic.h"
|
||||
#include "dds__listener.h"
|
||||
#include "dds__qos.h"
|
||||
#include "dds__stream.h"
|
||||
#include "dds__init.h"
|
||||
#include "dds__domain.h"
|
||||
#include "dds__err.h"
|
||||
#include "ddsi/q_entity.h"
|
||||
#include "ddsi/q_thread.h"
|
||||
#include "q__osplser.h"
|
||||
#include "ddsi/q_ddsi_discovery.h"
|
||||
#include "os/os_atomics.h"
|
||||
#include "dds__report.h"
|
||||
|
||||
|
||||
#define DDS_TOPIC_STATUS_MASK \
|
||||
DDS_INCONSISTENT_TOPIC_STATUS
|
||||
|
||||
const ut_avlTreedef_t dds_topictree_def = UT_AVL_TREEDEF_INITIALIZER_INDKEY
|
||||
(
|
||||
offsetof (struct sertopic, avlnode),
|
||||
offsetof (struct sertopic, name_typename),
|
||||
(int (*) (const void *, const void *)) strcmp,
|
||||
0
|
||||
);
|
||||
|
||||
/* builtin-topic handles */
|
||||
const dds_entity_t DDS_BUILTIN_TOPIC_DCPSPARTICIPANT = (DDS_KIND_INTERNAL + 1);
|
||||
const dds_entity_t DDS_BUILTIN_TOPIC_CMPARTICIPANT = (DDS_KIND_INTERNAL + 2);
|
||||
const dds_entity_t DDS_BUILTIN_TOPIC_DCPSTYPE = (DDS_KIND_INTERNAL + 3);
|
||||
const dds_entity_t DDS_BUILTIN_TOPIC_DCPSTOPIC = (DDS_KIND_INTERNAL + 4);
|
||||
const dds_entity_t DDS_BUILTIN_TOPIC_DCPSPUBLICATION = (DDS_KIND_INTERNAL + 5);
|
||||
const dds_entity_t DDS_BUILTIN_TOPIC_CMPUBLISHER = (DDS_KIND_INTERNAL + 6);
|
||||
const dds_entity_t DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION = (DDS_KIND_INTERNAL + 7);
|
||||
const dds_entity_t DDS_BUILTIN_TOPIC_CMSUBSCRIBER = (DDS_KIND_INTERNAL + 8);
|
||||
const dds_entity_t DDS_BUILTIN_TOPIC_CMDATAWRITER = (DDS_KIND_INTERNAL + 9);
|
||||
const dds_entity_t DDS_BUILTIN_TOPIC_CMDATAREADER = (DDS_KIND_INTERNAL + 10);
|
||||
|
||||
static bool
|
||||
is_valid_name(
|
||||
_In_ const char *name)
|
||||
{
|
||||
bool valid = false;
|
||||
/* DDS Spec:
|
||||
* | TOPICNAME - A topic name is an identifier for a topic, and is defined as any series of characters
|
||||
* | 'a', ..., 'z',
|
||||
* | 'A', ..., 'Z',
|
||||
* | '0', ..., '9',
|
||||
* | '-' but may not start with a digit.
|
||||
* It is considered that '-' is an error in the spec and should say '_'. So, that's what we'll check for.
|
||||
*/
|
||||
assert(name);
|
||||
if ((name[0] != '\0') && (!isdigit((unsigned char)name[0]))) {
|
||||
while (isalnum((unsigned char)*name) || (*name == '_')) {
|
||||
name++;
|
||||
}
|
||||
if (*name == '\0') {
|
||||
valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
static dds_return_t
|
||||
dds_topic_status_validate(
|
||||
uint32_t mask)
|
||||
{
|
||||
return (mask & ~(DDS_TOPIC_STATUS_MASK)) ?
|
||||
DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument mask is invalid") :
|
||||
DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Topic status change callback handler. Supports INCONSISTENT_TOPIC
|
||||
status (only defined status on a topic).
|
||||
*/
|
||||
|
||||
static void
|
||||
dds_topic_status_cb(
|
||||
struct dds_topic *cb_t)
|
||||
{
|
||||
dds_topic *topic;
|
||||
dds__retcode_t rc;
|
||||
void *metrics = NULL;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (dds_topic_lock(((dds_entity*)cb_t)->m_hdl, &topic) != DDS_RETCODE_OK) {
|
||||
/* There's a deletion or closing going on. */
|
||||
DDS_REPORT_FLUSH(false);
|
||||
return;
|
||||
}
|
||||
assert(topic == cb_t);
|
||||
|
||||
/* Reset the status for possible Listener call.
|
||||
* When a listener is not called, the status will be set (again). */
|
||||
|
||||
/* Update status metrics. */
|
||||
topic->m_inconsistent_topic_status.total_count++;
|
||||
topic->m_inconsistent_topic_status.total_count_change++;
|
||||
|
||||
|
||||
/* The topic needs to be unlocked when propagating the (possible) listener
|
||||
* call because the application should be able to call this topic within
|
||||
* the callback function. */
|
||||
dds_topic_unlock(topic);
|
||||
|
||||
/* Is anybody interested within the entity hierarchy through listeners? */
|
||||
rc = dds_entity_listener_propagation((dds_entity*)topic,
|
||||
(dds_entity*)topic,
|
||||
DDS_INCONSISTENT_TOPIC_STATUS,
|
||||
(void*)&(topic->m_inconsistent_topic_status),
|
||||
true);
|
||||
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
/* Event was eaten by a listener. */
|
||||
if (dds_topic_lock(((dds_entity*)cb_t)->m_hdl, &topic) == DDS_RETCODE_OK) {
|
||||
/* Reset the change counts of the metrics. */
|
||||
topic->m_inconsistent_topic_status.total_count_change = 0;
|
||||
dds_topic_unlock(topic);
|
||||
}
|
||||
} else if (rc == DDS_RETCODE_NO_DATA) {
|
||||
/* Nobody was interested through a listener (NO_DATA == NO_CALL): set the status. */
|
||||
dds_entity_status_set((dds_entity*)topic, DDS_INCONSISTENT_TOPIC_STATUS);
|
||||
/* Notify possible interested observers. */
|
||||
dds_entity_status_signal((dds_entity*)topic);
|
||||
rc = DDS_RETCODE_OK;
|
||||
} else if (rc == DDS_RETCODE_ALREADY_DELETED) {
|
||||
/* An entity up the hierarchy is being deleted. */
|
||||
rc = DDS_RETCODE_OK;
|
||||
} else {
|
||||
/* Something went wrong up the hierarchy. */
|
||||
}
|
||||
|
||||
DDS_REPORT_FLUSH(rc != DDS_RETCODE_OK);
|
||||
}
|
||||
|
||||
sertopic_t
|
||||
dds_topic_lookup(
|
||||
dds_domain *domain,
|
||||
const char *name)
|
||||
{
|
||||
sertopic_t st = NULL;
|
||||
ut_avlIter_t iter;
|
||||
|
||||
assert (domain);
|
||||
assert (name);
|
||||
|
||||
os_mutexLock (&dds_global.m_mutex);
|
||||
st = ut_avlIterFirst (&dds_topictree_def, &domain->m_topics, &iter);
|
||||
while (st) {
|
||||
if (strcmp (st->name, name) == 0) {
|
||||
break;
|
||||
}
|
||||
st = ut_avlIterNext (&iter);
|
||||
}
|
||||
os_mutexUnlock (&dds_global.m_mutex);
|
||||
return st;
|
||||
}
|
||||
|
||||
void
|
||||
dds_topic_free(
|
||||
dds_domainid_t domainid,
|
||||
struct sertopic *st)
|
||||
{
|
||||
dds_domain *domain;
|
||||
|
||||
assert (st);
|
||||
|
||||
os_mutexLock (&dds_global.m_mutex);
|
||||
domain = (dds_domain*) ut_avlLookup (&dds_domaintree_def, &dds_global.m_domains, &domainid);
|
||||
if (domain != NULL) {
|
||||
ut_avlDelete (&dds_topictree_def, &domain->m_topics, st);
|
||||
}
|
||||
os_mutexUnlock (&dds_global.m_mutex);
|
||||
st->status_cb_entity = NULL;
|
||||
sertopic_free (st);
|
||||
}
|
||||
|
||||
static void
|
||||
dds_topic_add(
|
||||
dds_domainid_t id,
|
||||
sertopic_t st)
|
||||
{
|
||||
dds_domain * dom;
|
||||
os_mutexLock (&dds_global.m_mutex);
|
||||
dom = dds_domain_find_locked (id);
|
||||
assert (dom);
|
||||
ut_avlInsert (&dds_topictree_def, &dom->m_topics, st);
|
||||
os_mutexUnlock (&dds_global.m_mutex);
|
||||
}
|
||||
|
||||
_Pre_satisfies_((participant & DDS_ENTITY_KIND_MASK) == DDS_KIND_PARTICIPANT)
|
||||
DDS_EXPORT dds_entity_t
|
||||
dds_find_topic(
|
||||
_In_ dds_entity_t participant,
|
||||
_In_z_ const char *name)
|
||||
{
|
||||
dds_entity_t tp;
|
||||
dds_entity *p = NULL;
|
||||
sertopic_t st;
|
||||
dds__retcode_t rc;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (name) {
|
||||
rc = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &p);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
st = dds_topic_lookup (p->m_domain, name);
|
||||
if (st) {
|
||||
dds_entity_add_ref (&st->status_cb_entity->m_entity);
|
||||
tp = st->status_cb_entity->m_entity.m_hdl;
|
||||
} else {
|
||||
tp = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "Topic is not being created yet");
|
||||
}
|
||||
dds_entity_unlock(p);
|
||||
} else {
|
||||
tp = DDS_ERRNO(rc, "Error occurred on locking entity");
|
||||
}
|
||||
} else {
|
||||
tp = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument name is not valid");
|
||||
}
|
||||
DDS_REPORT_FLUSH(tp <= 0);
|
||||
return tp;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_topic_delete(
|
||||
dds_entity *e)
|
||||
{
|
||||
dds_topic_free(e->m_domainid, ((dds_topic*) e)->m_stopic);
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_topic_qos_validate(
|
||||
const dds_qos_t *qos,
|
||||
bool enabled)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
assert(qos);
|
||||
|
||||
|
||||
/* Check consistency. */
|
||||
if (!dds_qos_validate_common(qos)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument QoS is not valid");
|
||||
}
|
||||
if ((qos->present & QP_GROUP_DATA) && !validate_octetseq (&qos->group_data)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Group data QoS policy is inconsistent and caused an error");
|
||||
}
|
||||
if ((qos->present & QP_DURABILITY_SERVICE) && (validate_durability_service_qospolicy(&qos->durability_service) != 0)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Durability service QoS policy is inconsistent and caused an error");
|
||||
}
|
||||
if ((qos->present & QP_LIFESPAN) && (validate_duration(&qos->lifespan.duration) != 0)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Lifespan QoS policy is inconsistent and caused an error");
|
||||
}
|
||||
if (qos->present & QP_HISTORY && (qos->present & QP_RESOURCE_LIMITS) && (validate_history_and_resource_limits(&qos->history, &qos->resource_limits) != 0)) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Lifespan QoS policy is inconsistent and caused an error");
|
||||
}
|
||||
if(ret == DDS_RETCODE_OK && enabled){
|
||||
ret = dds_qos_validate_mutable_common(qos);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static dds_return_t
|
||||
dds_topic_qos_set(
|
||||
dds_entity *e,
|
||||
const dds_qos_t *qos,
|
||||
bool enabled)
|
||||
{
|
||||
dds_return_t ret = dds_topic_qos_validate(qos, enabled);
|
||||
if (ret == DDS_RETCODE_OK) {
|
||||
if (enabled) {
|
||||
/* TODO: CHAM-95: DDSI does not support changing QoS policies. */
|
||||
ret = DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, "Changing the topic QoS is not supported.");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((participant & DDS_ENTITY_KIND_MASK) == DDS_KIND_PARTICIPANT)
|
||||
DDS_EXPORT dds_entity_t
|
||||
dds_create_topic(
|
||||
_In_ dds_entity_t participant,
|
||||
_In_ const dds_topic_descriptor_t *desc,
|
||||
_In_z_ const char *name,
|
||||
_In_opt_ const dds_qos_t *qos,
|
||||
_In_opt_ const dds_listener_t *listener)
|
||||
{
|
||||
static uint32_t next_topicid = 0;
|
||||
|
||||
char *key = NULL;
|
||||
sertopic_t st;
|
||||
const char *typename;
|
||||
dds__retcode_t rc;
|
||||
dds_entity *par;
|
||||
dds_topic *top;
|
||||
dds_qos_t *new_qos = NULL;
|
||||
nn_plist_t plist;
|
||||
dds_entity_t hdl;
|
||||
struct participant *ddsi_pp;
|
||||
struct thread_state1 *const thr = lookup_thread_state ();
|
||||
const bool asleep = !vtime_awake_p (thr->vtime);
|
||||
uint32_t index;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (desc == NULL){
|
||||
hdl = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Topic description is NULL");
|
||||
goto bad_param_err;
|
||||
}
|
||||
|
||||
if (name == NULL) {
|
||||
hdl = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Topic name is NULL");
|
||||
goto bad_param_err;
|
||||
}
|
||||
|
||||
if (!is_valid_name(name)) {
|
||||
hdl = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Topic name contains characters that are not allowed.");
|
||||
goto bad_param_err;
|
||||
}
|
||||
|
||||
rc = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &par);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
hdl = DDS_ERRNO(rc, "Error occurred on locking entity");
|
||||
goto lock_err;
|
||||
}
|
||||
|
||||
/* Validate qos */
|
||||
if (qos) {
|
||||
hdl = dds_topic_qos_validate (qos, false);
|
||||
if (hdl != DDS_RETCODE_OK) {
|
||||
goto qos_err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if topic already exists with same name */
|
||||
if (dds_topic_lookup (par->m_domain, name)) {
|
||||
hdl = DDS_ERRNO(DDS_RETCODE_PRECONDITION_NOT_MET, "Precondition not met");
|
||||
goto qos_err;
|
||||
}
|
||||
|
||||
typename = desc->m_typename;
|
||||
key = (char*) dds_alloc (strlen (name) + strlen (typename) + 2);
|
||||
strcpy (key, name);
|
||||
strcat (key, "/");
|
||||
strcat (key, typename);
|
||||
|
||||
if (qos) {
|
||||
new_qos = dds_qos_create();
|
||||
/* Only returns failure when one of the qos args is NULL, which
|
||||
* is not the case here. */
|
||||
(void)dds_qos_copy(new_qos, qos);
|
||||
}
|
||||
|
||||
/* Create topic */
|
||||
top = dds_alloc (sizeof (*top));
|
||||
top->m_descriptor = desc;
|
||||
hdl = dds_entity_init (&top->m_entity, par, DDS_KIND_TOPIC, new_qos, listener, DDS_TOPIC_STATUS_MASK);
|
||||
top->m_entity.m_deriver.delete = dds_topic_delete;
|
||||
top->m_entity.m_deriver.set_qos = dds_topic_qos_set;
|
||||
top->m_entity.m_deriver.validate_status = dds_topic_status_validate;
|
||||
|
||||
st = dds_alloc (sizeof (*st));
|
||||
st->type = (void*) desc;
|
||||
os_atomic_st32 (&st->refcount, 1);
|
||||
st->status_cb = dds_topic_status_cb;
|
||||
st->status_cb_entity = top;
|
||||
st->name_typename = key;
|
||||
st->name = dds_alloc (strlen (name) + 1);
|
||||
strcpy (st->name, name);
|
||||
st->typename = dds_alloc (strlen (typename) + 1);
|
||||
strcpy (st->typename, typename);
|
||||
st->nkeys = desc->m_nkeys;
|
||||
st->keys = desc->m_keys;
|
||||
st->id = next_topicid++;
|
||||
|
||||
#ifdef VXWORKS_RTP
|
||||
st->hash = (st->id * UINT64_C (12844332200329132887UL)) >> 32;
|
||||
#else
|
||||
st->hash = (st->id * UINT64_C (12844332200329132887)) >> 32;
|
||||
#endif
|
||||
|
||||
/* Check if topic cannot be optimised (memcpy marshal) */
|
||||
|
||||
if ((desc->m_flagset & DDS_TOPIC_NO_OPTIMIZE) == 0) {
|
||||
st->opt_size = dds_stream_check_optimize (desc);
|
||||
}
|
||||
top->m_stopic = st;
|
||||
|
||||
/* Add topic to extent */
|
||||
dds_topic_add (par->m_domainid, st);
|
||||
|
||||
nn_plist_init_empty (&plist);
|
||||
if (new_qos) {
|
||||
dds_qos_merge (&plist.qos, new_qos);
|
||||
}
|
||||
|
||||
/* Set Topic meta data (for SEDP publication) */
|
||||
plist.qos.topic_name = dds_string_dup (st->name);
|
||||
plist.qos.type_name = dds_string_dup (st->typename);
|
||||
plist.qos.present |= (QP_TOPIC_NAME | QP_TYPE_NAME);
|
||||
if (desc->m_meta) {
|
||||
plist.type_description = dds_string_dup (desc->m_meta);
|
||||
plist.present |= PP_PRISMTECH_TYPE_DESCRIPTION;
|
||||
}
|
||||
if (desc->m_nkeys) {
|
||||
plist.qos.present |= QP_PRISMTECH_SUBSCRIPTION_KEYS;
|
||||
plist.qos.subscription_keys.use_key_list = 1;
|
||||
plist.qos.subscription_keys.key_list.n = desc->m_nkeys;
|
||||
plist.qos.subscription_keys.key_list.strs = dds_alloc (desc->m_nkeys * sizeof (char*));
|
||||
for (index = 0; index < desc->m_nkeys; index++) {
|
||||
plist.qos.subscription_keys.key_list.strs[index] = dds_string_dup (desc->m_keys[index].m_name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Publish Topic */
|
||||
if (asleep) {
|
||||
thread_state_awake (thr);
|
||||
}
|
||||
ddsi_pp = ephash_lookup_participant_guid (&par->m_guid);
|
||||
assert (ddsi_pp);
|
||||
sedp_write_topic (ddsi_pp, &plist);
|
||||
if (asleep) {
|
||||
thread_state_asleep (thr);
|
||||
}
|
||||
nn_plist_fini (&plist);
|
||||
|
||||
qos_err:
|
||||
dds_entity_unlock(par);
|
||||
lock_err:
|
||||
bad_param_err:
|
||||
DDS_REPORT_FLUSH(hdl <= 0);
|
||||
return hdl;
|
||||
}
|
||||
|
||||
static bool
|
||||
dds_topic_chaining_filter(
|
||||
const void *sample,
|
||||
void *ctx)
|
||||
{
|
||||
dds_topic_filter_fn realf = (dds_topic_filter_fn)ctx;
|
||||
return realf (sample);
|
||||
}
|
||||
|
||||
static void
|
||||
dds_topic_mod_filter(
|
||||
dds_entity_t topic,
|
||||
dds_topic_intern_filter_fn *filter,
|
||||
void **ctx,
|
||||
bool set)
|
||||
{
|
||||
dds_topic *t;
|
||||
if (dds_topic_lock(topic, &t) == DDS_RETCODE_OK) {
|
||||
if (set) {
|
||||
t->m_stopic->filter_fn = *filter;
|
||||
t->m_stopic->filter_ctx = *ctx;
|
||||
|
||||
/* Create sample for read filtering */
|
||||
|
||||
if (t->m_stopic->filter_sample == NULL) {
|
||||
t->m_stopic->filter_sample = dds_alloc (t->m_descriptor->m_size);
|
||||
}
|
||||
} else {
|
||||
*filter = t->m_stopic->filter_fn;
|
||||
*ctx = t->m_stopic->filter_ctx;
|
||||
}
|
||||
dds_topic_unlock(t);
|
||||
}
|
||||
}
|
||||
|
||||
_Pre_satisfies_((topic & DDS_ENTITY_KIND_MASK) == DDS_KIND_TOPIC)
|
||||
void
|
||||
dds_topic_set_filter(
|
||||
dds_entity_t topic,
|
||||
dds_topic_filter_fn filter)
|
||||
{
|
||||
dds_topic_intern_filter_fn chaining = dds_topic_chaining_filter;
|
||||
void *realf = (void *)filter;
|
||||
dds_topic_mod_filter (topic, &chaining, &realf, true);
|
||||
}
|
||||
|
||||
_Pre_satisfies_((topic & DDS_ENTITY_KIND_MASK) == DDS_KIND_TOPIC)
|
||||
dds_topic_filter_fn
|
||||
dds_topic_get_filter(
|
||||
dds_entity_t topic)
|
||||
{
|
||||
dds_topic_intern_filter_fn filter;
|
||||
void *ctx;
|
||||
dds_topic_mod_filter (topic, &filter, &ctx, false);
|
||||
return
|
||||
(filter == dds_topic_chaining_filter) ? (dds_topic_filter_fn)ctx : NULL;
|
||||
}
|
||||
|
||||
void
|
||||
dds_topic_set_filter_with_ctx(
|
||||
dds_entity_t topic,
|
||||
dds_topic_intern_filter_fn filter,
|
||||
void *ctx)
|
||||
{
|
||||
dds_topic_mod_filter (topic, &filter, &ctx, true);
|
||||
}
|
||||
|
||||
dds_topic_intern_filter_fn
|
||||
dds_topic_get_filter_with_ctx(
|
||||
dds_entity_t topic)
|
||||
{
|
||||
dds_topic_intern_filter_fn filter;
|
||||
void *ctx;
|
||||
dds_topic_mod_filter (topic, &filter, &ctx, false);
|
||||
return (filter == dds_topic_chaining_filter) ? NULL : filter;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((topic & DDS_ENTITY_KIND_MASK) == DDS_KIND_TOPIC)
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_get_name(
|
||||
_In_ dds_entity_t topic,
|
||||
_Out_writes_z_(size) char *name,
|
||||
_In_ size_t size)
|
||||
{
|
||||
dds_topic *t;
|
||||
dds_return_t ret;
|
||||
dds__retcode_t rc;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if(size <= 0){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument size is smaller than 0");
|
||||
goto fail;
|
||||
}
|
||||
if(name == NULL){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument name is NULL");
|
||||
goto fail;
|
||||
}
|
||||
name[0] = '\0';
|
||||
rc = dds_topic_lock(topic, &t);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
(void)snprintf(name, size, "%s", t->m_stopic->name);
|
||||
dds_topic_unlock(t);
|
||||
ret = DDS_RETCODE_OK;
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking topic");
|
||||
goto fail;
|
||||
}
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((topic & DDS_ENTITY_KIND_MASK) == DDS_KIND_TOPIC)
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_get_type_name(
|
||||
_In_ dds_entity_t topic,
|
||||
_Out_writes_z_(size) char *name,
|
||||
_In_ size_t size)
|
||||
{
|
||||
dds_topic *t;
|
||||
dds__retcode_t rc;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if(size <= 0){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument size is smaller than 0");
|
||||
goto fail;
|
||||
}
|
||||
if(name == NULL){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument name is NULL");
|
||||
goto fail;
|
||||
}
|
||||
name[0] = '\0';
|
||||
rc = dds_topic_lock(topic, &t);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking topic");
|
||||
goto fail;
|
||||
}
|
||||
(void)snprintf(name, size, "%s", t->m_stopic->typename);
|
||||
dds_topic_unlock(t);
|
||||
ret = DDS_RETCODE_OK;
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
_Pre_satisfies_((topic & DDS_ENTITY_KIND_MASK) == DDS_KIND_TOPIC)
|
||||
dds_return_t
|
||||
dds_get_inconsistent_topic_status(
|
||||
_In_ dds_entity_t topic,
|
||||
_Out_opt_ dds_inconsistent_topic_status_t *status)
|
||||
{
|
||||
dds__retcode_t rc;
|
||||
dds_topic *t;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_topic_lock(topic, &t);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking topic");
|
||||
goto fail;
|
||||
}
|
||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
||||
if (status) {
|
||||
*status = t->m_inconsistent_topic_status;
|
||||
}
|
||||
if (((dds_entity*)t)->m_status_enable & DDS_INCONSISTENT_TOPIC_STATUS) {
|
||||
t->m_inconsistent_topic_status.total_count_change = 0;
|
||||
dds_entity_status_reset(t, DDS_INCONSISTENT_TOPIC_STATUS);
|
||||
}
|
||||
dds_topic_unlock(t);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
512
src/core/ddsc/src/dds_waitset.c
Normal file
512
src/core/ddsc/src/dds_waitset.c
Normal file
|
|
@ -0,0 +1,512 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include "os/os.h"
|
||||
#include "dds__entity.h"
|
||||
#include "dds__querycond.h"
|
||||
#include "dds__readcond.h"
|
||||
#include "dds__rhc.h"
|
||||
#include "dds__err.h"
|
||||
#include "dds__report.h"
|
||||
|
||||
|
||||
#define dds_waitset_lock(hdl, obj) dds_entity_lock(hdl, DDS_KIND_WAITSET, (dds_entity**)obj)
|
||||
#define dds_waitset_unlock(obj) dds_entity_unlock((dds_entity*)obj);
|
||||
|
||||
|
||||
static void
|
||||
dds_waitset_swap(
|
||||
_Inout_ dds_attachment **dst,
|
||||
_In_ dds_attachment **src,
|
||||
_In_opt_ dds_attachment *prev,
|
||||
_In_ dds_attachment *idx)
|
||||
{
|
||||
/* Remove from source. */
|
||||
if (prev == NULL) {
|
||||
*src = idx->next;
|
||||
} else {
|
||||
prev->next = idx->next;
|
||||
}
|
||||
|
||||
/* Add to destination. */
|
||||
idx->next = *dst;
|
||||
*dst = idx;
|
||||
}
|
||||
|
||||
static void
|
||||
dds_waitset_signal_entity(
|
||||
_In_ dds_waitset *ws)
|
||||
{
|
||||
dds_entity *e = (dds_entity*)ws;
|
||||
/* When signaling any observers of us through the entity,
|
||||
* we need to be unlocked. We still have claimed the related
|
||||
* handle, so possible deletions will be delayed until we
|
||||
* release it. */
|
||||
os_mutexUnlock(&(e->m_mutex));
|
||||
dds_entity_status_signal(e);
|
||||
os_mutexLock(&(e->m_mutex));
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_waitset_wait_impl(
|
||||
_In_ dds_entity_t waitset,
|
||||
_Out_writes_to_opt_(nxs, return < 0 ? 0 : return) dds_attach_t *xs,
|
||||
_In_ size_t nxs,
|
||||
_In_ dds_time_t abstimeout,
|
||||
_In_ dds_time_t tnow)
|
||||
{
|
||||
dds_waitset *ws;
|
||||
dds_return_t ret;
|
||||
dds__retcode_t rc;
|
||||
dds_attachment *idx;
|
||||
dds_attachment *next;
|
||||
dds_attachment *prev;
|
||||
|
||||
if ((xs == NULL) && (nxs != 0)){
|
||||
return DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "A size was given, but no array.");
|
||||
}
|
||||
if ((xs != NULL) && (nxs == 0)){
|
||||
return DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Array is given with an invalid size");
|
||||
}
|
||||
|
||||
/* Locking the waitset here will delay a possible deletion until it is
|
||||
* unlocked. Even when the related mutex is unlocked by a conditioned wait. */
|
||||
rc = dds_waitset_lock(waitset, &ws);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
/* Check if any of any previous triggered entities has changed there status
|
||||
* and thus it trigger value could be false now. */
|
||||
idx = ws->triggered;
|
||||
prev = NULL;
|
||||
while (idx != NULL) {
|
||||
next = idx->next;
|
||||
if (idx->entity->m_trigger == 0) {
|
||||
/* Move observed entity to triggered list. */
|
||||
dds_waitset_swap(&(ws->observed), &(ws->triggered), prev, idx);
|
||||
} else {
|
||||
prev = idx;
|
||||
}
|
||||
idx = next;
|
||||
}
|
||||
/* Check if any of the entities have been triggered. */
|
||||
idx = ws->observed;
|
||||
prev = NULL;
|
||||
while (idx != NULL) {
|
||||
next = idx->next;
|
||||
if (idx->entity->m_trigger > 0) {
|
||||
/* Move observed entity to triggered list. */
|
||||
dds_waitset_swap(&(ws->triggered), &(ws->observed), prev, idx);
|
||||
} else {
|
||||
prev = idx;
|
||||
}
|
||||
idx = next;
|
||||
}
|
||||
|
||||
/* Only wait/keep waiting when whe have something to observer and there aren't any triggers yet. */
|
||||
rc = DDS_RETCODE_OK;
|
||||
while ((ws->observed != NULL) && (ws->triggered == NULL) && (rc == DDS_RETCODE_OK)) {
|
||||
if (abstimeout == DDS_NEVER) {
|
||||
os_condWait(&ws->m_entity.m_cond, &ws->m_entity.m_mutex);
|
||||
} else if (abstimeout <= tnow) {
|
||||
rc = DDS_RETCODE_TIMEOUT;
|
||||
} else {
|
||||
dds_duration_t dt = abstimeout - tnow;
|
||||
os_time to;
|
||||
if ((dt / (dds_duration_t)DDS_NSECS_IN_SEC) >= (dds_duration_t)OS_TIME_INFINITE_SEC) {
|
||||
to.tv_sec = OS_TIME_INFINITE_SEC;
|
||||
to.tv_nsec = DDS_NSECS_IN_SEC - 1;
|
||||
} else {
|
||||
to.tv_sec = (os_timeSec) (dt / DDS_NSECS_IN_SEC);
|
||||
to.tv_nsec = (uint32_t) (dt % DDS_NSECS_IN_SEC);
|
||||
}
|
||||
(void)os_condTimedWait(&ws->m_entity.m_cond, &ws->m_entity.m_mutex, &to);
|
||||
tnow = dds_time();
|
||||
}
|
||||
}
|
||||
|
||||
/* Get number of triggered entities
|
||||
* - set attach array when needed
|
||||
* - swap them back to observed */
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
ret = 0;
|
||||
idx = ws->triggered;
|
||||
while (idx != NULL) {
|
||||
if ((uint32_t)ret < (uint32_t)nxs) {
|
||||
xs[ret] = idx->arg;
|
||||
}
|
||||
ret++;
|
||||
|
||||
next = idx->next;
|
||||
/* The idx is always the first in triggered, so no prev. */
|
||||
dds_waitset_swap(&(ws->observed), &(ws->triggered), NULL, idx);
|
||||
idx = next;
|
||||
}
|
||||
} else if (rc == DDS_RETCODE_TIMEOUT) {
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "Internal error");
|
||||
}
|
||||
|
||||
dds_waitset_unlock(ws);
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking waitset");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
dds_waitset_close_list(
|
||||
_In_ dds_attachment **list,
|
||||
_In_ dds_entity_t waitset)
|
||||
{
|
||||
dds_attachment *idx = *list;
|
||||
dds_attachment *next;
|
||||
while (idx != NULL) {
|
||||
next = idx->next;
|
||||
(void)dds_entity_observer_unregister(idx->entity->m_hdl, waitset);
|
||||
os_free(idx);
|
||||
idx = next;
|
||||
}
|
||||
*list = NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
dds_waitset_remove_from_list(
|
||||
_In_ dds_attachment **list,
|
||||
_In_ dds_entity_t observed)
|
||||
{
|
||||
dds_attachment *idx = *list;
|
||||
dds_attachment *prev = NULL;
|
||||
|
||||
while (idx != NULL) {
|
||||
if (idx->entity->m_hdl == observed) {
|
||||
if (prev == NULL) {
|
||||
*list = idx->next;
|
||||
} else {
|
||||
prev->next = idx->next;
|
||||
}
|
||||
os_free(idx);
|
||||
|
||||
/* We're done. */
|
||||
return true;
|
||||
}
|
||||
prev = idx;
|
||||
idx = idx->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
dds_waitset_close(
|
||||
struct dds_entity *e)
|
||||
{
|
||||
dds_waitset *ws = (dds_waitset*)e;
|
||||
|
||||
dds_waitset_close_list(&(ws->observed), e->m_hdl);
|
||||
dds_waitset_close_list(&(ws->triggered), e->m_hdl);
|
||||
|
||||
/* Trigger waitset to wake up. */
|
||||
os_condBroadcast(&e->m_cond);
|
||||
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((participant & DDS_ENTITY_KIND_MASK) == DDS_KIND_PARTICIPANT)
|
||||
DDS_EXPORT _Must_inspect_result_ dds_entity_t
|
||||
dds_create_waitset(
|
||||
_In_ dds_entity_t participant)
|
||||
{
|
||||
dds_entity_t hdl;
|
||||
dds_entity *par;
|
||||
dds__retcode_t rc;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_entity_lock(participant, DDS_KIND_PARTICIPANT, &par);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
dds_waitset *waitset = dds_alloc(sizeof(*waitset));
|
||||
hdl = dds_entity_init(&waitset->m_entity, par, DDS_KIND_WAITSET, NULL, NULL, 0);
|
||||
waitset->m_entity.m_deriver.close = dds_waitset_close;
|
||||
waitset->observed = NULL;
|
||||
waitset->triggered = NULL;
|
||||
dds_entity_unlock(par);
|
||||
} else {
|
||||
hdl = DDS_ERRNO(rc, "Error occurred on locking entity");
|
||||
}
|
||||
DDS_REPORT_FLUSH(hdl <= 0);
|
||||
return hdl;
|
||||
}
|
||||
|
||||
|
||||
_Pre_satisfies_((waitset & DDS_ENTITY_KIND_MASK) == DDS_KIND_WAITSET)
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_waitset_get_entities(
|
||||
_In_ dds_entity_t waitset,
|
||||
_Out_writes_to_(size, return < 0 ? 0 : return) dds_entity_t *entities,
|
||||
_In_ size_t size)
|
||||
{
|
||||
dds_return_t ret = 0;
|
||||
dds__retcode_t rc;
|
||||
dds_waitset *ws;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_waitset_lock(waitset, &ws);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
dds_attachment* iter;
|
||||
|
||||
iter = ws->observed;
|
||||
while (iter) {
|
||||
if (((size_t)ret < size) && (entities != NULL)) {
|
||||
entities[ret] = iter->entity->m_hdl;
|
||||
}
|
||||
ret++;
|
||||
iter = iter->next;
|
||||
}
|
||||
|
||||
iter = ws->triggered;
|
||||
while (iter) {
|
||||
if (((size_t)ret < size) && (entities != NULL)) {
|
||||
entities[ret] = iter->entity->m_hdl;
|
||||
}
|
||||
ret++;
|
||||
iter = iter->next;
|
||||
}
|
||||
dds_waitset_unlock(ws);
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking waitset");
|
||||
}
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dds_waitset_move(
|
||||
_In_ dds_attachment **src,
|
||||
_Inout_ dds_attachment **dst,
|
||||
_In_ dds_entity_t entity)
|
||||
{
|
||||
dds_attachment *idx = *src;
|
||||
dds_attachment *prev = NULL;
|
||||
while (idx != NULL) {
|
||||
if (idx->entity->m_hdl == entity) {
|
||||
/* Swap idx from src to dst. */
|
||||
dds_waitset_swap(dst, src, prev, idx);
|
||||
|
||||
/* We're done. */
|
||||
return;
|
||||
}
|
||||
prev = idx;
|
||||
idx = idx->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dds_waitset_remove(
|
||||
dds_waitset *ws,
|
||||
dds_entity_t observed)
|
||||
{
|
||||
if (!dds_waitset_remove_from_list(&(ws->observed), observed)) {
|
||||
(void)dds_waitset_remove_from_list(&(ws->triggered), observed);
|
||||
}
|
||||
}
|
||||
|
||||
/* This is called when the observed entity signals a status change. */
|
||||
void
|
||||
dds_waitset_observer(
|
||||
dds_entity_t observer,
|
||||
dds_entity_t observed,
|
||||
uint32_t status)
|
||||
{
|
||||
dds_waitset *ws;
|
||||
if (dds_waitset_lock(observer, &ws) == DDS_RETCODE_OK) {
|
||||
if (status & DDS_DELETING_STATUS) {
|
||||
/* Remove this observed entity, which is being deleted, from the waitset. */
|
||||
dds_waitset_remove(ws, observed);
|
||||
/* Our registration to this observed entity will be removed automatically. */
|
||||
} else if (status != 0) {
|
||||
/* Move observed entity to triggered list. */
|
||||
dds_waitset_move(&(ws->observed), &(ws->triggered), observed);
|
||||
} else {
|
||||
/* Remove observed entity from triggered list (which it possibly resides in). */
|
||||
dds_waitset_move(&(ws->triggered), &(ws->observed), observed);
|
||||
}
|
||||
/* Trigger waitset to wake up. */
|
||||
os_condBroadcast(&ws->m_entity.m_cond);
|
||||
dds_waitset_unlock(ws);
|
||||
}
|
||||
}
|
||||
|
||||
_Pre_satisfies_((waitset & DDS_ENTITY_KIND_MASK) == DDS_KIND_WAITSET)
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_waitset_attach(
|
||||
_In_ dds_entity_t waitset,
|
||||
_In_ dds_entity_t entity,
|
||||
_In_ dds_attach_t x)
|
||||
{
|
||||
dds_entity *e = NULL;
|
||||
dds_waitset *ws;
|
||||
dds__retcode_t rc;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_waitset_lock(waitset, &ws);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
if (waitset != entity) {
|
||||
rc = dds_entity_lock(entity, DDS_KIND_DONTCARE, &e);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
e = NULL;
|
||||
}
|
||||
} else {
|
||||
e = (dds_entity*)ws;
|
||||
}
|
||||
|
||||
/* This will fail if given entity is already attached (or deleted). */
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
rc = dds_entity_observer_register_nl(e, waitset, dds_waitset_observer);
|
||||
}
|
||||
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
dds_attachment *a = os_malloc(sizeof(dds_attachment));
|
||||
a->arg = x;
|
||||
a->entity = e;
|
||||
if (e->m_trigger > 0) {
|
||||
a->next = ws->triggered;
|
||||
ws->triggered = a;
|
||||
} else {
|
||||
a->next = ws->observed;
|
||||
ws->observed = a;
|
||||
}
|
||||
ret = DDS_RETCODE_OK;
|
||||
} else if (rc != DDS_RETCODE_PRECONDITION_NOT_MET) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Entity is not valid");
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "Entity is already attached.");
|
||||
}
|
||||
if ((e != NULL) && (waitset != entity)) {
|
||||
dds_entity_unlock(e);
|
||||
}
|
||||
dds_waitset_unlock(ws);
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking waitset");
|
||||
}
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK );
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((waitset & DDS_ENTITY_KIND_MASK) == DDS_KIND_WAITSET)
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_waitset_detach(
|
||||
_In_ dds_entity_t waitset,
|
||||
_In_ dds_entity_t entity)
|
||||
{
|
||||
dds_waitset *ws;
|
||||
dds__retcode_t rc;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_waitset_lock(waitset, &ws);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
/* Possibly fails when entity was not attached. */
|
||||
if (waitset == entity) {
|
||||
rc = dds_entity_observer_unregister_nl((dds_entity*)ws, waitset);
|
||||
} else {
|
||||
rc = dds_entity_observer_unregister(entity, waitset);
|
||||
}
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
dds_waitset_remove(ws, entity);
|
||||
ret = DDS_RETCODE_OK;
|
||||
} else if (rc != DDS_RETCODE_PRECONDITION_NOT_MET) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "The given entity to detach is invalid.");
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "The given entity to detach was not attached previously.");
|
||||
}
|
||||
dds_waitset_unlock(ws);
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking waitset");
|
||||
}
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((waitset & DDS_ENTITY_KIND_MASK) == DDS_KIND_WAITSET)
|
||||
dds_return_t
|
||||
dds_waitset_wait_until(
|
||||
_In_ dds_entity_t waitset,
|
||||
_Out_writes_to_opt_(nxs, return < 0 ? 0 : return) dds_attach_t *xs,
|
||||
_In_ size_t nxs,
|
||||
_In_ dds_time_t abstimeout)
|
||||
{
|
||||
dds_return_t ret;
|
||||
DDS_REPORT_STACK();
|
||||
ret = dds_waitset_wait_impl(waitset, xs, nxs, abstimeout, dds_time());
|
||||
DDS_REPORT_FLUSH(ret <0 );
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((waitset & DDS_ENTITY_KIND_MASK) == DDS_KIND_WAITSET)
|
||||
dds_return_t
|
||||
dds_waitset_wait(
|
||||
_In_ dds_entity_t waitset,
|
||||
_Out_writes_to_opt_(nxs, return < 0 ? 0 : return) dds_attach_t *xs,
|
||||
_In_ size_t nxs,
|
||||
_In_ dds_duration_t reltimeout)
|
||||
{
|
||||
dds_entity_t ret;
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (reltimeout >= 0) {
|
||||
dds_time_t tnow = dds_time();
|
||||
dds_time_t abstimeout = (DDS_INFINITY - reltimeout <= tnow) ? DDS_NEVER : (tnow + reltimeout);
|
||||
ret = dds_waitset_wait_impl(waitset, xs, nxs, abstimeout, tnow);
|
||||
} else{
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Negative timeout");
|
||||
}
|
||||
DDS_REPORT_FLUSH(ret <0 );
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((waitset & DDS_ENTITY_KIND_MASK) == DDS_KIND_WAITSET)
|
||||
dds_return_t
|
||||
dds_waitset_set_trigger(
|
||||
_In_ dds_entity_t waitset,
|
||||
_In_ bool trigger)
|
||||
{
|
||||
dds_waitset *ws;
|
||||
dds__retcode_t rc;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
/* Locking the waitset here will delay a possible deletion until it is
|
||||
* unlocked. Even when the related mutex is unlocked when we want to send
|
||||
* a signal. */
|
||||
rc = dds_waitset_lock(waitset, &ws);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking waitset");
|
||||
goto fail;
|
||||
}
|
||||
if (trigger) {
|
||||
dds_entity_status_set(ws, DDS_WAITSET_TRIGGER_STATUS);
|
||||
} else {
|
||||
dds_entity_status_reset(ws, DDS_WAITSET_TRIGGER_STATUS);
|
||||
}
|
||||
dds_waitset_signal_entity(ws);
|
||||
dds_waitset_unlock(ws);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
406
src/core/ddsc/src/dds_write.c
Normal file
406
src/core/ddsc/src/dds_write.c
Normal file
|
|
@ -0,0 +1,406 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include "dds__writer.h"
|
||||
#include "dds__write.h"
|
||||
#include "dds__tkmap.h"
|
||||
#include "ddsi/q_error.h"
|
||||
#include "ddsi/q_thread.h"
|
||||
#include "q__osplser.h"
|
||||
#include "dds__err.h"
|
||||
#include "ddsi/q_transmit.h"
|
||||
#include "ddsi/q_ephash.h"
|
||||
#include "ddsi/q_config.h"
|
||||
#include "ddsi/q_entity.h"
|
||||
#include "dds__report.h"
|
||||
#include "ddsi/q_radmin.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
typedef os_atomic_uint64_t fake_seq_t;
|
||||
uint64_t fake_seq_next (fake_seq_t *x) { return os_atomic_inc64_nv (x); }
|
||||
#else /* HACK */
|
||||
typedef os_atomic_uint32_t fake_seq_t;
|
||||
uint64_t fake_seq_next (fake_seq_t *x) { return os_atomic_inc32_nv (x); }
|
||||
#endif
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
dds_return_t
|
||||
dds_write(
|
||||
_In_ dds_entity_t writer,
|
||||
_In_ const void *data)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds__retcode_t rc;
|
||||
dds_writer *wr;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (data != NULL) {
|
||||
rc = dds_writer_lock(writer, &wr);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
ret = dds_write_impl(wr, data, dds_time(), 0);
|
||||
dds_writer_unlock(wr);
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking entity");
|
||||
}
|
||||
} else {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "No data buffer provided");
|
||||
}
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
int
|
||||
dds_writecdr(
|
||||
dds_entity_t writer,
|
||||
const void *cdr,
|
||||
size_t size)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds__retcode_t rc;
|
||||
dds_writer *wr;
|
||||
if (cdr != NULL) {
|
||||
rc = dds_writer_lock(writer, &wr);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
ret = dds_writecdr_impl (wr, cdr, size, dds_time (), 0);
|
||||
dds_writer_unlock(wr);
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking writer");
|
||||
}
|
||||
} else{
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Given cdr has NULL value");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
dds_return_t
|
||||
dds_write_ts(
|
||||
_In_ dds_entity_t writer,
|
||||
_In_ const void *data,
|
||||
_In_ dds_time_t timestamp)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds__retcode_t rc;
|
||||
dds_writer *wr;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if(data == NULL){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument data has NULL value");
|
||||
goto err;
|
||||
}
|
||||
if(timestamp < 0){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Argument timestamp has negative value");
|
||||
goto err;
|
||||
}
|
||||
rc = dds_writer_lock(writer, &wr);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
ret = dds_write_impl(wr, data, timestamp, 0);
|
||||
dds_writer_unlock(wr);
|
||||
} else {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking writer");
|
||||
}
|
||||
err:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
init_sampleinfo(
|
||||
_Out_ struct nn_rsample_info *sampleinfo,
|
||||
_In_ struct writer *wr,
|
||||
_In_ int64_t seq,
|
||||
_In_ serdata_t payload)
|
||||
{
|
||||
memset(sampleinfo, 0, sizeof(*sampleinfo));
|
||||
sampleinfo->bswap = 0;
|
||||
sampleinfo->complex_qos = 0;
|
||||
sampleinfo->hashash = 0;
|
||||
sampleinfo->seq = seq;
|
||||
sampleinfo->reception_timestamp = payload->v.msginfo.timestamp;
|
||||
sampleinfo->statusinfo = payload->v.msginfo.statusinfo;
|
||||
sampleinfo->pwr_info.iid = 1;
|
||||
sampleinfo->pwr_info.auto_dispose = 0;
|
||||
sampleinfo->pwr_info.guid = wr->e.guid;
|
||||
sampleinfo->pwr_info.ownership_strength = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
deliver_locally(
|
||||
_In_ struct writer *wr,
|
||||
_In_ int64_t seq,
|
||||
_In_ serdata_t payload,
|
||||
_In_ struct tkmap_instance *tk)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
os_mutexLock (&wr->rdary.rdary_lock);
|
||||
if (wr->rdary.fastpath_ok) {
|
||||
struct reader ** const rdary = wr->rdary.rdary;
|
||||
if (rdary[0]) {
|
||||
struct nn_rsample_info sampleinfo;
|
||||
unsigned i;
|
||||
init_sampleinfo(&sampleinfo, wr, seq, payload);
|
||||
for (i = 0; rdary[i]; i++) {
|
||||
bool stored;
|
||||
TRACE (("reader %x:%x:%x:%x\n", PGUID (rdary[i]->e.guid)));
|
||||
dds_duration_t max_block_ms = nn_from_ddsi_duration(wr->xqos->reliability.max_blocking_time) / DDS_NSECS_IN_MSEC;
|
||||
do {
|
||||
stored = (ddsi_plugin.rhc_store_fn) (rdary[i]->rhc, &sampleinfo, payload, tk);
|
||||
if (!stored) {
|
||||
if (max_block_ms <= 0) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_TIMEOUT, "The writer could not deliver data on time, probably due to a local reader resources being full.");
|
||||
} else {
|
||||
dds_sleepfor(DDS_MSECS(DDS_HEADBANG_TIMEOUT_MS));
|
||||
}
|
||||
/* Decreasing the block time after the sleep, let's us possibly
|
||||
* wait a bit too long. But that's preferable compared to waiting
|
||||
* a bit too short. */
|
||||
max_block_ms -= DDS_HEADBANG_TIMEOUT_MS;
|
||||
}
|
||||
} while ((!stored) && (ret == DDS_RETCODE_OK));
|
||||
}
|
||||
}
|
||||
os_mutexUnlock (&wr->rdary.rdary_lock);
|
||||
} else {
|
||||
/* When deleting, pwr is no longer accessible via the hash
|
||||
tables, and consequently, a reader may be deleted without
|
||||
it being possible to remove it from rdary. The primary
|
||||
reason rdary exists is to avoid locking the proxy writer
|
||||
but this is less of an issue when we are deleting it, so
|
||||
we fall back to using the GUIDs so that we can deliver all
|
||||
samples we received from it. As writer being deleted any
|
||||
reliable samples that are rejected are simply discarded. */
|
||||
ut_avlIter_t it;
|
||||
struct pwr_rd_match *m;
|
||||
struct nn_rsample_info sampleinfo;
|
||||
os_mutexUnlock (&wr->rdary.rdary_lock);
|
||||
init_sampleinfo(&sampleinfo, wr, seq, payload);
|
||||
os_mutexLock (&wr->e.lock);
|
||||
for (m = ut_avlIterFirst (&wr_local_readers_treedef, &wr->local_readers, &it); m != NULL; m = ut_avlIterNext (&it)) {
|
||||
struct reader *rd;
|
||||
if ((rd = ephash_lookup_reader_guid (&m->rd_guid)) != NULL) {
|
||||
TRACE (("reader-via-guid %x:%x:%x:%x\n", PGUID (rd->e.guid)));
|
||||
/* Copied the return value ignore from DDSI deliver_user_data() function. */
|
||||
(void)(ddsi_plugin.rhc_store_fn) (rd->rhc, &sampleinfo, payload, tk);
|
||||
}
|
||||
}
|
||||
os_mutexUnlock (&wr->e.lock);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dds_write_impl(
|
||||
_In_ dds_writer *wr,
|
||||
_In_ const void * data,
|
||||
_In_ dds_time_t tstamp,
|
||||
_In_ dds_write_action action)
|
||||
{
|
||||
static fake_seq_t fake_seq;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
int w_rc;
|
||||
|
||||
assert (wr);
|
||||
assert (dds_entity_kind(((dds_entity*)wr)->m_hdl) == DDS_KIND_WRITER);
|
||||
|
||||
struct thread_state1 * const thr = lookup_thread_state ();
|
||||
const bool asleep = !vtime_awake_p (thr->vtime);
|
||||
const bool writekey = action & DDS_WR_KEY_BIT;
|
||||
dds_writer * writer = (dds_writer*) wr;
|
||||
struct writer * ddsi_wr = writer->m_wr;
|
||||
struct tkmap_instance * tk;
|
||||
serdata_t d;
|
||||
|
||||
if (data == NULL) {
|
||||
return DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "No data buffer provided");
|
||||
}
|
||||
|
||||
/* Check for topic filter */
|
||||
if (ddsi_wr->topic->filter_fn && ! writekey) {
|
||||
if (!(ddsi_wr->topic->filter_fn) (data, ddsi_wr->topic->filter_ctx)) {
|
||||
goto filtered;
|
||||
}
|
||||
}
|
||||
|
||||
if (asleep) {
|
||||
thread_state_awake (thr);
|
||||
}
|
||||
|
||||
/* Serialize and write data or key */
|
||||
if (writekey) {
|
||||
d = serialize_key (gv.serpool, ddsi_wr->topic, data);
|
||||
} else {
|
||||
d = serialize (gv.serpool, ddsi_wr->topic, data);
|
||||
}
|
||||
|
||||
/* Set if disposing or unregistering */
|
||||
d->v.msginfo.statusinfo = ((action & DDS_WR_DISPOSE_BIT ) ? NN_STATUSINFO_DISPOSE : 0) |
|
||||
((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0) ;
|
||||
d->v.msginfo.timestamp.v = tstamp;
|
||||
os_mutexLock (&writer->m_call_lock);
|
||||
ddsi_serdata_ref(d);
|
||||
tk = (ddsi_plugin.rhc_lookup_fn) (d);
|
||||
w_rc = write_sample_gc (writer->m_xp, ddsi_wr, d, tk);
|
||||
|
||||
if (w_rc >= 0) {
|
||||
/* Flush out write unless configured to batch */
|
||||
if (! config.whc_batch){
|
||||
nn_xpack_send (writer->m_xp, false);
|
||||
}
|
||||
ret = DDS_RETCODE_OK;
|
||||
} else if (w_rc == ERR_TIMEOUT) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_TIMEOUT, "The writer could not deliver data on time, probably due to a reader resources being full.");
|
||||
} else if (w_rc == ERR_INVALID_DATA) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Invalid data provided");
|
||||
} else {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Internal error");
|
||||
}
|
||||
os_mutexUnlock (&writer->m_call_lock);
|
||||
|
||||
if (ret == DDS_RETCODE_OK) {
|
||||
ret = deliver_locally (ddsi_wr, fake_seq_next(&fake_seq), d, tk);
|
||||
}
|
||||
ddsi_serdata_unref(d);
|
||||
(ddsi_plugin.rhc_unref_fn) (tk);
|
||||
|
||||
if (asleep) {
|
||||
thread_state_asleep (thr);
|
||||
}
|
||||
|
||||
filtered:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dds_writecdr_impl(
|
||||
_In_ dds_writer *wr,
|
||||
_In_ const void *cdr,
|
||||
_In_ size_t sz,
|
||||
_In_ dds_time_t tstamp,
|
||||
_In_ dds_write_action action)
|
||||
{
|
||||
static fake_seq_t fake_seq;
|
||||
int ret = DDS_RETCODE_OK;
|
||||
int w_rc;
|
||||
|
||||
assert (wr);
|
||||
assert (cdr);
|
||||
|
||||
struct thread_state1 * const thr = lookup_thread_state ();
|
||||
const bool asleep = !vtime_awake_p (thr->vtime);
|
||||
const bool writekey = action & DDS_WR_KEY_BIT;
|
||||
struct writer * ddsi_wr = wr->m_wr;
|
||||
struct tkmap_instance * tk;
|
||||
serdata_t d;
|
||||
|
||||
/* Check for topic filter */
|
||||
if (ddsi_wr->topic->filter_fn && ! writekey) {
|
||||
abort();
|
||||
}
|
||||
|
||||
if (asleep) {
|
||||
thread_state_awake (thr);
|
||||
}
|
||||
|
||||
/* Serialize and write data or key */
|
||||
if (writekey) {
|
||||
abort();
|
||||
//d = serialize_key (gv.serpool, ddsi_wr->topic, data);
|
||||
} else {
|
||||
serstate_t st = ddsi_serstate_new (gv.serpool, ddsi_wr->topic);
|
||||
if (ddsi_wr->topic->nkeys) {
|
||||
abort();
|
||||
//dds_key_gen ((const dds_topic_descriptor_t*) tp->type, &st->data->v.keyhash, (char*) sample);
|
||||
}
|
||||
ddsi_serstate_append_blob(st, 1, sz, cdr);
|
||||
d = ddsi_serstate_fix(st);
|
||||
}
|
||||
|
||||
/* Set if disposing or unregistering */
|
||||
d->v.msginfo.statusinfo = ((action & DDS_WR_DISPOSE_BIT ) ? NN_STATUSINFO_DISPOSE : 0) |
|
||||
((action & DDS_WR_UNREGISTER_BIT) ? NN_STATUSINFO_UNREGISTER : 0) ;
|
||||
d->v.msginfo.timestamp.v = tstamp;
|
||||
os_mutexLock (&wr->m_call_lock);
|
||||
ddsi_serdata_ref(d);
|
||||
tk = (ddsi_plugin.rhc_lookup_fn) (d);
|
||||
w_rc = write_sample_gc (wr->m_xp, ddsi_wr, d, tk);
|
||||
|
||||
if (w_rc >= 0) {
|
||||
/* Flush out write unless configured to batch */
|
||||
if (! config.whc_batch) {
|
||||
nn_xpack_send (wr->m_xp, false);
|
||||
}
|
||||
ret = DDS_RETCODE_OK;
|
||||
} else if (w_rc == ERR_TIMEOUT) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_TIMEOUT, "The writer could not deliver data on time, probably due to a reader resources being full.");
|
||||
} else if (w_rc == ERR_INVALID_DATA) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Invalid data provided");
|
||||
} else {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Internal error");
|
||||
}
|
||||
os_mutexUnlock (&wr->m_call_lock);
|
||||
|
||||
if (ret == DDS_RETCODE_OK) {
|
||||
ret = deliver_locally (ddsi_wr, fake_seq_next(&fake_seq), d, tk);
|
||||
}
|
||||
ddsi_serdata_unref(d);
|
||||
(ddsi_plugin.rhc_unref_fn) (tk);
|
||||
|
||||
if (asleep) {
|
||||
thread_state_asleep (thr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
dds_write_set_batch(
|
||||
bool enable)
|
||||
{
|
||||
config.whc_batch = enable ? 1 : 0;
|
||||
}
|
||||
|
||||
_Pre_satisfies_((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER)
|
||||
void
|
||||
dds_write_flush(
|
||||
dds_entity_t writer)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
dds__retcode_t rc;
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
struct thread_state1 * const thr = lookup_thread_state ();
|
||||
const bool asleep = !vtime_awake_p (thr->vtime);
|
||||
dds_writer *wr;
|
||||
|
||||
if (asleep) {
|
||||
thread_state_awake (thr);
|
||||
}
|
||||
rc = dds_writer_lock(writer, &wr);
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
nn_xpack_send (wr->m_xp, true);
|
||||
dds_writer_unlock(wr);
|
||||
ret = DDS_RETCODE_OK;
|
||||
} else{
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking writer");
|
||||
}
|
||||
|
||||
if (asleep) {
|
||||
thread_state_asleep (thr);
|
||||
}
|
||||
DDS_REPORT_FLUSH(ret < 0);
|
||||
return ;
|
||||
}
|
||||
611
src/core/ddsc/src/dds_writer.c
Normal file
611
src/core/ddsc/src/dds_writer.c
Normal file
|
|
@ -0,0 +1,611 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include "ddsc/dds.h"
|
||||
#include "ddsi/q_config.h"
|
||||
#include "ddsi/q_entity.h"
|
||||
#include "ddsi/q_thread.h"
|
||||
#include "q__osplser.h"
|
||||
#include "dds__writer.h"
|
||||
#include "dds__listener.h"
|
||||
#include "dds__qos.h"
|
||||
#include "dds__err.h"
|
||||
#include "dds__init.h"
|
||||
#include "dds__tkmap.h"
|
||||
#include "dds__report.h"
|
||||
#include "ddsc/ddsc_project.h"
|
||||
|
||||
#define DDS_WRITER_STATUS_MASK \
|
||||
DDS_LIVELINESS_LOST_STATUS |\
|
||||
DDS_OFFERED_DEADLINE_MISSED_STATUS |\
|
||||
DDS_OFFERED_INCOMPATIBLE_QOS_STATUS |\
|
||||
DDS_PUBLICATION_MATCHED_STATUS
|
||||
|
||||
static dds_return_t
|
||||
dds_writer_instance_hdl(
|
||||
dds_entity *e,
|
||||
dds_instance_handle_t *i)
|
||||
{
|
||||
assert(e);
|
||||
assert(i);
|
||||
*i = (dds_instance_handle_t)writer_instance_id(&e->m_guid);
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_writer_status_validate(
|
||||
uint32_t mask)
|
||||
{
|
||||
return (mask & ~(DDS_WRITER_STATUS_MASK)) ?
|
||||
DDS_ERRNO(DDS_RETCODE_BAD_PARAMETER, "Invalid status mask") :
|
||||
DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Handler function for all write related status callbacks. May trigger status
|
||||
condition or call listener on writer. Each entity has a mask of
|
||||
supported status types. According to DDS specification, if listener is called
|
||||
then status conditions is not triggered.
|
||||
*/
|
||||
|
||||
static void
|
||||
dds_writer_status_cb(
|
||||
void *entity,
|
||||
const status_cb_data_t *data)
|
||||
{
|
||||
dds_writer *wr;
|
||||
dds__retcode_t rc;
|
||||
void *metrics = NULL;
|
||||
|
||||
/* When data is NULL, it means that the writer is deleted. */
|
||||
if (data == NULL) {
|
||||
/* Release the initial claim that was done during the create. This
|
||||
* will indicate that further API deletion is now possible. */
|
||||
ut_handle_release(((dds_entity*)entity)->m_hdl, ((dds_entity*)entity)->m_hdllink);
|
||||
return;
|
||||
}
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
if (dds_writer_lock(((dds_entity*)entity)->m_hdl, &wr) != DDS_RETCODE_OK) {
|
||||
/* There's a deletion or closing going on. */
|
||||
DDS_REPORT_FLUSH(false);
|
||||
return;
|
||||
}
|
||||
assert(wr == entity);
|
||||
|
||||
/* Reset the status for possible Listener call.
|
||||
* When a listener is not called, the status will be set (again). */
|
||||
dds_entity_status_reset(entity, data->status);
|
||||
|
||||
/* Update status metrics. */
|
||||
switch (data->status) {
|
||||
case DDS_OFFERED_DEADLINE_MISSED_STATUS: {
|
||||
wr->m_offered_deadline_missed_status.total_count++;
|
||||
wr->m_offered_deadline_missed_status.total_count_change++;
|
||||
wr->m_offered_deadline_missed_status.last_instance_handle = data->handle;
|
||||
metrics = (void*)&(wr->m_offered_deadline_missed_status);
|
||||
break;
|
||||
}
|
||||
case DDS_LIVELINESS_LOST_STATUS: {
|
||||
wr->m_liveliness_lost_status.total_count++;
|
||||
wr->m_liveliness_lost_status.total_count_change++;
|
||||
metrics = (void*)&(wr->m_liveliness_lost_status);
|
||||
break;
|
||||
}
|
||||
case DDS_OFFERED_INCOMPATIBLE_QOS_STATUS: {
|
||||
wr->m_offered_incompatible_qos_status.total_count++;
|
||||
wr->m_offered_incompatible_qos_status.total_count_change++;
|
||||
wr->m_offered_incompatible_qos_status.last_policy_id = data->extra;
|
||||
metrics = (void*)&(wr->m_offered_incompatible_qos_status);
|
||||
break;
|
||||
}
|
||||
case DDS_PUBLICATION_MATCHED_STATUS: {
|
||||
if (data->add) {
|
||||
wr->m_publication_matched_status.total_count++;
|
||||
wr->m_publication_matched_status.total_count_change++;
|
||||
wr->m_publication_matched_status.current_count++;
|
||||
wr->m_publication_matched_status.current_count_change++;
|
||||
} else {
|
||||
wr->m_publication_matched_status.current_count--;
|
||||
wr->m_publication_matched_status.current_count_change--;
|
||||
}
|
||||
wr->m_publication_matched_status.last_subscription_handle = data->handle;
|
||||
metrics = (void*)&(wr->m_publication_matched_status);
|
||||
break;
|
||||
}
|
||||
default: assert (0);
|
||||
}
|
||||
|
||||
/* The writer needs to be unlocked when propagating the (possible) listener
|
||||
* call because the application should be able to call this writer within
|
||||
* the callback function. */
|
||||
dds_writer_unlock(wr);
|
||||
|
||||
/* Is anybody interested within the entity hierarchy through listeners? */
|
||||
rc = dds_entity_listener_propagation(entity, entity, data->status, metrics, true);
|
||||
|
||||
if (rc == DDS_RETCODE_OK) {
|
||||
/* Event was eaten by a listener. */
|
||||
if (dds_writer_lock(((dds_entity*)entity)->m_hdl, &wr) == DDS_RETCODE_OK) {
|
||||
assert(wr == entity);
|
||||
|
||||
/* Reset the status. */
|
||||
dds_entity_status_reset(entity, data->status);
|
||||
|
||||
/* Reset the change counts of the metrics. */
|
||||
switch (data->status) {
|
||||
case DDS_OFFERED_DEADLINE_MISSED_STATUS: {
|
||||
wr->m_offered_deadline_missed_status.total_count_change = 0;
|
||||
break;
|
||||
}
|
||||
case DDS_LIVELINESS_LOST_STATUS: {
|
||||
wr->m_liveliness_lost_status.total_count_change = 0;
|
||||
break;
|
||||
}
|
||||
case DDS_OFFERED_INCOMPATIBLE_QOS_STATUS: {
|
||||
wr->m_offered_incompatible_qos_status.total_count_change = 0;
|
||||
break;
|
||||
}
|
||||
case DDS_PUBLICATION_MATCHED_STATUS: {
|
||||
wr->m_publication_matched_status.total_count_change = 0;
|
||||
wr->m_publication_matched_status.current_count_change = 0;
|
||||
break;
|
||||
}
|
||||
default: assert (0);
|
||||
}
|
||||
dds_writer_unlock(wr);
|
||||
} else {
|
||||
/* There's a deletion or closing going on. */
|
||||
}
|
||||
} else if (rc == DDS_RETCODE_NO_DATA) {
|
||||
/* Nobody was interested through a listener (NO_DATA == NO_CALL): set the status. */
|
||||
dds_entity_status_set(entity, data->status);
|
||||
/* Notify possible interested observers. */
|
||||
dds_entity_status_signal(entity);
|
||||
rc = DDS_RETCODE_OK;
|
||||
} else if (rc == DDS_RETCODE_ALREADY_DELETED) {
|
||||
/* An entity up the hierarchy is being deleted. */
|
||||
rc = DDS_RETCODE_OK;
|
||||
} else {
|
||||
/* Something went wrong up the hierarchy. */
|
||||
}
|
||||
|
||||
DDS_REPORT_FLUSH(rc != DDS_RETCODE_OK);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_bandwidth_limit(
|
||||
nn_transport_priority_qospolicy_t transport_priority)
|
||||
{
|
||||
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
|
||||
struct config_channel_listelem *channel = find_channel (transport_priority);
|
||||
return channel->data_bandwidth_limit;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_writer_close(
|
||||
dds_entity *e)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
dds_writer *wr = (dds_writer*)e;
|
||||
struct thread_state1 * const thr = lookup_thread_state();
|
||||
const bool asleep = thr ? !vtime_awake_p(thr->vtime) : false;
|
||||
|
||||
assert(e);
|
||||
|
||||
if (asleep) {
|
||||
thread_state_awake(thr);
|
||||
}
|
||||
if (thr) {
|
||||
nn_xpack_send (wr->m_xp, false);
|
||||
}
|
||||
if (delete_writer (&e->m_guid) != 0) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Internal error");
|
||||
}
|
||||
if (asleep) {
|
||||
thread_state_asleep(thr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_writer_delete(
|
||||
dds_entity *e)
|
||||
{
|
||||
dds_writer *wr = (dds_writer*)e;
|
||||
struct thread_state1 * const thr = lookup_thread_state();
|
||||
const bool asleep = thr ? !vtime_awake_p(thr->vtime) : false;
|
||||
dds_return_t ret;
|
||||
|
||||
assert(e);
|
||||
assert(thr);
|
||||
|
||||
if (asleep) {
|
||||
thread_state_awake(thr);
|
||||
}
|
||||
if (thr) {
|
||||
nn_xpack_free(wr->m_xp);
|
||||
}
|
||||
if (asleep) {
|
||||
thread_state_asleep(thr);
|
||||
}
|
||||
ret = dds_delete(wr->m_topic->m_entity.m_hdl);
|
||||
if(ret == DDS_RETCODE_OK){
|
||||
ret = dds_delete_impl(e->m_parent->m_hdl, true);
|
||||
if(dds_err_nr(ret) == DDS_RETCODE_ALREADY_DELETED){
|
||||
ret = DDS_RETCODE_OK;
|
||||
}
|
||||
}
|
||||
os_mutexDestroy(&wr->m_call_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static dds_return_t
|
||||
dds_writer_qos_validate(
|
||||
const dds_qos_t *qos,
|
||||
bool enabled)
|
||||
{
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
bool consistent = true;
|
||||
|
||||
assert(qos);
|
||||
|
||||
/* Check consistency. */
|
||||
if(dds_qos_validate_common(qos) != true){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Provided inconsistent QoS policy");
|
||||
}
|
||||
if((qos->present & QP_USER_DATA) && validate_octetseq(&qos->user_data) != true){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "User Data QoS policy is inconsistent and caused an error");
|
||||
}
|
||||
if ((qos->present & QP_DURABILITY_SERVICE) && validate_durability_service_qospolicy(&qos->durability_service) != 0){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Durability service QoS policy is inconsistent and caused an error");
|
||||
}
|
||||
if ((qos->present & QP_LIFESPAN) && validate_duration(&qos->lifespan.duration) != 0){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Lifespan QoS policy is inconsistent and caused an error");
|
||||
}
|
||||
if ((qos->present & QP_HISTORY) && (qos->present & QP_RESOURCE_LIMITS) && (validate_history_and_resource_limits(&qos->history, &qos->resource_limits) != 0)){
|
||||
ret = DDS_ERRNO(DDS_RETCODE_INCONSISTENT_POLICY, "Resource limits QoS policy is inconsistent and caused an error");
|
||||
}
|
||||
if(ret == DDS_RETCODE_OK && enabled) {
|
||||
ret = dds_qos_validate_mutable_common(qos);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
dds_writer_qos_set(
|
||||
dds_entity *e,
|
||||
const dds_qos_t *qos,
|
||||
bool enabled)
|
||||
{
|
||||
dds_return_t ret = dds_writer_qos_validate(qos, enabled);
|
||||
if (ret == DDS_RETCODE_OK) {
|
||||
/*
|
||||
* TODO: CHAM-95: DDSI does not support changing QoS policies.
|
||||
*
|
||||
* Only Ownership is required for the minimum viable product. This seems
|
||||
* to be the only QoS policy that DDSI supports changes on.
|
||||
*/
|
||||
if (qos->present & QP_OWNERSHIP_STRENGTH) {
|
||||
dds_ownership_kind_t kind;
|
||||
/* check for ownership before updating, ownership strength is applicable only if
|
||||
* writer is exclusive */
|
||||
dds_qget_ownership (e->m_qos, &kind);
|
||||
|
||||
if (kind == DDS_OWNERSHIP_EXCLUSIVE) {
|
||||
struct thread_state1 * const thr = lookup_thread_state ();
|
||||
const bool asleep = !vtime_awake_p (thr->vtime);
|
||||
struct writer * ddsi_wr = ((dds_writer*)e)->m_wr;
|
||||
|
||||
dds_qset_ownership_strength (e->m_qos, qos->ownership_strength.value);
|
||||
|
||||
if (asleep) {
|
||||
thread_state_awake (thr);
|
||||
}
|
||||
|
||||
os_mutexLock (&((dds_writer*)e)->m_call_lock);
|
||||
if (qos->ownership_strength.value != ddsi_wr->xqos->ownership_strength.value) {
|
||||
ddsi_wr->xqos->ownership_strength.value = qos->ownership_strength.value;
|
||||
}
|
||||
os_mutexUnlock (&((dds_writer*)e)->m_call_lock);
|
||||
|
||||
if (asleep) {
|
||||
thread_state_asleep (thr);
|
||||
}
|
||||
} else {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR, "Setting ownership strength doesn't make sense when the ownership is shared.");
|
||||
}
|
||||
} else {
|
||||
if (enabled) {
|
||||
ret = DDS_ERRNO(DDS_RETCODE_UNSUPPORTED, DDSC_PROJECT_NAME" does not support changing QoS policies yet");
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
_Pre_satisfies_(((participant_or_publisher & DDS_ENTITY_KIND_MASK) == DDS_KIND_PUBLISHER) || \
|
||||
((participant_or_publisher & DDS_ENTITY_KIND_MASK) == DDS_KIND_PARTICIPANT))
|
||||
_Pre_satisfies_((topic & DDS_ENTITY_KIND_MASK) == DDS_KIND_TOPIC)
|
||||
dds_entity_t
|
||||
dds_create_writer(
|
||||
_In_ dds_entity_t participant_or_publisher,
|
||||
_In_ dds_entity_t topic,
|
||||
_In_opt_ const dds_qos_t *qos,
|
||||
_In_opt_ const dds_listener_t *listener)
|
||||
{
|
||||
dds__retcode_t rc;
|
||||
dds_qos_t * wqos;
|
||||
dds_writer * wr;
|
||||
dds_entity_t writer;
|
||||
dds_entity * pub = NULL;
|
||||
dds_entity * tp;
|
||||
dds_entity_t publisher;
|
||||
struct thread_state1 * const thr = lookup_thread_state();
|
||||
const bool asleep = !vtime_awake_p(thr->vtime);
|
||||
ddsi_tran_conn_t conn = gv.data_conn_mc ? gv.data_conn_mc : gv.data_conn_uc;
|
||||
dds_return_t ret;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
/* Try claiming a participant. If that's not working, then it could be a subscriber. */
|
||||
if(dds_entity_kind(participant_or_publisher) == DDS_KIND_PARTICIPANT){
|
||||
publisher = dds_create_publisher(participant_or_publisher, qos, NULL);
|
||||
} else{
|
||||
publisher = participant_or_publisher;
|
||||
}
|
||||
rc = dds_entity_lock(publisher, DDS_KIND_PUBLISHER, &pub);
|
||||
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
writer = DDS_ERRNO(rc, "Error occurred on locking publisher");
|
||||
goto err_pub_lock;
|
||||
}
|
||||
|
||||
if (publisher != participant_or_publisher) {
|
||||
pub->m_flags |= DDS_ENTITY_IMPLICIT;
|
||||
}
|
||||
|
||||
rc = dds_entity_lock(topic, DDS_KIND_TOPIC, &tp);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
writer = DDS_ERRNO(rc, "Error occurred on locking topic");
|
||||
goto err_tp_lock;
|
||||
}
|
||||
assert(((dds_topic*)tp)->m_stopic);
|
||||
assert(pub->m_domain == tp->m_domain);
|
||||
|
||||
/* Merge Topic & Publisher qos */
|
||||
wqos = dds_qos_create();
|
||||
if (qos) {
|
||||
/* Only returns failure when one of the qos args is NULL, which
|
||||
* is not the case here. */
|
||||
(void)dds_qos_copy(wqos, qos);
|
||||
}
|
||||
|
||||
if (pub->m_qos) {
|
||||
dds_qos_merge(wqos, pub->m_qos);
|
||||
}
|
||||
|
||||
if (tp->m_qos) {
|
||||
/* merge topic qos data to writer qos */
|
||||
dds_qos_merge(wqos, tp->m_qos);
|
||||
}
|
||||
nn_xqos_mergein_missing(wqos, &gv.default_xqos_wr);
|
||||
|
||||
ret = dds_writer_qos_validate(wqos, false);
|
||||
if (ret != 0) {
|
||||
dds_qos_delete(wqos);
|
||||
writer = ret;
|
||||
goto err_bad_qos;
|
||||
}
|
||||
|
||||
/* Create writer */
|
||||
wr = dds_alloc(sizeof (*wr));
|
||||
writer = dds_entity_init(&wr->m_entity, pub, DDS_KIND_WRITER, wqos, listener, DDS_WRITER_STATUS_MASK);
|
||||
|
||||
wr->m_topic = (dds_topic*)tp;
|
||||
dds_entity_add_ref_nolock(tp);
|
||||
wr->m_xp = nn_xpack_new(conn, get_bandwidth_limit(wqos->transport_priority), config.xpack_send_async);
|
||||
os_mutexInit (&wr->m_call_lock);
|
||||
wr->m_entity.m_deriver.close = dds_writer_close;
|
||||
wr->m_entity.m_deriver.delete = dds_writer_delete;
|
||||
wr->m_entity.m_deriver.set_qos = dds_writer_qos_set;
|
||||
wr->m_entity.m_deriver.validate_status = dds_writer_status_validate;
|
||||
wr->m_entity.m_deriver.get_instance_hdl = dds_writer_instance_hdl;
|
||||
|
||||
/* Extra claim of this writer to make sure that the delete waits until DDSI
|
||||
* has deleted its writer as well. This can be known through the callback. */
|
||||
if (ut_handle_claim(wr->m_entity.m_hdl, wr->m_entity.m_hdllink, DDS_KIND_WRITER, NULL) != UT_HANDLE_OK) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
os_mutexUnlock(&tp->m_mutex);
|
||||
os_mutexUnlock(&pub->m_mutex);
|
||||
|
||||
if (asleep) {
|
||||
thread_state_awake(thr);
|
||||
}
|
||||
wr->m_wr = new_writer(&wr->m_entity.m_guid, NULL, &pub->m_participant->m_guid, ((dds_topic*)tp)->m_stopic,
|
||||
wqos, dds_writer_status_cb, wr);
|
||||
os_mutexLock(&pub->m_mutex);
|
||||
os_mutexLock(&tp->m_mutex);
|
||||
assert(wr->m_wr);
|
||||
if (asleep) {
|
||||
thread_state_asleep(thr);
|
||||
}
|
||||
dds_entity_unlock(tp);
|
||||
dds_entity_unlock(pub);
|
||||
DDS_REPORT_FLUSH(writer <= 0);
|
||||
return writer;
|
||||
|
||||
err_bad_qos:
|
||||
dds_entity_unlock(tp);
|
||||
err_tp_lock:
|
||||
dds_entity_unlock(pub);
|
||||
if((pub->m_flags & DDS_ENTITY_IMPLICIT) != 0){
|
||||
(void)dds_delete(publisher);
|
||||
}
|
||||
err_pub_lock:
|
||||
DDS_REPORT_FLUSH(writer <= 0);
|
||||
return writer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
_Pre_satisfies_(((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER))
|
||||
dds_entity_t
|
||||
dds_get_publisher(
|
||||
_In_ dds_entity_t writer)
|
||||
{
|
||||
dds_entity_t hdl = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
hdl = dds_valid_hdl(writer, DDS_KIND_WRITER);
|
||||
if(hdl != DDS_RETCODE_OK){
|
||||
hdl = DDS_ERRNO(hdl, "Provided handle is not writer kind, so it is not valid");
|
||||
} else{
|
||||
hdl = dds_get_parent(writer);
|
||||
}
|
||||
DDS_REPORT_FLUSH(hdl <= 0);
|
||||
return hdl;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER))
|
||||
dds_return_t
|
||||
dds_get_publication_matched_status (
|
||||
_In_ dds_entity_t writer,
|
||||
_Out_opt_ dds_publication_matched_status_t * status)
|
||||
{
|
||||
dds__retcode_t rc;
|
||||
dds_writer *wr;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_writer_lock(writer, &wr);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking writer");
|
||||
goto fail;
|
||||
}
|
||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
||||
if (status) {
|
||||
*status = wr->m_publication_matched_status;
|
||||
}
|
||||
if (((dds_entity*)wr)->m_status_enable & DDS_PUBLICATION_MATCHED_STATUS) {
|
||||
wr->m_publication_matched_status.total_count_change = 0;
|
||||
wr->m_publication_matched_status.current_count_change = 0;
|
||||
dds_entity_status_reset(wr, DDS_PUBLICATION_MATCHED_STATUS);
|
||||
}
|
||||
dds_writer_unlock(wr);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER))
|
||||
dds_return_t
|
||||
dds_get_liveliness_lost_status (
|
||||
_In_ dds_entity_t writer,
|
||||
_Out_opt_ dds_liveliness_lost_status_t * status)
|
||||
{
|
||||
dds__retcode_t rc;
|
||||
dds_writer *wr;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_writer_lock(writer, &wr);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking writer");
|
||||
goto fail;
|
||||
}
|
||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
||||
if (status) {
|
||||
*status = wr->m_liveliness_lost_status;
|
||||
}
|
||||
if (((dds_entity*)wr)->m_status_enable & DDS_LIVELINESS_LOST_STATUS) {
|
||||
wr->m_liveliness_lost_status.total_count_change = 0;
|
||||
dds_entity_status_reset(wr, DDS_LIVELINESS_LOST_STATUS);
|
||||
}
|
||||
dds_writer_unlock(wr);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER))
|
||||
dds_return_t
|
||||
dds_get_offered_deadline_missed_status(
|
||||
_In_ dds_entity_t writer,
|
||||
_Out_opt_ dds_offered_deadline_missed_status_t *status)
|
||||
{
|
||||
dds__retcode_t rc;
|
||||
dds_writer *wr;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_writer_lock(writer, &wr);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking writer");
|
||||
goto fail;
|
||||
}
|
||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
||||
if (status) {
|
||||
*status = wr->m_offered_deadline_missed_status;
|
||||
}
|
||||
if (((dds_entity*)wr)->m_status_enable & DDS_OFFERED_DEADLINE_MISSED_STATUS) {
|
||||
wr->m_offered_deadline_missed_status.total_count_change = 0;
|
||||
dds_entity_status_reset(wr, DDS_OFFERED_DEADLINE_MISSED_STATUS);
|
||||
}
|
||||
dds_writer_unlock(wr);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_Pre_satisfies_(((writer & DDS_ENTITY_KIND_MASK) == DDS_KIND_WRITER))
|
||||
dds_return_t
|
||||
dds_get_offered_incompatible_qos_status (
|
||||
_In_ dds_entity_t writer,
|
||||
_Out_opt_ dds_offered_incompatible_qos_status_t * status)
|
||||
{
|
||||
dds__retcode_t rc;
|
||||
dds_writer *wr;
|
||||
dds_return_t ret = DDS_RETCODE_OK;
|
||||
|
||||
DDS_REPORT_STACK();
|
||||
|
||||
rc = dds_writer_lock(writer, &wr);
|
||||
if (rc != DDS_RETCODE_OK) {
|
||||
ret = DDS_ERRNO(rc, "Error occurred on locking writer");
|
||||
goto fail;
|
||||
}
|
||||
/* status = NULL, application do not need the status, but reset the counter & triggered bit */
|
||||
if (status) {
|
||||
*status = wr->m_offered_incompatible_qos_status;
|
||||
}
|
||||
if (((dds_entity*)wr)->m_status_enable & DDS_OFFERED_INCOMPATIBLE_QOS_STATUS) {
|
||||
wr->m_offered_incompatible_qos_status.total_count_change = 0;
|
||||
dds_entity_status_reset(wr, DDS_OFFERED_INCOMPATIBLE_QOS_STATUS);
|
||||
}
|
||||
dds_writer_unlock(wr);
|
||||
fail:
|
||||
DDS_REPORT_FLUSH(ret != DDS_RETCODE_OK);
|
||||
return ret;
|
||||
}
|
||||
39
src/core/ddsc/src/q__osplser.h
Normal file
39
src/core/ddsc/src/q__osplser.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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 DDS_OSPLSER_H
|
||||
#define DDS_OSPLSER_H
|
||||
|
||||
#include "ddsi/ddsi_ser.h"
|
||||
#include "ddsi/q_xmsg.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int serdata_cmp (const struct serdata * a, const struct serdata * b);
|
||||
uint32_t serdata_hash (const struct serdata *a);
|
||||
|
||||
serdata_t serialize (serstatepool_t pool, const struct sertopic * tp, const void * sample);
|
||||
serdata_t serialize_key (serstatepool_t pool, const struct sertopic * tp, const void * sample);
|
||||
|
||||
void deserialize_into (void *sample, const struct serdata *serdata);
|
||||
void free_deserialized (const struct serdata *serdata, void *vx);
|
||||
|
||||
void sertopic_free (struct sertopic * tp);
|
||||
void serstate_set_key (serstate_t st, int justkey, const void *key);
|
||||
void serstate_init (serstate_t st, const struct sertopic * topic);
|
||||
void serstate_free (serstate_t st);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
153
src/core/ddsc/src/q_osplser.c
Normal file
153
src/core/ddsc/src/q_osplser.c
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
#include "os/os.h"
|
||||
#include "dds__key.h"
|
||||
#include "dds__tkmap.h"
|
||||
#include "dds__stream.h"
|
||||
#include "ddsi/q_bswap.h"
|
||||
#include "q__osplser.h"
|
||||
|
||||
serdata_t serialize (serstatepool_t pool, const struct sertopic * tp, const void * sample)
|
||||
{
|
||||
dds_stream_t os;
|
||||
serstate_t st = ddsi_serstate_new (pool, tp);
|
||||
|
||||
if (tp->nkeys)
|
||||
{
|
||||
dds_key_gen ((const dds_topic_descriptor_t*) tp->type, &st->data->v.keyhash, (char*) sample);
|
||||
}
|
||||
dds_stream_from_serstate (&os, st);
|
||||
dds_stream_write_sample (&os, sample, tp);
|
||||
dds_stream_add_to_serstate (&os, st);
|
||||
return st->data;
|
||||
}
|
||||
|
||||
int serdata_cmp (const struct serdata *a, const struct serdata *b)
|
||||
{
|
||||
/* First compare on topic */
|
||||
|
||||
if (a->v.st->topic != b->v.st->topic)
|
||||
{
|
||||
return a->v.st->topic < b->v.st->topic ? -1 : 1;
|
||||
}
|
||||
|
||||
/* Samples with a keyless topic map to the default instance */
|
||||
|
||||
if
|
||||
(
|
||||
(a->v.st->topic) &&
|
||||
(((dds_topic_descriptor_t*) a->v.st->topic->type)->m_keys == 0)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check key has been hashed */
|
||||
|
||||
assert (a->v.keyhash.m_flags & DDS_KEY_HASH_SET);
|
||||
|
||||
/* Compare by hash */
|
||||
|
||||
return memcmp (a->v.keyhash.m_hash, b->v.keyhash.m_hash, 16);
|
||||
}
|
||||
|
||||
serdata_t serialize_key (serstatepool_t pool, const struct sertopic * tp, const void * sample)
|
||||
{
|
||||
serdata_t sd;
|
||||
if (tp->nkeys)
|
||||
{
|
||||
dds_stream_t os;
|
||||
dds_topic_descriptor_t * desc = (dds_topic_descriptor_t*) tp->type;
|
||||
serstate_t st = ddsi_serstate_new (pool, tp);
|
||||
dds_key_gen (desc, &st->data->v.keyhash, (char*) sample);
|
||||
dds_stream_from_serstate (&os, st);
|
||||
dds_stream_write_key (&os, sample, desc);
|
||||
dds_stream_add_to_serstate (&os, st);
|
||||
sd = st->data;
|
||||
}
|
||||
else
|
||||
{
|
||||
sd = serialize (pool, tp, sample);
|
||||
}
|
||||
sd->v.st->kind = STK_KEY;
|
||||
return sd;
|
||||
}
|
||||
|
||||
void deserialize_into (void * sample, const struct serdata * serdata)
|
||||
{
|
||||
const serstate_t st = serdata->v.st;
|
||||
dds_stream_t is;
|
||||
|
||||
dds_stream_from_serstate (&is, st);
|
||||
if (st->kind == STK_KEY)
|
||||
{
|
||||
dds_stream_read_key (&is, sample, (const dds_topic_descriptor_t*) st->topic->type);
|
||||
}
|
||||
else
|
||||
{
|
||||
dds_stream_read_sample (&is, sample, st->topic);
|
||||
}
|
||||
}
|
||||
|
||||
void serstate_set_key (serstate_t st, int justkey, const void *key)
|
||||
{
|
||||
st->kind = justkey ? STK_KEY : STK_DATA;
|
||||
memcpy (&st->data->v.keyhash.m_hash, key, 16);
|
||||
st->data->v.keyhash.m_flags = DDS_KEY_SET | DDS_KEY_HASH_SET | DDS_KEY_IS_HASH;
|
||||
st->data->v.keyhash.m_key_len = 16;
|
||||
}
|
||||
|
||||
void serstate_init (serstate_t st, const struct sertopic * topic)
|
||||
{
|
||||
st->pos = 0;
|
||||
st->topic = topic;
|
||||
st->kind = STK_DATA;
|
||||
st->twrite.v = -1;
|
||||
os_atomic_st32 (&st->refcount, 1);
|
||||
|
||||
if (topic)
|
||||
{
|
||||
os_atomic_inc32 (&(((struct sertopic *) topic)->refcount));
|
||||
}
|
||||
|
||||
st->data->hdr.identifier = topic ?
|
||||
(PLATFORM_IS_LITTLE_ENDIAN ? CDR_LE : CDR_BE) :
|
||||
(PLATFORM_IS_LITTLE_ENDIAN ? PL_CDR_LE : PL_CDR_BE);
|
||||
|
||||
st->data->v.hash_valid = (topic == NULL || topic->nkeys) ? 0 : 1;
|
||||
st->data->v.hash = 0;
|
||||
st->data->v.bswap = false;
|
||||
memset (st->data->v.keyhash.m_hash, 0, sizeof (st->data->v.keyhash.m_hash));
|
||||
st->data->v.keyhash.m_key_len = 0;
|
||||
st->data->v.keyhash.m_flags = 0;
|
||||
}
|
||||
|
||||
void serstate_free (serstate_t st)
|
||||
{
|
||||
dds_free (st->data->v.keyhash.m_key_buff);
|
||||
dds_free (st->data);
|
||||
dds_free (st);
|
||||
}
|
||||
|
||||
void sertopic_free (struct sertopic * tp)
|
||||
{
|
||||
if (tp && (os_atomic_dec32_nv (&tp->refcount) == 0))
|
||||
{
|
||||
dds_free (tp->name);
|
||||
dds_free (tp->typename);
|
||||
dds_free (tp->name_typename);
|
||||
dds_sample_free (tp->filter_sample, (const struct dds_topic_descriptor *) tp->type, DDS_FREE_ALL);
|
||||
dds_free (tp);
|
||||
}
|
||||
}
|
||||
33
src/core/ddsc/tests/CMakeLists.txt
Normal file
33
src/core/ddsc/tests/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# 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(Criterion)
|
||||
|
||||
idlc_generate(RoundTrip RoundTrip.idl)
|
||||
idlc_generate(Space Space.idl)
|
||||
idlc_generate(TypesArrayKey TypesArrayKey.idl)
|
||||
add_criterion_executable(criterion_ddsc .)
|
||||
target_include_directories(criterion_ddsc PRIVATE
|
||||
"$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/src/include/>")
|
||||
target_link_libraries(criterion_ddsc RoundTrip Space TypesArrayKey ddsc OSAPI)
|
||||
|
||||
# Setup environment for config-tests
|
||||
set(Criterion_ddsc_config_simple_udp_file "${CMAKE_CURRENT_LIST_DIR}/config_simple_udp.xml")
|
||||
set(Criterion_ddsc_config_simple_udp_uri "file://${Criterion_ddsc_config_simple_udp_file}")
|
||||
set(Criterion_ddsc_config_simple_udp_max_participants "0")
|
||||
set_tests_properties(
|
||||
Criterion_ddsc_config_simple_udp
|
||||
PROPERTIES
|
||||
REQUIRED_FILES ${Criterion_ddsc_config_simple_udp_file}
|
||||
ENVIRONMENT "${CMAKE_PROJECT_NAME_CAPS}_URI=${Criterion_ddsc_config_simple_udp_uri};MAX_PARTICIPANTS=${Criterion_ddsc_config_simple_udp_max_participants}"
|
||||
|
||||
)
|
||||
configure_file("config_env.h.in" "config_env.h")
|
||||
26
src/core/ddsc/tests/RoundTrip.idl
Normal file
26
src/core/ddsc/tests/RoundTrip.idl
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
module RoundTripModule
|
||||
{
|
||||
struct DataType
|
||||
{
|
||||
sequence<octet> payload;
|
||||
};
|
||||
#pragma keylist DataType
|
||||
|
||||
struct Address
|
||||
{
|
||||
string ip;
|
||||
long port;
|
||||
};
|
||||
#pragma keylist Address ip port
|
||||
};
|
||||
40
src/core/ddsc/tests/Space.idl
Normal file
40
src/core/ddsc/tests/Space.idl
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
module Space {
|
||||
struct Type1 {
|
||||
long long_1; //@Key
|
||||
long long_2;
|
||||
long long_3;
|
||||
};
|
||||
#pragma keylist Type1 long_1
|
||||
struct Type2 {
|
||||
long long_1; //@Key
|
||||
long long_2;
|
||||
long long_3;
|
||||
};
|
||||
#pragma keylist Type2 long_1
|
||||
|
||||
struct simpletypes {
|
||||
long l;
|
||||
long long ll;
|
||||
unsigned short us;
|
||||
unsigned long ul;
|
||||
unsigned long long ull;
|
||||
float f;
|
||||
double d;
|
||||
char c;
|
||||
boolean b;
|
||||
octet o;
|
||||
string s; //@Key
|
||||
};
|
||||
#pragma keylist simpletypes s
|
||||
};
|
||||
81
src/core/ddsc/tests/TypesArrayKey.idl
Normal file
81
src/core/ddsc/tests/TypesArrayKey.idl
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
module TypesArrayKey {
|
||||
struct long_arraytypekey {
|
||||
long key[20]; //@Key
|
||||
};
|
||||
#pragma keylist long_arraytypekey key
|
||||
|
||||
typedef long long longlong;
|
||||
struct longlong_arraytypekey {
|
||||
longlong key[20]; //@Key
|
||||
};
|
||||
#pragma keylist longlong_arraytypekey key
|
||||
|
||||
typedef unsigned short unsignedshort;
|
||||
struct unsignedshort_arraytypekey {
|
||||
unsignedshort key[20]; //@Key
|
||||
};
|
||||
#pragma keylist unsignedshort_arraytypekey key
|
||||
|
||||
typedef unsigned long unsignedlong;
|
||||
struct unsignedlong_arraytypekey {
|
||||
unsignedlong key[20]; //@Key
|
||||
};
|
||||
#pragma keylist unsignedlong_arraytypekey key
|
||||
|
||||
typedef unsigned long long unsignedlonglong;
|
||||
struct unsignedlonglong_arraytypekey {
|
||||
unsignedlonglong key[20]; //@Key
|
||||
};
|
||||
#pragma keylist unsignedlonglong_arraytypekey key
|
||||
|
||||
struct float_arraytypekey {
|
||||
float key[20]; //@Key
|
||||
};
|
||||
#pragma keylist float_arraytypekey key
|
||||
|
||||
struct double_arraytypekey {
|
||||
double key[20]; //@Key
|
||||
};
|
||||
#pragma keylist double_arraytypekey key
|
||||
|
||||
struct char_arraytypekey {
|
||||
char key[128]; //@Key
|
||||
};
|
||||
#pragma keylist char_arraytypekey key
|
||||
|
||||
struct boolean_arraytypekey {
|
||||
boolean key[128]; //@Key
|
||||
};
|
||||
#pragma keylist boolean_arraytypekey key
|
||||
|
||||
struct octet_arraytypekey {
|
||||
octet key[128]; //@Key
|
||||
};
|
||||
#pragma keylist octet_arraytypekey key
|
||||
|
||||
struct alltypeskey {
|
||||
long l;
|
||||
long long ll;
|
||||
unsigned short us;
|
||||
unsigned long ul;
|
||||
unsigned long long ull;
|
||||
float f;
|
||||
double d;
|
||||
char c;
|
||||
boolean b;
|
||||
octet o;
|
||||
string s; //@Key
|
||||
};
|
||||
#pragma keylist alltypeskey l ll us ul ull f d c b o s
|
||||
};
|
||||
28
src/core/ddsc/tests/basic.c
Normal file
28
src/core/ddsc/tests/basic.c
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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 "ddsc/dds.h"
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/logging.h>
|
||||
|
||||
Test(ddsc_basic, test)
|
||||
{
|
||||
dds_entity_t participant;
|
||||
dds_return_t status;
|
||||
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0);
|
||||
|
||||
/* TODO: CHAM-108: Add some simple read/write test(s). */
|
||||
|
||||
status = dds_delete(participant);
|
||||
cr_assert_eq(status, DDS_RETCODE_OK);
|
||||
}
|
||||
842
src/core/ddsc/tests/builtin_topics.c
Executable file
842
src/core/ddsc/tests/builtin_topics.c
Executable file
|
|
@ -0,0 +1,842 @@
|
|||
/*
|
||||
* 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 "RoundTrip.h"
|
||||
#include "Space.h"
|
||||
#include "ddsc/dds.h"
|
||||
#include "os/os.h"
|
||||
#include "test-common.h"
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/logging.h>
|
||||
|
||||
static dds_entity_t g_participant = 0;
|
||||
static dds_entity_t g_subscriber = 0;
|
||||
static dds_entity_t g_publisher = 0;
|
||||
static dds_entity_t g_topic = 0;
|
||||
|
||||
#define MAX_SAMPLES 1
|
||||
|
||||
static dds_sample_info_t g_info[MAX_SAMPLES];
|
||||
|
||||
static struct DDS_UserDataQosPolicy g_pol_userdata;
|
||||
static struct DDS_TopicDataQosPolicy g_pol_topicdata;
|
||||
static struct DDS_GroupDataQosPolicy g_pol_groupdata;
|
||||
static struct DDS_DurabilityQosPolicy g_pol_durability;
|
||||
static struct DDS_HistoryQosPolicy g_pol_history;
|
||||
static struct DDS_ResourceLimitsQosPolicy g_pol_resource_limits;
|
||||
static struct DDS_PresentationQosPolicy g_pol_presentation;
|
||||
static struct DDS_LifespanQosPolicy g_pol_lifespan;
|
||||
static struct DDS_DeadlineQosPolicy g_pol_deadline;
|
||||
static struct DDS_LatencyBudgetQosPolicy g_pol_latency_budget;
|
||||
static struct DDS_OwnershipQosPolicy g_pol_ownership;
|
||||
static struct DDS_OwnershipStrengthQosPolicy g_pol_ownership_strength;
|
||||
static struct DDS_LivelinessQosPolicy g_pol_liveliness;
|
||||
static struct DDS_TimeBasedFilterQosPolicy g_pol_time_based_filter;
|
||||
static struct DDS_PartitionQosPolicy g_pol_partition;
|
||||
static struct DDS_ReliabilityQosPolicy g_pol_reliability;
|
||||
static struct DDS_TransportPriorityQosPolicy g_pol_transport_priority;
|
||||
static struct DDS_DestinationOrderQosPolicy g_pol_destination_order;
|
||||
static struct DDS_WriterDataLifecycleQosPolicy g_pol_writer_data_lifecycle;
|
||||
static struct DDS_ReaderDataLifecycleQosPolicy g_pol_reader_data_lifecycle;
|
||||
static struct DDS_DurabilityServiceQosPolicy g_pol_durability_service;
|
||||
|
||||
static const char* c_userdata = "user_key";
|
||||
static const char* c_topicdata = "topic_key";
|
||||
static const char* c_groupdata = "group_key";
|
||||
static const char* c_partitions[] = {"Partition1", "Partition2"};
|
||||
|
||||
static dds_qos_t *g_qos = NULL;
|
||||
|
||||
static void
|
||||
qos_init(void)
|
||||
{
|
||||
g_qos = dds_qos_create();
|
||||
cr_assert_not_null(g_qos);
|
||||
|
||||
g_pol_userdata.value._buffer = dds_alloc(strlen(c_userdata) + 1);
|
||||
g_pol_userdata.value._length = (uint32_t)strlen(c_userdata) + 1;
|
||||
g_pol_userdata.value._release = true;
|
||||
g_pol_userdata.value._maximum = 0;
|
||||
|
||||
g_pol_topicdata.value._buffer = dds_alloc(strlen(c_topicdata) + 1);
|
||||
g_pol_topicdata.value._length = (uint32_t)strlen(c_topicdata) + 1;
|
||||
g_pol_topicdata.value._release = true;
|
||||
g_pol_topicdata.value._maximum = 0;
|
||||
|
||||
g_pol_groupdata.value._buffer = dds_alloc(strlen(c_groupdata) + 1);
|
||||
g_pol_groupdata.value._length = (uint32_t)strlen(c_groupdata) + 1;
|
||||
g_pol_groupdata.value._release = true;
|
||||
g_pol_groupdata.value._maximum = 0;
|
||||
|
||||
g_pol_history.kind = DDS_KEEP_LAST_HISTORY_QOS;
|
||||
g_pol_history.depth = 1;
|
||||
|
||||
g_pol_resource_limits.max_samples = 1;
|
||||
g_pol_resource_limits.max_instances = 1;
|
||||
g_pol_resource_limits.max_samples_per_instance = 1;
|
||||
|
||||
g_pol_presentation.access_scope = DDS_INSTANCE_PRESENTATION_QOS;
|
||||
g_pol_presentation.coherent_access = true;
|
||||
g_pol_presentation.ordered_access = true;
|
||||
|
||||
g_pol_lifespan.duration.sec = 10000;
|
||||
g_pol_lifespan.duration.nanosec = 11000;
|
||||
|
||||
g_pol_deadline.period.sec = 20000;
|
||||
g_pol_deadline.period.nanosec = 220000;
|
||||
|
||||
g_pol_latency_budget.duration.sec = 30000;
|
||||
g_pol_latency_budget.duration.nanosec = 33000;
|
||||
|
||||
g_pol_ownership.kind = DDS_EXCLUSIVE_OWNERSHIP_QOS;
|
||||
|
||||
g_pol_ownership_strength.value = 10;
|
||||
|
||||
g_pol_liveliness.kind = DDS_AUTOMATIC_LIVELINESS_QOS;
|
||||
g_pol_liveliness.lease_duration.sec = 40000;
|
||||
g_pol_liveliness.lease_duration.nanosec = 44000;
|
||||
|
||||
g_pol_time_based_filter.minimum_separation.sec = 50000;
|
||||
g_pol_time_based_filter.minimum_separation.nanosec = 55000;
|
||||
|
||||
g_pol_partition.name._buffer = (char**)c_partitions;
|
||||
g_pol_partition.name._length = 2;
|
||||
|
||||
g_pol_reliability.kind = DDS_RELIABLE_RELIABILITY_QOS;
|
||||
g_pol_reliability.max_blocking_time.sec = 60000;
|
||||
g_pol_reliability.max_blocking_time.nanosec = 66000;
|
||||
|
||||
g_pol_transport_priority.value = 42;
|
||||
|
||||
g_pol_destination_order.kind = DDS_BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS;
|
||||
|
||||
g_pol_writer_data_lifecycle.autodispose_unregistered_instances = true;
|
||||
|
||||
g_pol_reader_data_lifecycle.autopurge_disposed_samples_delay.sec = 70000;
|
||||
g_pol_reader_data_lifecycle.autopurge_disposed_samples_delay.nanosec= 77000;
|
||||
g_pol_reader_data_lifecycle.autopurge_nowriter_samples_delay.sec = 80000;
|
||||
g_pol_reader_data_lifecycle.autopurge_nowriter_samples_delay.nanosec = 88000;
|
||||
|
||||
g_pol_durability_service.history_depth = 1;
|
||||
g_pol_durability_service.history_kind = DDS_KEEP_LAST_HISTORY_QOS;
|
||||
g_pol_durability_service.max_samples = 2;
|
||||
g_pol_durability_service.max_instances = 3;
|
||||
g_pol_durability_service.max_samples_per_instance = 4;
|
||||
g_pol_durability_service.service_cleanup_delay.sec = 90000;
|
||||
g_pol_durability_service.service_cleanup_delay.nanosec = 99000;
|
||||
}
|
||||
|
||||
static void
|
||||
qos_fini(void)
|
||||
{
|
||||
dds_qos_delete(g_qos);
|
||||
dds_free(g_pol_userdata.value._buffer);
|
||||
dds_free(g_pol_groupdata.value._buffer);
|
||||
dds_free(g_pol_topicdata.value._buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
setup(void)
|
||||
{
|
||||
qos_init();
|
||||
|
||||
g_participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(g_participant, 0, "Failed to create prerequisite g_participant");
|
||||
g_topic = dds_create_topic(g_participant, &RoundTripModule_DataType_desc, "RoundTrip", NULL, NULL);
|
||||
cr_assert_gt(g_topic, 0, "Failed to create prerequisite g_topic");
|
||||
g_subscriber = dds_create_subscriber(g_participant, NULL, NULL);
|
||||
cr_assert_gt(g_subscriber, 0, "Failed to create prerequisite g_subscriber");
|
||||
g_publisher = dds_create_publisher(g_participant, NULL, NULL);
|
||||
cr_assert_gt(g_publisher, 0, "Failed to create prerequisite g_publisher");
|
||||
}
|
||||
|
||||
static void
|
||||
teardown(void)
|
||||
{
|
||||
qos_fini();
|
||||
dds_delete(g_participant);
|
||||
}
|
||||
#define T_MILLISECOND 1000000ll
|
||||
#define T_SECOND (1000 * T_MILLISECOND)
|
||||
|
||||
int64_t from_ddsi_duration (DDS_Duration_t x)
|
||||
{
|
||||
int64_t t;
|
||||
t = x.sec * 10^9 + x.nanosec;
|
||||
return t;
|
||||
}
|
||||
|
||||
static void
|
||||
check_default_qos_of_builtin_entity(dds_entity_t entity)
|
||||
{
|
||||
dds_return_t ret;
|
||||
int64_t deadline;
|
||||
int64_t liveliness_lease_duration;
|
||||
int64_t minimum_separation;
|
||||
int64_t max_blocking_time;
|
||||
int64_t autopurge_nowriter_samples_delay;
|
||||
int64_t autopurge_disposed_samples_delay;
|
||||
|
||||
dds_durability_kind_t durability_kind;
|
||||
dds_presentation_access_scope_kind_t presentation_access_scope_kind;
|
||||
dds_ownership_kind_t ownership_kind;
|
||||
dds_liveliness_kind_t liveliness_kind;
|
||||
dds_reliability_kind_t reliability_kind;
|
||||
dds_destination_order_kind_t destination_order_kind;
|
||||
dds_history_kind_t history_kind;
|
||||
|
||||
char **partitions;
|
||||
uint32_t plen;
|
||||
|
||||
dds_qos_t *qos = dds_qos_create();
|
||||
cr_assert_not_null(qos);
|
||||
|
||||
ret = dds_get_qos(entity, qos);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed to get QOS of builtin entity");
|
||||
|
||||
dds_qget_durability(qos, &durability_kind);
|
||||
dds_qget_presentation(qos, &presentation_access_scope_kind, &g_pol_presentation.coherent_access, &g_pol_presentation.ordered_access);
|
||||
dds_qget_deadline(qos, &deadline);
|
||||
dds_qget_ownership(qos, &ownership_kind);
|
||||
dds_qget_liveliness(qos, &liveliness_kind, &liveliness_lease_duration);
|
||||
dds_qget_time_based_filter(qos, &minimum_separation);
|
||||
dds_qget_reliability(qos, &reliability_kind, &max_blocking_time);
|
||||
dds_qget_destination_order(qos, &destination_order_kind);
|
||||
dds_qget_history(qos, &history_kind, &g_pol_history.depth);
|
||||
dds_qget_resource_limits(qos, &g_pol_resource_limits.max_samples, &g_pol_resource_limits.max_instances, &g_pol_resource_limits.max_samples_per_instance);
|
||||
dds_qget_reader_data_lifecycle(qos, &autopurge_nowriter_samples_delay, &autopurge_disposed_samples_delay);
|
||||
dds_qget_partition(qos, &plen, &partitions);
|
||||
// no getter for ENTITY_FACTORY
|
||||
|
||||
if ((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_SUBSCRIBER) {
|
||||
cr_expect_eq(plen, 1);
|
||||
if (plen > 0) {
|
||||
cr_expect_str_eq(partitions[0], "__BUILT-IN PARTITION__");
|
||||
}
|
||||
} else if ((entity & DDS_ENTITY_KIND_MASK) == DDS_KIND_READER) {
|
||||
cr_expect_eq(durability_kind, DDS_DURABILITY_TRANSIENT_LOCAL);
|
||||
cr_expect_eq(presentation_access_scope_kind, DDS_PRESENTATION_TOPIC);
|
||||
cr_expect_eq(g_pol_presentation.coherent_access, false);
|
||||
cr_expect_eq(g_pol_presentation.ordered_access, false);
|
||||
cr_expect_eq(deadline, DDS_INFINITY);
|
||||
cr_expect_eq(ownership_kind, DDS_OWNERSHIP_SHARED);
|
||||
cr_expect_eq(liveliness_kind, DDS_LIVELINESS_AUTOMATIC);
|
||||
cr_expect_eq(minimum_separation, 0);
|
||||
cr_expect_eq(reliability_kind, DDS_RELIABILITY_RELIABLE);
|
||||
cr_expect_eq(max_blocking_time, DDS_MSECS(100));
|
||||
cr_expect_eq(destination_order_kind, DDS_DESTINATIONORDER_BY_RECEPTION_TIMESTAMP);
|
||||
cr_expect_eq(history_kind, DDS_HISTORY_KEEP_LAST);
|
||||
cr_expect_eq(g_pol_history.depth, 1);
|
||||
cr_expect_eq(g_pol_resource_limits.max_instances, DDS_LENGTH_UNLIMITED);
|
||||
cr_expect_eq(g_pol_resource_limits.max_samples, DDS_LENGTH_UNLIMITED);
|
||||
cr_expect_eq(g_pol_resource_limits.max_samples_per_instance, DDS_LENGTH_UNLIMITED);
|
||||
cr_expect_eq(autopurge_nowriter_samples_delay, DDS_INFINITY);
|
||||
cr_expect_eq(autopurge_disposed_samples_delay, DDS_INFINITY);
|
||||
} else {
|
||||
cr_assert_fail("Unsupported entity kind %s", entity_kind_str(entity));
|
||||
}
|
||||
if (plen > 0) {
|
||||
for (uint32_t i = 0; i < plen; i++) {
|
||||
dds_free(partitions[i]);
|
||||
}
|
||||
dds_free(partitions);
|
||||
}
|
||||
dds_qos_delete(qos);
|
||||
}
|
||||
|
||||
static dds_entity_t builtin_topic_handles[10];
|
||||
|
||||
Test(ddsc_builtin_topics, types_allocation)
|
||||
{
|
||||
#define TEST_ALLOC(type) do { \
|
||||
DDS_##type##BuiltinTopicData *data = DDS_##type##BuiltinTopicData__alloc(); \
|
||||
cr_expect_not_null(data, "Failed to allocate DDS_" #type "BuiltinTopicData"); \
|
||||
DDS_##type##BuiltinTopicData_free(data, DDS_FREE_ALL); \
|
||||
} while(0)
|
||||
|
||||
TEST_ALLOC(Participant);
|
||||
TEST_ALLOC(CMParticipant);
|
||||
TEST_ALLOC(Type);
|
||||
TEST_ALLOC(Topic);
|
||||
TEST_ALLOC(Publication);
|
||||
TEST_ALLOC(CMPublisher);
|
||||
TEST_ALLOC(Subscription);
|
||||
TEST_ALLOC(CMSubscriber);
|
||||
TEST_ALLOC(CMDataWriter);
|
||||
TEST_ALLOC(CMDataReader);
|
||||
#undef TEST_ALLOC
|
||||
}
|
||||
|
||||
Test(ddsc_builtin_topics, availability_builtin_topics, .init = setup, .fini = teardown)
|
||||
{
|
||||
dds_entity_t topic;
|
||||
|
||||
topic = dds_find_topic(g_participant, "DCPSParticipant");
|
||||
cr_assert_gt(topic, 0);
|
||||
dds_delete(topic);
|
||||
topic = dds_find_topic(g_participant, "DCPSTopic");
|
||||
cr_assert_lt(topic, 0);
|
||||
//TODO CHAM-347: dds_delete(topic);
|
||||
topic = dds_find_topic(g_participant, "DCPSType");
|
||||
cr_assert_lt(topic, 0);
|
||||
//TODO CHAM-347: dds_delete(topic);
|
||||
topic = dds_find_topic(g_participant, "DCPSSubscription");
|
||||
cr_assert_lt(topic, 0);
|
||||
//TODO CHAM-347: dds_delete(topic);
|
||||
topic = dds_find_topic(g_participant, "DCSPPublication");
|
||||
cr_assert_lt(topic, 0);
|
||||
//TODO CHAM-347: dds_delete(topic);
|
||||
}
|
||||
|
||||
Test(ddsc_builtin_topics, read_publication_data, .init = setup, .fini = teardown)
|
||||
{
|
||||
dds_entity_t reader;
|
||||
#if 0 /* disabled pending CHAM-347 */
|
||||
dds_return_t ret;
|
||||
DDS_PublicationBuiltinTopicData *data;
|
||||
#endif
|
||||
void *samples[MAX_SAMPLES];
|
||||
|
||||
|
||||
reader = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSPUBLICATION, NULL, NULL);
|
||||
cr_assert_gt(reader, 0, "Failed to create a data reader for DDS_BUILTIN_TOPIC_DCPSPUBLICATION.");
|
||||
|
||||
samples[0] = DDS_PublicationBuiltinTopicData__alloc();
|
||||
#if 0 /* disabled pending CHAM-347 */
|
||||
ret = dds_read(reader, samples, g_info, MAX_SAMPLES, MAX_SAMPLES);
|
||||
cr_assert_gt(ret, 0, "Failed to read samples DCPSPublication");
|
||||
|
||||
data = (DDS_PublicationBuiltinTopicData *)samples;
|
||||
cr_assert_str_eq(data->topic_name, "DCPSPublication");
|
||||
#endif
|
||||
|
||||
DDS_PublicationBuiltinTopicData_free(samples[0], DDS_FREE_ALL);
|
||||
}
|
||||
|
||||
Test(ddsc_builtin_topics, create_reader)
|
||||
{
|
||||
dds_entity_t participant;
|
||||
dds_entity_t t1;
|
||||
|
||||
/* Create a participant */
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "dds_participant_create");
|
||||
|
||||
/*
|
||||
* The topics are created by the middleware as soon as a participant
|
||||
* is created.
|
||||
*/
|
||||
#define TEST_FIND(p, t) do { \
|
||||
t1 = dds_find_topic(p, t); \
|
||||
cr_expect_gt(t1, 0, "dds_find_topic(\"" t "\") returned a valid handle"); \
|
||||
dds_delete(t1); \
|
||||
} while(0);
|
||||
|
||||
/* A builtin-topic proxy is created 'on demand' and should not exist before a reader is created for it */
|
||||
TEST_FIND(participant, "DCPSParticipant");
|
||||
TEST_FIND(participant, "CMParticipant");
|
||||
#undef TEST_FIND
|
||||
|
||||
/*
|
||||
* TODO CHAM-347: Not all builtin topics are created at the start.
|
||||
*/
|
||||
#define TEST_NOTFOUND(p, t) do { \
|
||||
t1 = dds_find_topic(p, t); \
|
||||
cr_expect_lt(t1, 0, "dds_find_topic(\"" t "\") returned a valid handle"); \
|
||||
} while(0);
|
||||
|
||||
/* A builtin-topic proxy is created 'on demand' and should not exist before a reader is created for it */
|
||||
TEST_NOTFOUND(participant, "DCPSType");
|
||||
TEST_NOTFOUND(participant, "DCPSTopic");
|
||||
TEST_NOTFOUND(participant, "DCPSPublication");
|
||||
TEST_NOTFOUND(participant, "CMPublisher");
|
||||
TEST_NOTFOUND(participant, "DCPSSubscription");
|
||||
TEST_NOTFOUND(participant, "CMSubscriber");
|
||||
TEST_NOTFOUND(participant, "CMDataWriter");
|
||||
TEST_NOTFOUND(participant, "CMDataReader");
|
||||
#undef TEST_NOTFOUND
|
||||
|
||||
/* A reader is created by providing a special builtin-topic handle */
|
||||
{
|
||||
dds_entity_t readers[10];
|
||||
dds_entity_t builtin_subscriber, s;
|
||||
|
||||
builtin_topic_handles[0] = DDS_BUILTIN_TOPIC_DCPSPARTICIPANT;
|
||||
builtin_topic_handles[1] = DDS_BUILTIN_TOPIC_CMPARTICIPANT;
|
||||
builtin_topic_handles[2] = DDS_BUILTIN_TOPIC_DCPSTYPE;
|
||||
builtin_topic_handles[3] = DDS_BUILTIN_TOPIC_DCPSTOPIC;
|
||||
builtin_topic_handles[4] = DDS_BUILTIN_TOPIC_DCPSPUBLICATION;
|
||||
builtin_topic_handles[5] = DDS_BUILTIN_TOPIC_CMPUBLISHER;
|
||||
builtin_topic_handles[6] = DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION;
|
||||
builtin_topic_handles[7] = DDS_BUILTIN_TOPIC_CMSUBSCRIBER;
|
||||
builtin_topic_handles[8] = DDS_BUILTIN_TOPIC_CMDATAWRITER;
|
||||
builtin_topic_handles[9] = DDS_BUILTIN_TOPIC_CMDATAREADER;
|
||||
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
readers[i] = dds_create_reader(participant, builtin_topic_handles[i], NULL, NULL);
|
||||
cr_expect_gt(readers[i], 0, "Failed to created reader for builtin topic handle %d", builtin_topic_handles[i]);
|
||||
|
||||
if (i == 0) {
|
||||
/* Check the parent of reader is a subscriber */
|
||||
builtin_subscriber = dds_get_parent(readers[i]);
|
||||
cr_assert_gt(builtin_subscriber, 0, "Failed to get parent of first builtin-reader (%s)", dds_err_str(builtin_subscriber));
|
||||
cr_assert_eq(builtin_subscriber & DDS_ENTITY_KIND_MASK, DDS_KIND_SUBSCRIBER, "Parent is not a subscriber");
|
||||
} else {
|
||||
/* Check the parent of reader equals parent of first reader */
|
||||
s = dds_get_parent(readers[i]);
|
||||
cr_assert_gt(s, 0, "Failed to get parent of builtin-reader (%s)", dds_err_str(s));
|
||||
cr_assert_eq(s, builtin_subscriber, "Parent subscriber of reader(%d) doesn't equal builtin-subscriber", i);
|
||||
//dds_delete(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define TEST_FOUND(p, t) do { \
|
||||
t1 = dds_find_topic(p, t); \
|
||||
cr_expect_gt(t1, 0, "dds_find_topic(\"" t "\") returned an invalid handle (%s)", dds_err_str(t1)); \
|
||||
if (t1 > 0) { \
|
||||
dds_delete(t1); \
|
||||
} \
|
||||
} while(0);
|
||||
|
||||
/* Builtin-topics proxies should now be created */
|
||||
TEST_FOUND(participant, "DCPSParticipant");
|
||||
TEST_FOUND(participant, "CMParticipant");
|
||||
TEST_FOUND(participant, "DCPSType");
|
||||
TEST_FOUND(participant, "DCPSTopic");
|
||||
TEST_FOUND(participant, "DCPSPublication");
|
||||
TEST_FOUND(participant, "CMPublisher");
|
||||
TEST_FOUND(participant, "DCPSSubscription");
|
||||
TEST_FOUND(participant, "CMSubscriber");
|
||||
TEST_FOUND(participant, "CMDataWriter");
|
||||
TEST_FOUND(participant, "CMDataReader");
|
||||
#undef TEST_FOUND
|
||||
|
||||
dds_delete(participant);
|
||||
}
|
||||
|
||||
Test(ddsc_builtin_topics, read_subscription_data, .init = setup, .fini = teardown)
|
||||
{
|
||||
dds_entity_t reader;
|
||||
#if 0 /* not supported yet */
|
||||
dds_return_t ret;
|
||||
DDS_SubscriptionBuiltinTopicData *data;
|
||||
#endif
|
||||
void * samples[MAX_SAMPLES];
|
||||
|
||||
reader = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL);
|
||||
cr_assert_gt(reader, 0, "Failed to create a data reader for DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION.");
|
||||
|
||||
samples[0] = DDS_SubscriptionBuiltinTopicData__alloc();
|
||||
|
||||
#if 0 /* not supported yet */
|
||||
ret = dds_read(reader, samples, g_info, MAX_SAMPLES, MAX_SAMPLES);
|
||||
cr_assert_gt(ret, 0, "Failed to read samples DCPSSubscription");
|
||||
|
||||
data = (DDS_SubscriptionBuiltinTopicData *)samples;
|
||||
cr_assert_str_eq(data->topic_name, "DCPSSubscription");
|
||||
#endif
|
||||
|
||||
DDS_SubscriptionBuiltinTopicData_free(samples[0], DDS_FREE_ALL);
|
||||
}
|
||||
|
||||
Test(ddsc_builtin_topics, read_participant_data, .init = setup, .fini = teardown)
|
||||
{
|
||||
dds_entity_t reader;
|
||||
dds_return_t ret;
|
||||
void * samples[MAX_SAMPLES];
|
||||
|
||||
reader = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSPARTICIPANT, NULL, NULL);
|
||||
cr_assert_gt(reader, 0, "Failed to create a data reader for DDS_BUILTIN_TOPIC_DCPSPARTICIPANT.");
|
||||
|
||||
samples[0] = DDS_ParticipantBuiltinTopicData__alloc();
|
||||
|
||||
ret = dds_read(reader, samples, g_info, MAX_SAMPLES, MAX_SAMPLES);
|
||||
cr_assert_gt(ret, 0, "Failed to read samples DCPSParticipant");
|
||||
|
||||
{
|
||||
DDS_ParticipantBuiltinTopicData *data = (DDS_ParticipantBuiltinTopicData*)samples[0];
|
||||
cr_log_info("Participant.key: %x.%x.%x\n", data->key[0], data->key[1], data->key[2]);
|
||||
cr_log_info("Participant.userdata: %s\n", data->user_data.value._buffer);
|
||||
}
|
||||
|
||||
DDS_ParticipantBuiltinTopicData_free(samples[0], DDS_FREE_ALL);
|
||||
}
|
||||
|
||||
Test(ddsc_builtin_topics, read_cmparticipant_data, .init = setup, .fini = teardown)
|
||||
{
|
||||
dds_entity_t reader;
|
||||
dds_return_t ret;
|
||||
void * samples[MAX_SAMPLES];
|
||||
|
||||
reader = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_CMPARTICIPANT, NULL, NULL);
|
||||
cr_assert_gt(reader, 0, "Failed to create a data reader for DDS_BUILTIN_TOPIC_DCPSPARTICIPANT.");
|
||||
|
||||
samples[0] = DDS_CMParticipantBuiltinTopicData__alloc();
|
||||
|
||||
ret = dds_read(reader, samples, g_info, MAX_SAMPLES, MAX_SAMPLES);
|
||||
cr_assert_gt(ret, 0, "Failed to read samples CMParticipant");
|
||||
|
||||
{
|
||||
DDS_CMParticipantBuiltinTopicData *data = (DDS_CMParticipantBuiltinTopicData*)samples[0];
|
||||
cr_log_info("CMParticipant.key: %x.%x.%x\n", data->key[0], data->key[1], data->key[2]);
|
||||
cr_log_info("CMParticipant.product: %s\n", data->product.value);
|
||||
}
|
||||
|
||||
DDS_CMParticipantBuiltinTopicData_free(samples[0], DDS_FREE_ALL);
|
||||
}
|
||||
|
||||
Test(ddsc_builtin_topics, read_topic_data, .init = setup, .fini = teardown)
|
||||
{
|
||||
dds_entity_t reader;
|
||||
#if 0 /* disabled pending CHAM-347 */
|
||||
dds_return_t ret;
|
||||
DDS_TopicBuiltinTopicData *data;
|
||||
#endif
|
||||
void * samples[MAX_SAMPLES];
|
||||
|
||||
|
||||
reader = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSTOPIC, NULL, NULL);
|
||||
cr_assert_gt(reader, 0, "Failed to create a data reader for DDS_BUILTIN_TOPIC_DCPSTOPIC.");
|
||||
|
||||
samples[0] = DDS_TopicBuiltinTopicData__alloc();
|
||||
#if 0 /* disabled pending CHAM-347 */
|
||||
ret = dds_read(reader, samples, g_info, MAX_SAMPLES, MAX_SAMPLES);
|
||||
cr_assert_gt(ret, 0, "Failed to read samples DCPSTopic");
|
||||
|
||||
data = (DDS_TopicBuiltinTopicData *)samples;
|
||||
cr_assert_str_eq(data->name, "DCPSSubscription");
|
||||
#endif
|
||||
DDS_ParticipantBuiltinTopicData_free(samples[0], DDS_FREE_ALL);
|
||||
}
|
||||
|
||||
Test(ddsc_builtin_topics, read_type_data, .init = setup, .fini = teardown)
|
||||
{
|
||||
dds_entity_t reader;
|
||||
#if 0 /* disabled pending CHAM-347 */
|
||||
dds_return_t ret;
|
||||
DDS_TypeBuiltinTopicData *data;
|
||||
#endif
|
||||
void * samples[MAX_SAMPLES];
|
||||
|
||||
reader = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSTYPE, NULL, NULL);
|
||||
cr_assert_gt(reader, 0, "Failed to create a data reader for DDS_BUILTIN_TOPIC_DCPSTYPE.");
|
||||
|
||||
samples[0] = DDS_TypeBuiltinTopicData__alloc();
|
||||
#if 0 /* disabled pending CHAM-347 */
|
||||
ret = dds_read(reader, samples, g_info, MAX_SAMPLES, MAX_SAMPLES);
|
||||
cr_assert_gt(ret, 0, "Failed to read samples DCPSType");
|
||||
|
||||
data = (DDS_TypeBuiltinTopicData *)samples;
|
||||
cr_assert_str_eq(data->name, "DCPSType");
|
||||
#endif
|
||||
DDS_TypeBuiltinTopicData_free(samples[0], DDS_FREE_ALL);
|
||||
}
|
||||
|
||||
Test(ddsc_builtin_topics, same_subscriber, .init = setup, .fini = teardown)
|
||||
{
|
||||
dds_entity_t subscription_rdr;
|
||||
dds_entity_t subscription_subscriber;
|
||||
|
||||
dds_entity_t publication_rdr;
|
||||
dds_entity_t publication_subscriber;
|
||||
|
||||
dds_entity_t participant_rdr;
|
||||
dds_entity_t participant_subscriber;
|
||||
|
||||
dds_entity_t topic_rdr;
|
||||
dds_entity_t topic_subscriber;
|
||||
|
||||
dds_entity_t type_rdr;
|
||||
dds_entity_t type_subscriber;
|
||||
|
||||
subscription_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL);
|
||||
cr_assert_gt(subscription_rdr, 0, "Failed to create a data reader for DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION.");
|
||||
subscription_subscriber = dds_get_parent(subscription_rdr);
|
||||
cr_assert_gt(subscription_subscriber, 0, "Could not find builtin subscriber for DSCPSSubscription-reader.");
|
||||
|
||||
publication_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSPUBLICATION, NULL, NULL);
|
||||
cr_assert_gt(publication_rdr, 0, "Failed to create a data reader for DDS_BUILTIN_TOPIC_DCPSPUBLICATION.");
|
||||
publication_subscriber = dds_get_parent(publication_rdr);
|
||||
cr_assert_gt(publication_subscriber, 0, "Could not find builtin subscriber for DSCPSPublication-reader.");
|
||||
|
||||
cr_assert_eq(subscription_subscriber, publication_subscriber);
|
||||
|
||||
participant_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSPARTICIPANT, NULL, NULL);
|
||||
cr_assert_gt(participant_rdr, 0, "Failed to create a data reader for DDS_BUILTIN_TOPIC_DCPSPARTICIPANT.");
|
||||
participant_subscriber = dds_get_parent(participant_rdr);
|
||||
cr_assert_gt(participant_subscriber, 0, "Could not find builtin subscriber for DSCPSParticipant-reader.");
|
||||
|
||||
cr_assert_eq(publication_subscriber, participant_subscriber);
|
||||
|
||||
topic_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSTOPIC, NULL, NULL);
|
||||
cr_assert_gt(topic_rdr, 0, "Failed to create a data reader for DDS_BUILTIN_TOPIC_DCPSTOPIC.");
|
||||
topic_subscriber = dds_get_parent(topic_rdr);
|
||||
cr_assert_gt(topic_subscriber, 0, "Could not find builtin subscriber for DSCPSTopic-reader.");
|
||||
|
||||
cr_assert_eq(participant_subscriber, topic_subscriber);
|
||||
|
||||
type_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSTYPE, NULL, NULL);
|
||||
cr_assert_gt(type_rdr, 0, "Failed to create a data reader for DDS_BUILTIN_TOPIC_DCPSTYPE.");
|
||||
type_subscriber = dds_get_parent(type_rdr);
|
||||
cr_assert_gt(type_subscriber, 0, "Could not find builtin subscriber for DSCPSType-reader.");
|
||||
|
||||
cr_assert_eq(topic_subscriber, type_subscriber);
|
||||
}
|
||||
|
||||
Test(ddsc_builtin_topics, builtin_qos, .init = setup, .fini = teardown)
|
||||
{
|
||||
dds_entity_t dds_sub_rdr;
|
||||
dds_entity_t dds_sub_subscriber;
|
||||
|
||||
dds_sub_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL);
|
||||
cr_assert_gt(dds_sub_rdr, 0, "Failed to create a data reader for DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION.");
|
||||
check_default_qos_of_builtin_entity(dds_sub_rdr);
|
||||
|
||||
dds_sub_subscriber = dds_get_parent(dds_sub_rdr);
|
||||
cr_assert_gt(dds_sub_subscriber, 0, "Could not find builtin subscriber for DSCPSSubscription-reader.");
|
||||
check_default_qos_of_builtin_entity(dds_sub_subscriber);
|
||||
}
|
||||
|
||||
Test(ddsc_builtin_topics, datareader_qos, .init = setup, .fini = teardown)
|
||||
{
|
||||
dds_entity_t rdr;
|
||||
dds_entity_t subscription_rdr;
|
||||
void * subscription_samples[MAX_SAMPLES];
|
||||
#if 0 /* disabled pending CHAM-347 */
|
||||
dds_return_t ret;
|
||||
DDS_SubscriptionBuiltinTopicData *subscription_data;
|
||||
#endif
|
||||
|
||||
// Set some qos' which differ from the default
|
||||
dds_qset_durability(g_qos, (dds_durability_kind_t)g_pol_durability.kind);
|
||||
dds_qset_deadline(g_qos, from_ddsi_duration(g_pol_deadline.period));
|
||||
dds_qset_latency_budget(g_qos, from_ddsi_duration(g_pol_latency_budget.duration));
|
||||
dds_qset_liveliness(g_qos, (dds_liveliness_kind_t)g_pol_liveliness.kind, from_ddsi_duration(g_pol_liveliness.lease_duration));
|
||||
dds_qset_reliability(g_qos, (dds_reliability_kind_t)g_pol_reliability.kind, from_ddsi_duration(g_pol_reliability.max_blocking_time));
|
||||
dds_qset_ownership(g_qos, (dds_ownership_kind_t)g_pol_ownership.kind);
|
||||
dds_qset_destination_order(g_qos, (dds_destination_order_kind_t)g_pol_destination_order.kind);
|
||||
dds_qset_userdata(g_qos, g_pol_userdata.value._buffer, g_pol_userdata.value._length);
|
||||
dds_qset_time_based_filter(g_qos, from_ddsi_duration(g_pol_time_based_filter.minimum_separation));
|
||||
dds_qset_presentation(g_qos, g_pol_presentation.access_scope, g_pol_presentation.coherent_access, g_pol_presentation.ordered_access);
|
||||
dds_qset_partition(g_qos, g_pol_partition.name._length, c_partitions);
|
||||
dds_qset_topicdata(g_qos, g_pol_topicdata.value._buffer, g_pol_topicdata.value._length);
|
||||
dds_qset_groupdata(g_qos, g_pol_groupdata.value._buffer, g_pol_groupdata.value._length);
|
||||
|
||||
rdr = dds_create_reader(g_subscriber, g_topic, g_qos, NULL);
|
||||
|
||||
subscription_samples[0] = DDS_SubscriptionBuiltinTopicData__alloc();
|
||||
|
||||
subscription_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL);
|
||||
cr_assert_gt(subscription_rdr, 0, "Failed to retrieve built-in datareader for DCPSSubscription");
|
||||
#if 0 /* disabled pending CHAM-347 */
|
||||
ret = dds_read(subscription_rdr, subscription_samples, g_info, MAX_SAMPLES, MAX_SAMPLES);
|
||||
cr_assert_gt(ret, 0, "Failed to read Subscription data");
|
||||
|
||||
// Check the QOS settings of the 'remote' qos'
|
||||
subscription_data = (DDS_SubscriptionBuiltinTopicData *)subscription_samples[0];
|
||||
|
||||
cr_assert_str_eq(subscription_data->topic_name, "RoundTrip");
|
||||
cr_assert_str_eq(subscription_data->type_name, "RoundTripModule::DataType");
|
||||
cr_assert_eq(subscription_data->durability.kind, g_pol_durability.kind);
|
||||
cr_assert_eq(subscription_data->deadline.period.sec, g_pol_deadline.period.sec);
|
||||
cr_assert_eq(subscription_data->deadline.period.nanosec, g_pol_deadline.period.nanosec);
|
||||
cr_assert_eq(subscription_data->latency_budget.duration.sec, g_pol_latency_budget.duration.sec);
|
||||
cr_assert_eq(subscription_data->latency_budget.duration.nanosec, g_pol_latency_budget.duration.nanosec);
|
||||
cr_assert_eq(subscription_data->liveliness.kind, g_pol_liveliness.kind);
|
||||
cr_assert_eq(subscription_data->liveliness.lease_duration.sec, g_pol_liveliness.lease_duration.sec);
|
||||
cr_assert_eq(subscription_data->liveliness.lease_duration.nanosec, g_pol_liveliness.lease_duration.nanosec);
|
||||
cr_assert_eq(subscription_data->reliability.kind, g_pol_reliability.kind);
|
||||
cr_assert_eq(subscription_data->reliability.max_blocking_time.sec, g_pol_reliability.max_blocking_time.sec);
|
||||
cr_assert_eq(subscription_data->reliability.max_blocking_time.nanosec, g_pol_reliability.max_blocking_time.nanosec);
|
||||
cr_assert_eq(subscription_data->ownership.kind, g_pol_ownership.kind);
|
||||
cr_assert_eq(subscription_data->destination_order.kind, g_pol_destination_order.kind);
|
||||
cr_assert_eq(subscription_data->user_data.value._buffer, g_pol_userdata.value._buffer);
|
||||
cr_assert_eq(subscription_data->user_data.value._length, g_pol_userdata.value._length);
|
||||
cr_assert_eq(subscription_data->time_based_filter.minimum_separation.sec, g_pol_time_based_filter.minimum_separation.sec);
|
||||
cr_assert_eq(subscription_data->time_based_filter.minimum_separation.nanosec, g_pol_time_based_filter.minimum_separation.nanosec);
|
||||
cr_assert_eq(subscription_data->presentation.access_scope, g_pol_presentation.access_scope);
|
||||
cr_assert_eq(subscription_data->presentation.coherent_access, g_pol_presentation.coherent_access);
|
||||
cr_assert_eq(subscription_data->presentation.ordered_access, g_pol_presentation.ordered_access);
|
||||
|
||||
cr_assert_eq(subscription_data->partition.name._length, g_pol_partition.name._length);
|
||||
for (uint32_t i = 0; i < subscription_data->partition.name._length; ++i)
|
||||
{
|
||||
cr_assert_str_eq(subscription_data->partition.name._buffer[i], c_partitions[i]);
|
||||
}
|
||||
|
||||
cr_assert_str_eq(subscription_data->topic_data.value._buffer, g_pol_topicdata.value._buffer);
|
||||
cr_assert_eq(subscription_data->topic_data.value._length, g_pol_topicdata.value._length);
|
||||
cr_assert_str_eq(subscription_data->group_data.value._buffer, g_pol_groupdata.value._buffer);
|
||||
cr_assert_eq(subscription_data->group_data.value._length, g_pol_groupdata.value._length);
|
||||
#endif
|
||||
DDS_SubscriptionBuiltinTopicData_free(subscription_samples[0], DDS_FREE_ALL);
|
||||
}
|
||||
|
||||
Test(ddsc_builtin_topics, datawriter_qos, .init = setup, .fini = teardown)
|
||||
{
|
||||
dds_entity_t wrtr;
|
||||
dds_entity_t publication_rdr;
|
||||
#if 0 /* disabled pending CHAM-347 */
|
||||
dds_return_t ret;
|
||||
DDS_PublicationBuiltinTopicData *publication_data;
|
||||
#endif
|
||||
void * publication_samples[MAX_SAMPLES];
|
||||
|
||||
|
||||
dds_qset_durability(g_qos, g_pol_durability.kind);
|
||||
dds_qset_deadline(g_qos, from_ddsi_duration(g_pol_deadline.period));
|
||||
dds_qset_latency_budget(g_qos, from_ddsi_duration(g_pol_latency_budget.duration));
|
||||
dds_qset_liveliness(g_qos, (dds_liveliness_kind_t)g_pol_liveliness.kind, from_ddsi_duration(g_pol_liveliness.lease_duration));
|
||||
dds_qset_reliability(g_qos, (dds_reliability_kind_t)g_pol_reliability.kind, from_ddsi_duration(g_pol_reliability.max_blocking_time));
|
||||
dds_qset_lifespan(g_qos, from_ddsi_duration(g_pol_lifespan.duration));
|
||||
dds_qset_destination_order(g_qos, (dds_destination_order_kind_t)g_pol_destination_order.kind);
|
||||
dds_qset_userdata(g_qos, g_pol_userdata.value._buffer, g_pol_userdata.value._length);
|
||||
dds_qset_ownership(g_qos, (dds_ownership_kind_t)g_pol_ownership.kind);
|
||||
dds_qset_ownership_strength(g_qos, g_pol_ownership_strength.value);
|
||||
dds_qset_presentation(g_qos, g_pol_presentation.access_scope, g_pol_presentation.coherent_access, g_pol_presentation.ordered_access);
|
||||
dds_qset_partition(g_qos, g_pol_partition.name._length, c_partitions);
|
||||
dds_qset_topicdata(g_qos, g_pol_topicdata.value._buffer, g_pol_topicdata.value._length);
|
||||
|
||||
wrtr = dds_create_writer(g_publisher, g_topic, g_qos, NULL);
|
||||
|
||||
publication_samples[0] = DDS_PublicationBuiltinTopicData__alloc();
|
||||
|
||||
publication_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSPUBLICATION, NULL, NULL);
|
||||
cr_assert_gt(publication_rdr, 0, "Failed to retrieve built-in datareader for DCPSPublication");
|
||||
|
||||
#if 0 /* disabled pending CHAM-347 */
|
||||
ret = dds_read(publication_rdr, publication_samples, g_info, MAX_SAMPLES, MAX_SAMPLES);
|
||||
cr_assert_gt(ret, 0, "Failed to read Publication data");
|
||||
|
||||
// Check the QOS settings of the 'remote' qos'
|
||||
publication_data = (DDS_PublicationBuiltinTopicData *)publication_samples[0];
|
||||
|
||||
cr_assert_str_eq(publication_data->topic_name, "RoundTrip");
|
||||
cr_assert_str_eq(publication_data->type_name, "RoundTripModule::DataType");
|
||||
cr_assert_eq(publication_data->durability.kind, g_pol_durability.kind);
|
||||
cr_assert_eq(publication_data->deadline.period.sec, g_pol_deadline.period.sec);
|
||||
cr_assert_eq(publication_data->deadline.period.nanosec, g_pol_deadline.period.nanosec);
|
||||
cr_assert_eq(publication_data->latency_budget.duration.sec, g_pol_latency_budget.duration.sec);
|
||||
cr_assert_eq(publication_data->latency_budget.duration.nanosec, g_pol_latency_budget.duration.nanosec);
|
||||
cr_assert_eq(publication_data->liveliness.kind, g_pol_liveliness.kind);
|
||||
cr_assert_eq(publication_data->liveliness.lease_duration.sec, g_pol_liveliness.lease_duration.sec);
|
||||
cr_assert_eq(publication_data->liveliness.lease_duration.nanosec, g_pol_liveliness.lease_duration.nanosec);
|
||||
cr_assert_eq(publication_data->reliability.kind, g_pol_reliability.kind);
|
||||
cr_assert_eq(publication_data->reliability.max_blocking_time.sec, g_pol_reliability.max_blocking_time.sec);
|
||||
cr_assert_eq(publication_data->reliability.max_blocking_time.nanosec, g_pol_reliability.max_blocking_time.nanosec);
|
||||
cr_assert_eq(publication_data->lifespan.duration.sec, g_pol_lifespan.duration.sec);
|
||||
cr_assert_eq(publication_data->lifespan.duration.nanosec, g_pol_lifespan.duration.nanosec);
|
||||
cr_assert_eq(publication_data->destination_order.kind, g_pol_destination_order.kind);
|
||||
cr_assert_eq(publication_data->user_data.value._buffer, g_pol_userdata.value._buffer);
|
||||
cr_assert_eq(publication_data->user_data.value._length, g_pol_userdata.value._length);
|
||||
cr_assert_eq(publication_data->ownership.kind, g_pol_ownership.kind);
|
||||
cr_assert_eq(publication_data->ownership_strength.value, g_pol_ownership_strength.value);
|
||||
cr_assert_eq(publication_data->presentation.access_scope, g_pol_presentation.access_scope);
|
||||
cr_assert_eq(publication_data->presentation.coherent_access, g_pol_presentation.coherent_access);
|
||||
cr_assert_eq(publication_data->presentation.ordered_access, g_pol_presentation.ordered_access);
|
||||
|
||||
cr_assert_eq(publication_data->partition.name._length, g_pol_partition.name._length);
|
||||
for (uint32_t i = 0; i < publication_data->partition.name._length; ++i)
|
||||
{
|
||||
cr_assert_str_eq(publication_data->partition.name._buffer[i], c_partitions[i]);
|
||||
}
|
||||
|
||||
cr_assert_str_eq(publication_data->topic_data.value._buffer, g_pol_topicdata.value._buffer);
|
||||
cr_assert_eq(publication_data->topic_data.value._length, g_pol_topicdata.value._length);
|
||||
cr_assert_str_eq(publication_data->group_data.value._buffer, g_pol_groupdata.value._buffer);
|
||||
cr_assert_eq(publication_data->group_data.value._length, g_pol_groupdata.value._length);
|
||||
#endif
|
||||
DDS_PublicationBuiltinTopicData_free(publication_samples[0], DDS_FREE_ALL);
|
||||
}
|
||||
|
||||
Test(ddsc_builtin_topics, topic_qos, .init = setup, .fini = teardown)
|
||||
{
|
||||
dds_entity_t tpc;
|
||||
dds_entity_t topic_rdr;
|
||||
|
||||
#if 0 /* disabled pending CHAM-347 */
|
||||
dds_return_t ret;
|
||||
DDS_TopicBuiltinTopicData *topic_data;
|
||||
#endif
|
||||
|
||||
void * topic_samples[MAX_SAMPLES];
|
||||
|
||||
dds_qset_durability(g_qos, g_pol_durability.kind);
|
||||
dds_qset_durability_service(g_qos,
|
||||
from_ddsi_duration(g_pol_durability_service.service_cleanup_delay),
|
||||
(dds_history_kind_t)g_pol_durability_service.history_kind,
|
||||
g_pol_durability_service.history_depth,
|
||||
g_pol_durability_service.max_samples,
|
||||
g_pol_durability_service.max_instances,
|
||||
g_pol_durability_service.max_samples_per_instance);
|
||||
dds_qset_deadline(g_qos, from_ddsi_duration(g_pol_deadline.period));
|
||||
dds_qset_latency_budget(g_qos, from_ddsi_duration(g_pol_latency_budget.duration));
|
||||
dds_qset_liveliness(g_qos, (dds_liveliness_kind_t)g_pol_liveliness.kind, from_ddsi_duration(g_pol_liveliness.lease_duration));
|
||||
dds_qset_reliability(g_qos, (dds_reliability_kind_t)g_pol_reliability.kind, from_ddsi_duration(g_pol_reliability.max_blocking_time));
|
||||
dds_qset_transport_priority(g_qos, g_pol_transport_priority.value);
|
||||
dds_qset_lifespan(g_qos, from_ddsi_duration(g_pol_lifespan.duration));
|
||||
dds_qset_destination_order(g_qos, (dds_destination_order_kind_t)g_pol_destination_order.kind);
|
||||
dds_qset_history(g_qos, (dds_history_kind_t)g_pol_history.kind, g_pol_history.depth);
|
||||
dds_qset_resource_limits(g_qos, g_pol_resource_limits.max_samples, g_pol_resource_limits.max_instances,
|
||||
g_pol_resource_limits.max_samples_per_instance);
|
||||
dds_qset_ownership(g_qos, (dds_ownership_kind_t)g_pol_ownership.kind);
|
||||
dds_qset_topicdata(g_qos, g_pol_topicdata.value._buffer, g_pol_topicdata.value._length);
|
||||
|
||||
|
||||
tpc = dds_create_topic(g_participant, &Space_Type1_desc, "SpaceType1", g_qos, NULL);
|
||||
|
||||
topic_samples[0] = DDS_PublicationBuiltinTopicData__alloc();
|
||||
|
||||
topic_rdr = dds_create_reader(g_participant, DDS_BUILTIN_TOPIC_DCPSTOPIC, NULL, NULL);
|
||||
cr_assert_gt(topic_rdr, 0, "Failed to retrieve built-in datareader for DCPSPublication");
|
||||
#if 0 /* disabled pending CHAM-347 */
|
||||
ret = dds_read(topic_rdr, topic_samples, g_info, MAX_SAMPLES, MAX_SAMPLES);
|
||||
cr_assert_gt(ret, 0, "Failed to read Topic data");
|
||||
|
||||
topic_data = (DDS_TopicBuiltinTopicData *)topic_samples[0];
|
||||
|
||||
cr_assert_str_eq(topic_data->name, "SpaceType1");
|
||||
cr_assert_str_eq(topic_data->type_name, "RoundTripModule::DataType");
|
||||
cr_assert_eq(topic_data->durability.kind, g_pol_durability.kind);
|
||||
cr_assert_eq(topic_data->durability_service.service_cleanup_delay.sec, g_pol_durability_service.service_cleanup_delay.sec);
|
||||
cr_assert_eq(topic_data->durability_service.service_cleanup_delay.nanosec, g_pol_durability_service.service_cleanup_delay.nanosec);
|
||||
cr_assert_eq(topic_data->durability_service.history_kind, g_pol_durability_service.history_kind);
|
||||
cr_assert_eq(topic_data->durability_service.history_depth, g_pol_durability_service.history_depth);
|
||||
cr_assert_eq(topic_data->durability_service.max_samples, g_pol_durability_service.max_samples);
|
||||
cr_assert_eq(topic_data->durability_service.max_instances, g_pol_durability_service.max_instances);
|
||||
cr_assert_eq(topic_data->durability_service.max_samples_per_instance, g_pol_durability_service.max_samples_per_instance);
|
||||
cr_assert_eq(topic_data->deadline.period.sec, g_pol_deadline.period.sec);
|
||||
cr_assert_eq(topic_data->deadline.period.nanosec, g_pol_deadline.period.nanosec);
|
||||
cr_assert_eq(topic_data->latency_budget.duration.sec, g_pol_latency_budget.duration.sec);
|
||||
cr_assert_eq(topic_data->latency_budget.duration.nanosec, g_pol_latency_budget.duration.nanosec);
|
||||
cr_assert_eq(topic_data->liveliness.kind, g_pol_liveliness.kind);
|
||||
cr_assert_eq(topic_data->liveliness.lease_duration.sec, g_pol_liveliness.lease_duration.sec);
|
||||
cr_assert_eq(topic_data->liveliness.lease_duration.nanosec, g_pol_liveliness.lease_duration.nanosec);
|
||||
cr_assert_eq(topic_data->reliability.kind, g_pol_reliability.kind);
|
||||
cr_assert_eq(topic_data->reliability.max_blocking_time.sec, g_pol_reliability.max_blocking_time.sec);
|
||||
cr_assert_eq(topic_data->reliability.max_blocking_time.nanosec, g_pol_reliability.max_blocking_time.nanosec);
|
||||
cr_assert_eq(topic_data->transport_priority.value, g_pol_transport_priority.value);
|
||||
cr_assert_eq(topic_data->lifespan.duration.sec, g_pol_lifespan.duration.sec);
|
||||
cr_assert_eq(topic_data->lifespan.duration.nanosec, g_pol_lifespan.duration.nanosec);
|
||||
cr_assert_eq(topic_data->destination_order.kind, g_pol_destination_order.kind);
|
||||
cr_assert_eq(topic_data->history.kind, g_pol_history.kind);
|
||||
cr_assert_eq(topic_data->history.depth, g_pol_history.depth);
|
||||
cr_assert_eq(topic_data->resource_limits.max_samples, g_pol_resource_limits.max_samples);
|
||||
cr_assert_eq(topic_data->resource_limits.max_instances, g_pol_resource_limits.max_instances);
|
||||
cr_assert_eq(topic_data->resource_limits.max_samples_per_instance, g_pol_resource_limits.max_samples_per_instance);
|
||||
cr_assert_eq(topic_data->ownership.kind, g_pol_ownership.kind);
|
||||
cr_assert_str_eq(topic_data->topic_data.value._buffer, g_pol_topicdata.value._buffer);
|
||||
cr_assert_eq(topic_data->topic_data.value._length, g_pol_topicdata.value._length);
|
||||
#endif
|
||||
DDS_TopicBuiltinTopicData_free(topic_samples[0], DDS_FREE_ALL);
|
||||
}
|
||||
79
src/core/ddsc/tests/config.c
Normal file
79
src/core/ddsc/tests/config.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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 "ddsc/dds.h"
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/logging.h>
|
||||
#include "os/os.h"
|
||||
#include "config_env.h"
|
||||
#include "ddsc/ddsc_project.h"
|
||||
|
||||
#define FORCE_ENV
|
||||
|
||||
#define URI_VARIABLE DDSC_PROJECT_NAME_NOSPACE_CAPS"_URI"
|
||||
#define MAX_PARTICIPANTS_VARIABLE "MAX_PARTICIPANTS"
|
||||
|
||||
static void config__check_env(
|
||||
_In_z_ const char * env_variable,
|
||||
_In_z_ const char * expected_value)
|
||||
{
|
||||
const char * env_uri = os_getenv(env_variable);
|
||||
const char * const env_not_set = "Environment variable '%s' isn't set. This needs to be set to '%s' for this test to run.";
|
||||
const char * const env_not_as_expected = "Environment variable '%s' has an unexpected value: '%s' (expected: '%s')";
|
||||
|
||||
#ifdef FORCE_ENV
|
||||
{
|
||||
bool env_ok;
|
||||
|
||||
if ( env_uri == NULL ) {
|
||||
cr_log_info(env_not_set, env_variable, expected_value);
|
||||
env_ok = false;
|
||||
} else if ( strncmp(env_uri, expected_value, strlen(expected_value)) != 0 ) {
|
||||
cr_log_info(env_not_as_expected, env_variable, env_uri, expected_value);
|
||||
env_ok = false;
|
||||
} else {
|
||||
env_ok = true;
|
||||
}
|
||||
|
||||
if ( !env_ok ) {
|
||||
os_result r;
|
||||
char *envstr;
|
||||
|
||||
envstr = os_malloc(strlen(env_variable) + strlen("=") + strlen(expected_value) + 1);
|
||||
(void) sprintf(envstr, "%s=%s", env_variable, expected_value);
|
||||
|
||||
r = os_putenv(envstr);
|
||||
cr_assert_eq(r, os_resultSuccess, "Invoking os_putenv(\"%s\") failed", envstr);
|
||||
cr_log_warn("Environment variable '%s' set to expected value '%s'", env_variable, expected_value);
|
||||
|
||||
os_free(envstr);
|
||||
}
|
||||
}
|
||||
#else
|
||||
cr_assert_not_null(env_uri, env_not_set, env_variable, expected_value);
|
||||
cr_assert_str_eq(env_uri, expected_value, env_not_as_expected, env_variable, env_uri, expected_value);
|
||||
#endif /* FORCE_ENV */
|
||||
|
||||
}
|
||||
|
||||
Test(ddsc_config, simple_udp, .init = os_osInit, .fini = os_osExit) {
|
||||
|
||||
dds_entity_t participant;
|
||||
|
||||
config__check_env(URI_VARIABLE, CONFIG_ENV_SIMPLE_UDP);
|
||||
config__check_env(MAX_PARTICIPANTS_VARIABLE, CONFIG_ENV_MAX_PARTICIPANTS);
|
||||
|
||||
participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
|
||||
cr_assert_gt(participant, 0, "dds_create_participant");
|
||||
|
||||
dds_delete(participant);
|
||||
}
|
||||
18
src/core/ddsc/tests/config_env.h.in
Normal file
18
src/core/ddsc/tests/config_env.h.in
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* 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 CONFIG_ENV_H
|
||||
#define CONFIG_ENV_H
|
||||
|
||||
#define CONFIG_ENV_SIMPLE_UDP "@Criterion_ddsc_config_simple_udp_uri@"
|
||||
#define CONFIG_ENV_MAX_PARTICIPANTS "@Criterion_ddsc_config_simple_udp_max_participants@"
|
||||
|
||||
#endif /* CONFIG_ENV_H */
|
||||
42
src/core/ddsc/tests/config_simple_udp.xml
Normal file
42
src/core/ddsc/tests/config_simple_udp.xml
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
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
|
||||
-->
|
||||
<CycloneDDS>
|
||||
<!-- Simple config-file for testing whether a config-file can be picked up
|
||||
correctly. -->
|
||||
<Domain>
|
||||
<Id>3</Id>
|
||||
</Domain>
|
||||
<Lease>
|
||||
<ExpiryTime update_factor="2e-1"/>
|
||||
</Lease>
|
||||
<DDSI2E>
|
||||
<General>
|
||||
<NetworkInterfaceAddress>127.0.0.1</NetworkInterfaceAddress>
|
||||
<AllowMulticast>true</AllowMulticast>
|
||||
<EnableMulticastLoopback>true</EnableMulticastLoopback>
|
||||
<EnableLoopback>false</EnableLoopback>
|
||||
</General>
|
||||
<Compatibility>
|
||||
<StandardsConformance>lax</StandardsConformance>
|
||||
</Compatibility>
|
||||
<Tracing>
|
||||
<Verbosity>warning</Verbosity>
|
||||
<OutputFile>vortexdds-<![CDATA[trace]]>.${NON_EXISTENT_ENV_VARIABLE:-l}${CYCLONEDDS_URI:+o}g </OutputFile>
|
||||
</Tracing>
|
||||
<Internal>
|
||||
<MaxParticipants>${MAX_PARTICIPANTS}</MaxParticipants>
|
||||
<HeartbeatInterval max="10 s"> 100 ms </HeartbeatInterval>
|
||||
<RediscoveryBlacklistDuration></RediscoveryBlacklistDuration>
|
||||
</Internal>
|
||||
</DDSI2E>
|
||||
</CycloneDDS>
|
||||
1099
src/core/ddsc/tests/dispose.c
Normal file
1099
src/core/ddsc/tests/dispose.c
Normal file
File diff suppressed because it is too large
Load diff
365
src/core/ddsc/tests/entity_api.c
Normal file
365
src/core/ddsc/tests/entity_api.c
Normal file
|
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
* 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 "ddsc/dds.h"
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/logging.h>
|
||||
|
||||
/* We are deliberately testing some bad arguments that SAL will complain about.
|
||||
* So, silence SAL regarding these issues. */
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 6387 28020)
|
||||
|
||||
/* Add --verbose command line argument to get the cr_log_info traces (if there are any). */
|
||||
|
||||
static dds_entity_t entity = -1;
|
||||
|
||||
#define cr_assert_status_eq(s1, s2, ...) cr_assert_eq(dds_err_nr(s1), s2, __VA_ARGS__)
|
||||
|
||||
/* Fixture to create prerequisite entity */
|
||||
void create_entity(void)
|
||||
{
|
||||
cr_assert_eq(entity, -1, "entity already created pre create_entity fixture");
|
||||
entity = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(entity, 0, "create_entity fixture failed");
|
||||
}
|
||||
|
||||
/* Fixture to delete prerequisite entity */
|
||||
void delete_entity(void)
|
||||
{
|
||||
cr_assert_gt(entity, 0, "entity not created pre delete_entity fixture");
|
||||
dds_return_t ret = dds_delete(entity);
|
||||
cr_assert_status_eq(ret, DDS_RETCODE_OK, "delete_entity fixture failed (ret: %d)", dds_err_nr(ret));
|
||||
entity = -1;
|
||||
}
|
||||
|
||||
Test(ddsc_entity, create, .fini = delete_entity)
|
||||
{
|
||||
/* Use participant as entity in the tests. */
|
||||
entity = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(entity, 0, "dds_create_participant");
|
||||
}
|
||||
|
||||
Test(ddsc_entity, enable, .init = create_entity, .fini = delete_entity)
|
||||
{
|
||||
dds_return_t status;
|
||||
|
||||
/* Check enabling with bad parameters. */
|
||||
status = dds_enable(0);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_enable (NULL)");
|
||||
|
||||
/* Check actual enabling. */
|
||||
/* TODO: CHAM-96: Check enabling.
|
||||
status = dds_enable(&entity);
|
||||
cr_assert_status_eq(status, dds_err_nr(DDS_RETCODE_OK), "dds_enable (delayed enable)");
|
||||
*/
|
||||
|
||||
/* Check re-enabling (should be a noop). */
|
||||
status = dds_enable(entity);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_enable (already enabled)");
|
||||
}
|
||||
|
||||
void entity_qos_get_set(dds_entity_t e, const char* info)
|
||||
{
|
||||
dds_return_t status;
|
||||
dds_qos_t *qos = dds_qos_create();
|
||||
|
||||
/* Get QoS. */
|
||||
status = dds_get_qos (e, qos);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_qos(e, qos) ret: %d, %s", dds_err_nr(status), info);
|
||||
|
||||
status = dds_set_qos (e, qos); /* Doesn't change anything, so no need to forbid. But we return NOT_SUPPORTED anyway for now*/
|
||||
cr_assert_status_eq(status, DDS_RETCODE_UNSUPPORTED, "dds_set_qos(entity, qos) %s", info);
|
||||
|
||||
dds_qos_delete(qos);
|
||||
}
|
||||
|
||||
Test(ddsc_entity, qos, .init = create_entity, .fini = delete_entity)
|
||||
{
|
||||
dds_return_t status;
|
||||
dds_qos_t *qos = dds_qos_create();
|
||||
|
||||
/* Don't check inconsistent and immutable policies. That's a job
|
||||
* for the specific entity children, not for the generic part. */
|
||||
|
||||
/* Check getting QoS with bad parameters. */
|
||||
status = dds_get_qos (0, NULL);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_get_qos(NULL, NULL)");
|
||||
status = dds_get_qos (entity, NULL);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_get_qos(entity, NULL)");
|
||||
status = dds_get_qos (0, qos);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_get_qos(NULL, qos)");
|
||||
|
||||
/* Check setting QoS with bad parameters. */
|
||||
status = dds_set_qos (0, NULL);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_set_qos(NULL, NULL)");
|
||||
status = dds_set_qos (entity, NULL);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_set_qos(entity, NULL)");
|
||||
status = dds_set_qos (0, qos);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_set_qos(NULL, qos)");
|
||||
|
||||
/* Check set/get with entity without initial qos. */
|
||||
entity_qos_get_set(entity, "{without initial qos}");
|
||||
|
||||
/* Check set/get with entity with initial qos. */
|
||||
{
|
||||
dds_entity_t par = dds_create_participant (DDS_DOMAIN_DEFAULT, qos, NULL);
|
||||
entity_qos_get_set(par, "{with initial qos}");
|
||||
dds_delete(par);
|
||||
}
|
||||
|
||||
/* Delete qos. */
|
||||
dds_qos_delete(qos);
|
||||
}
|
||||
|
||||
Test(ddsc_entity, listener, .init = create_entity, .fini = delete_entity)
|
||||
{
|
||||
dds_return_t status;
|
||||
dds_listener_t *l1 = dds_listener_create(NULL);
|
||||
dds_listener_t *l2 = dds_listener_create(NULL);
|
||||
void *cb1;
|
||||
void *cb2;
|
||||
|
||||
/* Don't check actual workings of the listeners. That's a job
|
||||
* for the specific entity children, not for the generic part. */
|
||||
|
||||
/* Set some random values for the l2 listener callbacks.
|
||||
* I know for sure that these will not be called within this test.
|
||||
* Otherwise, the following would let everything crash.
|
||||
* We just set them to know for sure that we got what we set. */
|
||||
dds_lset_liveliness_changed(l2, (dds_on_liveliness_changed_fn) 1234);
|
||||
dds_lset_requested_deadline_missed(l2, (dds_on_requested_deadline_missed_fn) 5678);
|
||||
dds_lset_requested_incompatible_qos(l2, (dds_on_requested_incompatible_qos_fn) 8765);
|
||||
dds_lset_publication_matched(l2, (dds_on_publication_matched_fn) 4321);
|
||||
|
||||
/* Check getting Listener with bad parameters. */
|
||||
status = dds_get_listener (0, NULL);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_get_listener(NULL, NULL)");
|
||||
status = dds_get_listener (entity, NULL);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_get_listener(entity, NULL)");
|
||||
status = dds_get_listener (0, l1);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_get_listener(NULL, listener)");
|
||||
|
||||
/* Get Listener, which should be unset. */
|
||||
status = dds_get_listener (entity, l1);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_listener(entity, listener)");
|
||||
dds_lget_liveliness_changed (l1, (dds_on_liveliness_changed_fn*)&cb1);
|
||||
cr_assert_eq(cb1, DDS_LUNSET, "Listener not initialized to NULL");
|
||||
dds_lget_requested_deadline_missed (l1, (dds_on_requested_deadline_missed_fn*)&cb1);
|
||||
cr_assert_eq(cb1, DDS_LUNSET, "Listener not initialized to NULL");
|
||||
dds_lget_requested_incompatible_qos (l1, (dds_on_requested_incompatible_qos_fn*)&cb1);
|
||||
cr_assert_eq(cb1, DDS_LUNSET, "Listener not initialized to NULL");
|
||||
dds_lget_publication_matched (l1, (dds_on_publication_matched_fn*)&cb1);
|
||||
cr_assert_eq(cb1, DDS_LUNSET, "Listener not initialized to NULL");
|
||||
|
||||
/* Check setting Listener with bad parameters. */
|
||||
status = dds_set_listener (0, NULL);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_set_listener(NULL, NULL)");
|
||||
status = dds_set_listener (0, l2);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_set_listener(NULL, listener)");
|
||||
|
||||
/* Getting after setting should return set listener. */
|
||||
status = dds_set_listener (entity, l2);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_set_listener(entity, listener)");
|
||||
status = dds_get_listener (entity, l1);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_listener(entity, listener)");
|
||||
dds_lget_liveliness_changed (l1, (dds_on_liveliness_changed_fn*)&cb1);
|
||||
dds_lget_liveliness_changed (l2, (dds_on_liveliness_changed_fn*)&cb2);
|
||||
cr_assert_eq(cb1, cb2, "Listeners are not equal");
|
||||
dds_lget_requested_deadline_missed (l1, (dds_on_requested_deadline_missed_fn*)&cb1);
|
||||
dds_lget_requested_deadline_missed (l2, (dds_on_requested_deadline_missed_fn*)&cb2);
|
||||
cr_assert_eq(cb1, cb2, "Listeners are not equal");
|
||||
dds_lget_requested_incompatible_qos (l1, (dds_on_requested_incompatible_qos_fn*)&cb1);
|
||||
dds_lget_requested_incompatible_qos (l2, (dds_on_requested_incompatible_qos_fn*)&cb2);
|
||||
cr_assert_eq(cb1, cb2, "Listeners are not equal");
|
||||
dds_lget_publication_matched (l1, (dds_on_publication_matched_fn*)&cb1);
|
||||
dds_lget_publication_matched (l2, (dds_on_publication_matched_fn*)&cb2);
|
||||
cr_assert_eq(cb1, cb2, "Listeners are not equal");
|
||||
|
||||
/* Reset listener. */
|
||||
status = dds_set_listener (entity, NULL);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_set_listener(entity, NULL)");
|
||||
status = dds_get_listener (entity, l2);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_listener(entity, listener)");
|
||||
dds_lget_liveliness_changed (l2, (dds_on_liveliness_changed_fn*)&cb2);
|
||||
cr_assert_eq(cb2, DDS_LUNSET, "Listener not reset");
|
||||
dds_lget_requested_deadline_missed (l2, (dds_on_requested_deadline_missed_fn*)&cb2);
|
||||
cr_assert_eq(cb2, DDS_LUNSET, "Listener not reset");
|
||||
dds_lget_requested_incompatible_qos (l2, (dds_on_requested_incompatible_qos_fn*)&cb2);
|
||||
cr_assert_eq(cb2, DDS_LUNSET, "Listener not reset");
|
||||
dds_lget_publication_matched (l2, (dds_on_publication_matched_fn*)&cb2);
|
||||
cr_assert_eq(cb2, DDS_LUNSET, "Listener not reset");
|
||||
|
||||
dds_free(l2);
|
||||
dds_free(l1);
|
||||
}
|
||||
|
||||
Test(ddsc_entity, status, .init = create_entity, .fini = delete_entity)
|
||||
{
|
||||
dds_return_t status1;
|
||||
uint32_t s1 = 0;
|
||||
|
||||
/* Don't check actual bad statuses. That's a job
|
||||
* for the specific entity children, not for the generic part. */
|
||||
|
||||
/* Check getting Status with bad parameters. */
|
||||
status1 = dds_get_enabled_status (0, NULL);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_BAD_PARAMETER, "dds_get_enabled_status(NULL, NULL)");
|
||||
status1 = dds_get_enabled_status (entity, NULL);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_BAD_PARAMETER, "dds_get_enabled_status(entity, NULL)");
|
||||
status1 = dds_get_enabled_status (0, &s1);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_BAD_PARAMETER, "dds_get_enabled_status(NULL, status)");
|
||||
|
||||
/* Get Status, which should be 0 for a participant. */
|
||||
status1 = dds_get_enabled_status (entity, &s1);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_OK, "dds_get_enabled_status(entity, status)");
|
||||
cr_assert_eq(s1, 0, "Enabled status mask is not 0");
|
||||
|
||||
/* Check setting Status with bad parameters. */
|
||||
status1 = dds_set_enabled_status (0, 0);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_BAD_PARAMETER, "dds_set_enabled_status(NULL, 0)");
|
||||
|
||||
/* I shouldn't be able to set statuses on a participant. */
|
||||
status1 = dds_set_enabled_status (entity, 0);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_OK, "dds_set_enabled_status(entity, 0) %d", dds_err_nr(status1));
|
||||
status1 = dds_set_enabled_status (entity, DDS_DATA_AVAILABLE_STATUS);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_BAD_PARAMETER, "dds_set_enabled_status(entity, status)");
|
||||
|
||||
/* Check getting Status changes with bad parameters. */
|
||||
status1 = dds_get_status_changes (0, NULL);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_BAD_PARAMETER, "dds_get_status_changes(NULL, NULL)");
|
||||
status1 = dds_get_status_changes (entity, NULL);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_BAD_PARAMETER, "dds_get_status_changes(entity, NULL)");
|
||||
status1 = dds_get_status_changes (0, &s1);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_BAD_PARAMETER, "dds_get_status_changes(NULL, status)");
|
||||
status1 = dds_get_status_changes (entity, &s1);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_OK, "dds_get_status_changes(entity, status)");
|
||||
|
||||
/* Status read and take shouldn't work either. */
|
||||
status1 = dds_read_status (0, &s1, 0);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_BAD_PARAMETER, "dds_read_status(NULL, status, 0)");
|
||||
status1 = dds_read_status (entity, &s1, 0);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_OK, "dds_read_status(entity, status, 0)");
|
||||
status1 = dds_take_status (0, &s1, 0);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_BAD_PARAMETER, "dds_take_status(NULL, status, 0)");
|
||||
status1 = dds_take_status (entity, &s1, 0);
|
||||
cr_assert_status_eq(status1, DDS_RETCODE_OK, "dds_take_status(entity, status, 0)");
|
||||
}
|
||||
|
||||
|
||||
Test(ddsc_entity, instance_handle, .init = create_entity, .fini = delete_entity)
|
||||
{
|
||||
dds_return_t status;
|
||||
dds_instance_handle_t hdl;
|
||||
|
||||
/* Don't check actual handle contents. That's a job
|
||||
* for the specific entity children, not for the generic part. */
|
||||
|
||||
/* Check getting Handle with bad parameters. */
|
||||
status = dds_get_instance_handle (0, NULL);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_instancehandle_get(NULL, NULL)");
|
||||
status = dds_get_instance_handle (entity, NULL);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_instancehandle_get(entity, NULL)");
|
||||
status = dds_get_instance_handle (0, &hdl);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_instancehandle_get(NULL, handle)");
|
||||
|
||||
/* Get Instance Handle, which should not be 0 for a participant. */
|
||||
status = dds_get_instance_handle (entity, &hdl);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_instancehandle_get(entity, handle)");
|
||||
cr_assert_neq(hdl, 0, "Entity instance handle is 0");
|
||||
}
|
||||
|
||||
Test(ddsc_entity, get_entities, .init = create_entity, .fini = delete_entity)
|
||||
{
|
||||
dds_return_t status;
|
||||
dds_entity_t par;
|
||||
dds_entity_t child;
|
||||
|
||||
/* ---------- Get Parent ------------ */
|
||||
|
||||
/* Check getting Parent with bad parameters. */
|
||||
par = dds_get_parent (0);
|
||||
cr_assert_eq(dds_err_nr(par), DDS_RETCODE_BAD_PARAMETER, "Parent was returned (despite of bad parameter)");
|
||||
|
||||
/* Get Parent, a participant doesn't have a parent. */
|
||||
par = dds_get_parent (entity);
|
||||
cr_assert_eq(dds_err_nr(par), DDS_ENTITY_NIL, "Parent was returned (despite of it being a participant)");
|
||||
|
||||
/* ---------- Get Participant ------------ */
|
||||
|
||||
/* Check getting Participant with bad parameters. */
|
||||
par = dds_get_participant (0);
|
||||
cr_assert_eq(dds_err_nr(par), DDS_RETCODE_BAD_PARAMETER, "Participant was returned (despite of bad parameter)");
|
||||
|
||||
/* Get Participant, a participants' participant is itself. */
|
||||
par = dds_get_participant (entity);
|
||||
cr_assert_eq(par, entity, "Returned participant was not expected");
|
||||
|
||||
/* ---------- Get Children ------------ */
|
||||
|
||||
/* Check getting Children with bad parameters. */
|
||||
status = dds_get_children (0, &child, 1);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_get_children(NULL, child, 1)");
|
||||
status = dds_get_children (entity, NULL, 1);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_get_children(entity, NULL, 1)");
|
||||
status = dds_get_children (entity, &child, 0);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_get_children(entity, child, 0)");
|
||||
status = dds_get_children (0, NULL, 1);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_get_children(NULL, NULL, 1)");
|
||||
status = dds_get_children (0, &child, 0);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_get_children(NULL, child, 0)");
|
||||
|
||||
/* Get Children, of which there are currently none. */
|
||||
status = dds_get_children (entity, NULL, 0);
|
||||
if (status > 0) {
|
||||
cr_assert("dds_get_children(entity, NULL, 0) un-expectantly found children");
|
||||
} else {
|
||||
cr_assert_eq(status, 0, "dds_get_children(entity, NULL, 0) failed");
|
||||
}
|
||||
status = dds_get_children (entity, &child, 1);
|
||||
if (status > 0) {
|
||||
cr_assert("dds_get_children(entity, child, 1) un-expectantly returned children");
|
||||
} else {
|
||||
cr_assert_eq(status, 0, "dds_get_children(entity, child, 1) failed");
|
||||
}
|
||||
}
|
||||
|
||||
Test(ddsc_entity, get_domainid, .init = create_entity, .fini = delete_entity)
|
||||
{
|
||||
dds_return_t status;
|
||||
dds_domainid_t id;
|
||||
|
||||
/* Check getting ID with bad parameters. */
|
||||
status = dds_get_domainid (0, NULL);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_get_domainid(NULL, NULL)");
|
||||
status = dds_get_domainid (entity, NULL);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_get_domainid(entity, NULL)");
|
||||
status = dds_get_domainid (0, &id);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_get_domainid(NULL, id)");
|
||||
|
||||
/* Get and check the domain id. */
|
||||
status = dds_get_domainid (entity, &id);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_domainid(entity, id)");
|
||||
cr_assert_eq(id, 0, "Different domain_id was returned than expected");
|
||||
}
|
||||
|
||||
Test(ddsc_entity, delete, .init = create_entity)
|
||||
{
|
||||
dds_return_t status;
|
||||
status = dds_delete(0);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_delete(NULL)");
|
||||
|
||||
status = dds_delete(entity);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_delete(entity)");
|
||||
entity = 0;
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
995
src/core/ddsc/tests/entity_hierarchy.c
Normal file
995
src/core/ddsc/tests/entity_hierarchy.c
Normal file
|
|
@ -0,0 +1,995 @@
|
|||
/*
|
||||
* 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 "ddsc/dds.h"
|
||||
#include "os/os.h"
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/logging.h>
|
||||
#include <criterion/theories.h>
|
||||
#include "RoundTrip.h"
|
||||
|
||||
/* Add --verbose command line argument to get the cr_log_info traces (if there are any). */
|
||||
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* Test fixtures
|
||||
*
|
||||
*************************************************************************************************/
|
||||
|
||||
static dds_entity_t g_keep = 0;
|
||||
static dds_entity_t g_participant = 0;
|
||||
static dds_entity_t g_topic = 0;
|
||||
static dds_entity_t g_subscriber = 0;
|
||||
static dds_entity_t g_publisher = 0;
|
||||
static dds_entity_t g_reader = 0;
|
||||
static dds_entity_t g_writer = 0;
|
||||
static dds_entity_t g_readcond = 0;
|
||||
static dds_entity_t g_querycond = 0;
|
||||
|
||||
/* Dummy query condition callback. */
|
||||
static bool
|
||||
accept_all(const void * sample)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static char*
|
||||
create_topic_name(const char *prefix, char *name, size_t size)
|
||||
{
|
||||
/* Get semi random g_topic name. */
|
||||
os_procId pid = os_procIdSelf();
|
||||
uintmax_t tid = os_threadIdToInteger(os_threadIdSelf());
|
||||
(void) snprintf(name, size, "%s_pid%"PRIprocId"_tid%"PRIuMAX"", prefix, pid, tid);
|
||||
return name;
|
||||
}
|
||||
|
||||
static void
|
||||
hierarchy_init(void)
|
||||
{
|
||||
uint32_t mask = DDS_ANY_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE;
|
||||
char name[100];
|
||||
|
||||
g_participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(g_participant, 0, "Failed to create prerequisite g_participant");
|
||||
|
||||
g_topic = dds_create_topic(g_participant, &RoundTripModule_DataType_desc, create_topic_name("ddsc_hierarchy_test", name, sizeof name), NULL, NULL);
|
||||
cr_assert_gt(g_topic, 0, "Failed to create prerequisite g_topic");
|
||||
|
||||
g_publisher = dds_create_publisher(g_participant, NULL, NULL);
|
||||
cr_assert_gt(g_publisher, 0, "Failed to create prerequisite g_publisher");
|
||||
|
||||
g_subscriber = dds_create_subscriber(g_participant, NULL, NULL);
|
||||
cr_assert_gt(g_subscriber, 0, "Failed to create prerequisite g_subscriber");
|
||||
|
||||
g_writer = dds_create_writer(g_publisher, g_topic, NULL, NULL);
|
||||
cr_assert_gt(g_writer, 0, "Failed to create prerequisite g_writer");
|
||||
|
||||
g_reader = dds_create_reader(g_subscriber, g_topic, NULL, NULL);
|
||||
cr_assert_gt(g_reader, 0, "Failed to create prerequisite g_reader");
|
||||
|
||||
g_readcond = dds_create_readcondition(g_reader, mask);
|
||||
cr_assert_gt(g_readcond, 0, "Failed to create prerequisite g_readcond");
|
||||
|
||||
g_querycond = dds_create_querycondition(g_reader, mask, accept_all);
|
||||
cr_assert_gt(g_querycond, 0, "Failed to create prerequisite g_querycond");
|
||||
|
||||
/* The deletion of the last participant will close down every thing. This
|
||||
* means that the API will react differently after that. Because the
|
||||
* testing we're doing here is quite generic, we'd like to not close down
|
||||
* everything when we delete our participant. For that, we create a second
|
||||
* participant, which will keep everything running.
|
||||
*/
|
||||
g_keep = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(g_keep, 0, "Failed to create prerequisite g_keep");
|
||||
}
|
||||
|
||||
static void
|
||||
hierarchy_fini(void)
|
||||
{
|
||||
dds_delete(g_querycond);
|
||||
dds_delete(g_readcond);
|
||||
dds_delete(g_reader);
|
||||
dds_delete(g_writer);
|
||||
dds_delete(g_subscriber);
|
||||
dds_delete(g_publisher);
|
||||
dds_delete(g_topic);
|
||||
dds_delete(g_participant);
|
||||
dds_delete(g_keep);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#else
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* These will check the recursive deletion.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_delete, recursive, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_domainid_t id;
|
||||
dds_return_t ret;
|
||||
|
||||
/* First be sure that 'dds_get_domainid' returns ok. */
|
||||
ret = dds_get_domainid(g_participant, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_OK);
|
||||
ret = dds_get_domainid(g_topic, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_OK);
|
||||
ret = dds_get_domainid(g_publisher, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_OK);
|
||||
ret = dds_get_domainid(g_subscriber, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_OK);
|
||||
ret = dds_get_domainid(g_writer, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_OK);
|
||||
ret = dds_get_domainid(g_reader, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_OK);
|
||||
ret = dds_get_domainid(g_readcond, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_OK);
|
||||
ret = dds_get_domainid(g_querycond, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_OK);
|
||||
|
||||
/* Deleting the top dog (participant) should delete all children. */
|
||||
ret = dds_delete(g_participant);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_OK);
|
||||
|
||||
/* Check if all the entities are deleted now. */
|
||||
ret = dds_get_domainid(g_participant, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED);
|
||||
ret = dds_get_domainid(g_topic, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED);
|
||||
ret = dds_get_domainid(g_publisher, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED);
|
||||
ret = dds_get_domainid(g_subscriber, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED);
|
||||
ret = dds_get_domainid(g_writer, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED);
|
||||
ret = dds_get_domainid(g_reader, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED);
|
||||
ret = dds_get_domainid(g_readcond, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED);
|
||||
ret = dds_get_domainid(g_querycond, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_delete, recursive_with_deleted_topic)
|
||||
{
|
||||
dds_domainid_t id;
|
||||
dds_return_t ret;
|
||||
char name[100];
|
||||
|
||||
/* Internal handling of topic is different from all the other entities.
|
||||
* It's very interesting if this recursive deletion still works and
|
||||
* doesn't crash when the topic is already deleted (CHAM-424). */
|
||||
|
||||
/* First, create a topic and a writer with that topic. */
|
||||
g_participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(g_participant, 0, "Failed to create prerequisite g_participant");
|
||||
g_topic = dds_create_topic(g_participant, &RoundTripModule_DataType_desc, create_topic_name("ddsc_hierarchy_test", name, 100), NULL, NULL);
|
||||
cr_assert_gt(g_topic, 0, "Failed to create prerequisite g_topic");
|
||||
g_writer = dds_create_writer(g_participant, g_topic, NULL, NULL);
|
||||
cr_assert_gt(g_writer, 0, "Failed to create prerequisite g_writer");
|
||||
g_keep = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(g_keep, 0, "Failed to create prerequisite g_keep");
|
||||
|
||||
/* Second, delete the topic to make sure that the writer holds the last
|
||||
* reference to the topic and thus will delete it when it itself is
|
||||
* deleted. */
|
||||
ret = dds_delete(g_topic);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_OK);
|
||||
|
||||
/* Third, deleting the participant should delete all children of which
|
||||
* the writer with the last topic reference is one. */
|
||||
ret = dds_delete(g_participant);
|
||||
/* Before the CHAM-424 fix, we would not get here because of a crash,
|
||||
* or it (incidentally) continued but returned an error. */
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_OK);
|
||||
|
||||
/* Check if the entities are actually deleted. */
|
||||
ret = dds_get_domainid(g_participant, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED, "%s", dds_err_str(ret));
|
||||
ret = dds_get_domainid(g_topic, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED);
|
||||
ret = dds_get_domainid(g_writer, &id);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED);
|
||||
|
||||
dds_delete(g_keep);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* These will check the dds_get_participant in various ways.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_participant, valid_entities) = {
|
||||
DataPoints(dds_entity_t*, &g_readcond, &g_querycond, &g_reader, &g_subscriber, &g_writer, &g_publisher, &g_topic, &g_participant),
|
||||
};
|
||||
Theory((dds_entity_t *entity), ddsc_entity_get_participant, valid_entities, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t participant;
|
||||
participant = dds_get_participant(*entity);
|
||||
cr_assert_eq(participant, g_participant);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_participant, deleted_entities) = {
|
||||
DataPoints(dds_entity_t*, &g_readcond, &g_querycond, &g_reader, &g_subscriber, &g_writer, &g_publisher, &g_topic, &g_participant),
|
||||
};
|
||||
Theory((dds_entity_t *entity), ddsc_entity_get_participant, deleted_entities, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t participant;
|
||||
dds_delete(*entity);
|
||||
participant = dds_get_participant(*entity);
|
||||
cr_assert_eq(dds_err_nr(participant), DDS_RETCODE_ALREADY_DELETED, "returned %d", dds_err_nr(participant));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_participant, invalid_entities) = {
|
||||
DataPoints(dds_entity_t, -2, -1, 0, 1, 100, INT_MAX, INT_MIN),
|
||||
};
|
||||
Theory((dds_entity_t entity), ddsc_entity_get_participant, invalid_entities, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t exp = DDS_RETCODE_BAD_PARAMETER * -1;
|
||||
dds_entity_t participant;
|
||||
|
||||
participant = dds_get_participant(entity);
|
||||
cr_assert_eq(dds_err_nr(participant), dds_err_nr(exp), "returned %d != expected %d", dds_err_nr(participant), dds_err_nr(exp));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* These will check the dds_get_parent in various ways.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_parent, conditions) = {
|
||||
DataPoints(dds_entity_t*, &g_readcond, &g_querycond),
|
||||
};
|
||||
Theory((dds_entity_t *entity), ddsc_entity_get_parent, conditions, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t parent;
|
||||
parent = dds_get_parent(*entity);
|
||||
cr_assert_eq(parent, g_reader);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_parent, reader, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t parent;
|
||||
parent = dds_get_parent(g_reader);
|
||||
cr_assert_eq(parent, g_subscriber);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_parent, writer, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t parent;
|
||||
parent = dds_get_parent(g_writer);
|
||||
cr_assert_eq(parent, g_publisher);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_parent, pubsubtop) = {
|
||||
DataPoints(dds_entity_t*, &g_publisher, &g_subscriber, &g_topic),
|
||||
};
|
||||
Theory((dds_entity_t *entity), ddsc_entity_get_parent, pubsubtop, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t parent;
|
||||
parent = dds_get_parent(*entity);
|
||||
cr_assert_eq(parent, g_participant);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_parent, participant, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t parent;
|
||||
parent = dds_get_parent(g_participant);
|
||||
cr_assert_eq(dds_err_nr(parent), DDS_ENTITY_NIL, "returned %d", dds_err_nr(parent));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_parent, deleted_entities) = {
|
||||
DataPoints(dds_entity_t*, &g_readcond, &g_querycond, &g_reader, &g_subscriber, &g_writer, &g_publisher, &g_topic, &g_participant),
|
||||
};
|
||||
Theory((dds_entity_t *entity), ddsc_entity_get_parent, deleted_entities, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t parent;
|
||||
dds_delete(*entity);
|
||||
parent = dds_get_parent(*entity);
|
||||
cr_assert_eq(dds_err_nr(parent), DDS_RETCODE_ALREADY_DELETED);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_parent, invalid_entities) = {
|
||||
DataPoints(dds_entity_t, -2, -1, 0, 1, 100, INT_MAX, INT_MIN),
|
||||
};
|
||||
Theory((dds_entity_t entity), ddsc_entity_get_parent, invalid_entities, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t exp = DDS_RETCODE_BAD_PARAMETER * -1;
|
||||
dds_entity_t parent;
|
||||
|
||||
parent = dds_get_parent(entity);
|
||||
cr_assert_eq(dds_err_nr(parent), dds_err_nr(exp), "returned %d != expected %d", dds_err_nr(parent), dds_err_nr(exp));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* These will check the dds_get_children in various ways.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_children, null, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
ret = dds_get_children(g_participant, NULL, 0);
|
||||
cr_assert_eq(ret, 3);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_children, invalid_size, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds_entity_t child;
|
||||
ret = dds_get_children(g_participant, &child, INT32_MAX);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_BAD_PARAMETER);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_children, too_small, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds_entity_t children[2];
|
||||
ret = dds_get_children(g_participant, children, 2);
|
||||
cr_assert_eq(ret, 3);
|
||||
cr_assert((children[0] == g_publisher) || (children[0] == g_subscriber) || (children[0] == g_topic));
|
||||
cr_assert((children[1] == g_publisher) || (children[1] == g_subscriber) || (children[1] == g_topic));
|
||||
cr_assert_neq(children[0], children[1]);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_children, participant, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds_entity_t children[4];
|
||||
ret = dds_get_children(g_participant, children, 4);
|
||||
cr_assert_eq(ret, 3);
|
||||
cr_assert((children[0] == g_publisher) || (children[0] == g_subscriber) || (children[0] == g_topic));
|
||||
cr_assert((children[1] == g_publisher) || (children[1] == g_subscriber) || (children[1] == g_topic));
|
||||
cr_assert((children[2] == g_publisher) || (children[2] == g_subscriber) || (children[2] == g_topic));
|
||||
cr_assert_neq(children[0], children[1]);
|
||||
cr_assert_neq(children[0], children[2]);
|
||||
cr_assert_neq(children[1], children[2]);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_children, topic, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds_entity_t child;
|
||||
ret = dds_get_children(g_topic, &child, 1);
|
||||
cr_assert_eq(ret, 0);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_children, publisher, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds_entity_t child;
|
||||
ret = dds_get_children(g_publisher, &child, 1);
|
||||
cr_assert_eq(ret, 1);
|
||||
cr_assert_eq(child, g_writer);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_children, subscriber, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds_entity_t children[2];
|
||||
ret = dds_get_children(g_subscriber, children, 2);
|
||||
cr_assert_eq(ret, 1);
|
||||
cr_assert_eq(children[0], g_reader);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_children, writer, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
ret = dds_get_children(g_writer, NULL, 0);
|
||||
cr_assert_eq(ret, 0);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_children, reader, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds_entity_t children[2];
|
||||
ret = dds_get_children(g_reader, children, 2);
|
||||
cr_assert_eq(ret, 2);
|
||||
cr_assert((children[0] == g_readcond) || (children[0] == g_querycond));
|
||||
cr_assert((children[1] == g_readcond) || (children[1] == g_querycond));
|
||||
cr_assert_neq(children[0], children[1]);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_children, conditions) = {
|
||||
DataPoints(dds_entity_t*, &g_readcond, &g_querycond),
|
||||
};
|
||||
Theory((dds_entity_t *entity), ddsc_entity_get_children, conditions, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds_entity_t child;
|
||||
ret = dds_get_children(*entity, &child, 1);
|
||||
cr_assert_eq(ret, 0);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_children, deleted_entities) = {
|
||||
DataPoints(dds_entity_t*, &g_readcond, &g_querycond, &g_reader, &g_subscriber, &g_writer, &g_publisher, &g_topic, &g_participant),
|
||||
};
|
||||
Theory((dds_entity_t *entity), ddsc_entity_get_children, deleted_entities, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds_entity_t children[4];
|
||||
dds_delete(*entity);
|
||||
ret = dds_get_children(*entity, children, 4);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_children, invalid_entities) = {
|
||||
DataPoints(dds_entity_t, -2, -1, 0, 1, 100, INT_MAX, INT_MIN),
|
||||
};
|
||||
Theory((dds_entity_t entity), ddsc_entity_get_children, invalid_entities, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t exp = DDS_RETCODE_BAD_PARAMETER * -1;
|
||||
dds_entity_t children[4];
|
||||
dds_return_t ret;
|
||||
|
||||
ret = dds_get_children(entity, children, 4);
|
||||
cr_assert_eq(dds_err_nr(ret), dds_err_nr(exp), "returned %d != expected %d", dds_err_nr(ret), dds_err_nr(exp));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* These will check the dds_get_topic in various ways.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_topic, data_entities) = {
|
||||
DataPoints(dds_entity_t*, &g_readcond, &g_querycond, &g_reader, &g_writer),
|
||||
};
|
||||
Theory((dds_entity_t *entity), ddsc_entity_get_topic, data_entities, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t topic;
|
||||
topic = dds_get_topic(*entity);
|
||||
cr_assert_eq(topic, g_topic );
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_topic, deleted_entities) = {
|
||||
DataPoints(dds_entity_t*, &g_readcond, &g_querycond, &g_reader, &g_writer),
|
||||
};
|
||||
Theory((dds_entity_t *entity), ddsc_entity_get_topic, deleted_entities, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t topic;
|
||||
dds_delete(*entity);
|
||||
topic = dds_get_topic(*entity);
|
||||
cr_assert_eq(dds_err_nr(topic), DDS_RETCODE_ALREADY_DELETED);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_topic, invalid_entities) = {
|
||||
DataPoints(dds_entity_t, -2, -1, 0, 1, 100, INT_MAX, INT_MIN),
|
||||
};
|
||||
Theory((dds_entity_t entity), ddsc_entity_get_topic, invalid_entities, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t exp = DDS_RETCODE_BAD_PARAMETER * -1;
|
||||
dds_entity_t topic;
|
||||
|
||||
topic = dds_get_topic(entity);
|
||||
cr_assert_eq(dds_err_nr(topic), dds_err_nr(exp), "returned %d != expected %d", dds_err_nr(topic), dds_err_nr(exp));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_topic, non_data_entities) = {
|
||||
DataPoints(dds_entity_t*, &g_subscriber, &g_publisher, &g_topic, &g_participant),
|
||||
};
|
||||
Theory((dds_entity_t *entity), ddsc_entity_get_topic, non_data_entities, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t topic;
|
||||
topic = dds_get_topic(*entity);
|
||||
cr_assert_eq(dds_err_nr(topic), DDS_RETCODE_ILLEGAL_OPERATION, "returned %d", dds_err_nr(topic));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* These will check the dds_get_publisher in various ways.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_publisher, writer, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t publisher;
|
||||
publisher = dds_get_publisher(g_writer);
|
||||
cr_assert_eq(publisher, g_publisher);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_publisher, deleted_writer, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t publisher;
|
||||
dds_delete(g_writer);
|
||||
publisher = dds_get_publisher(g_writer);
|
||||
cr_assert_eq(dds_err_nr(publisher), DDS_RETCODE_ALREADY_DELETED);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_publisher, invalid_writers) = {
|
||||
DataPoints(dds_entity_t, -2, -1, 0, 1, 100, INT_MAX, INT_MIN),
|
||||
};
|
||||
Theory((dds_entity_t entity), ddsc_entity_get_publisher, invalid_writers, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t exp = DDS_RETCODE_BAD_PARAMETER * -1;
|
||||
dds_entity_t publisher;
|
||||
|
||||
publisher = dds_get_publisher(entity);
|
||||
cr_assert_eq(dds_err_nr(publisher), dds_err_nr(exp), "returned %d != expected %d", dds_err_nr(publisher), dds_err_nr(exp));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_publisher, non_writers) = {
|
||||
DataPoints(dds_entity_t*, &g_publisher, &g_reader, &g_publisher, &g_topic, &g_participant),
|
||||
};
|
||||
Theory((dds_entity_t *cond), ddsc_entity_get_publisher, non_writers, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t publisher;
|
||||
publisher = dds_get_publisher(*cond);
|
||||
cr_assert_eq(dds_err_nr(publisher), DDS_RETCODE_ILLEGAL_OPERATION, "returned %d", dds_err_nr(publisher));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* These will check the dds_get_subscriber in various ways.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_subscriber, readers) = {
|
||||
DataPoints(dds_entity_t*, &g_readcond, &g_querycond, &g_reader),
|
||||
};
|
||||
Theory((dds_entity_t *entity), ddsc_entity_get_subscriber, readers, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t subscriber;
|
||||
subscriber = dds_get_subscriber(*entity);
|
||||
cr_assert_eq(subscriber, g_subscriber);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_subscriber, deleted_readers) = {
|
||||
DataPoints(dds_entity_t*, &g_readcond, &g_querycond, &g_reader),
|
||||
};
|
||||
Theory((dds_entity_t *entity), ddsc_entity_get_subscriber, deleted_readers, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t subscriber;
|
||||
dds_delete(*entity);
|
||||
subscriber = dds_get_subscriber(*entity);
|
||||
cr_assert_eq(dds_err_nr(subscriber), DDS_RETCODE_ALREADY_DELETED);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_subscriber, invalid_readers) = {
|
||||
DataPoints(dds_entity_t, -2, -1, 0, 1, 100, INT_MAX, INT_MIN),
|
||||
};
|
||||
Theory((dds_entity_t entity), ddsc_entity_get_subscriber, invalid_readers, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t exp = DDS_RETCODE_BAD_PARAMETER * -1;
|
||||
dds_entity_t subscriber;
|
||||
|
||||
subscriber = dds_get_subscriber(entity);
|
||||
cr_assert_eq(dds_err_nr(subscriber), dds_err_nr(exp), "returned %d != expected %d", dds_err_nr(subscriber), dds_err_nr(exp));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_subscriber, non_readers) = {
|
||||
DataPoints(dds_entity_t*, &g_subscriber, &g_writer, &g_publisher, &g_topic, &g_participant),
|
||||
};
|
||||
Theory((dds_entity_t *cond), ddsc_entity_get_subscriber, non_readers, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t subscriber;
|
||||
subscriber = dds_get_subscriber(*cond);
|
||||
cr_assert_eq(dds_err_nr(subscriber), DDS_RETCODE_ILLEGAL_OPERATION, "returned %d", dds_err_nr(subscriber));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* These will check the dds_get_datareader in various ways.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_datareader, conditions) = {
|
||||
DataPoints(dds_entity_t*, &g_readcond, &g_querycond),
|
||||
};
|
||||
Theory((dds_entity_t *cond), ddsc_entity_get_datareader, conditions, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t reader;
|
||||
reader = dds_get_datareader(*cond);
|
||||
cr_assert_eq(reader, g_reader);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_datareader, deleted_conds) = {
|
||||
DataPoints(dds_entity_t*, &g_readcond, &g_querycond),
|
||||
};
|
||||
Theory((dds_entity_t *cond), ddsc_entity_get_datareader, deleted_conds, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t reader;
|
||||
dds_delete(*cond);
|
||||
reader = dds_get_datareader(*cond);
|
||||
cr_assert_eq(dds_err_nr(reader), DDS_RETCODE_ALREADY_DELETED);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_datareader, invalid_conds) = {
|
||||
DataPoints(dds_entity_t, -2, -1, 0, 1, 100, INT_MAX, INT_MIN),
|
||||
};
|
||||
Theory((dds_entity_t cond), ddsc_entity_get_datareader, invalid_conds, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t exp = DDS_RETCODE_BAD_PARAMETER * -1;
|
||||
dds_entity_t reader;
|
||||
|
||||
reader = dds_get_datareader(cond);
|
||||
cr_assert_eq(dds_err_nr(reader), dds_err_nr(exp), "returned %d != expected %d", dds_err_nr(reader), dds_err_nr(exp));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_entity_get_datareader, non_conds) = {
|
||||
DataPoints(dds_entity_t*, &g_reader, &g_subscriber, &g_writer, &g_publisher, &g_topic, &g_participant),
|
||||
};
|
||||
Theory((dds_entity_t *cond), ddsc_entity_get_datareader, non_conds, .init=hierarchy_init, .fini=hierarchy_fini)
|
||||
{
|
||||
dds_entity_t reader;
|
||||
reader = dds_get_datareader(*cond);
|
||||
cr_assert_eq(dds_err_nr(reader), DDS_RETCODE_ILLEGAL_OPERATION, "returned %d", dds_err_nr(reader));
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_implicit_publisher, deleted)
|
||||
{
|
||||
dds_entity_t participant;
|
||||
dds_entity_t writer;
|
||||
dds_entity_t topic;
|
||||
dds_return_t ret;
|
||||
char name[100];
|
||||
|
||||
participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0);
|
||||
|
||||
topic = dds_create_topic(participant, &RoundTripModule_DataType_desc, create_topic_name("ddsc_entity_implicit_publisher_test", name, 100), NULL, NULL);
|
||||
cr_assert_gt(topic, 0);
|
||||
|
||||
writer = dds_create_writer(participant, topic, NULL, NULL);
|
||||
cr_assert_gt(writer, 0);
|
||||
|
||||
ret = dds_get_children(participant, NULL, 0);
|
||||
cr_assert_eq(ret, 2);
|
||||
|
||||
dds_delete(writer);
|
||||
|
||||
ret = dds_get_children(participant, NULL, 0);
|
||||
cr_assert_eq(ret, 1);
|
||||
|
||||
dds_delete(topic);
|
||||
dds_delete(participant);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_implicit_publisher, invalid_topic)
|
||||
{
|
||||
dds_entity_t participant;
|
||||
dds_entity_t writer;
|
||||
|
||||
participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0);
|
||||
|
||||
/* Disable SAL warning on intentional misuse of the API */
|
||||
OS_WARNING_MSVC_OFF(28020);
|
||||
writer = dds_create_writer(participant, 0, NULL, NULL);
|
||||
/* Disable SAL warning on intentional misuse of the API */
|
||||
OS_WARNING_MSVC_ON(28020);
|
||||
cr_assert_lt(writer, 0);
|
||||
|
||||
dds_delete(writer);
|
||||
dds_delete(participant);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_implicit_subscriber, deleted)
|
||||
{
|
||||
dds_entity_t participant;
|
||||
dds_entity_t reader;
|
||||
dds_entity_t topic;
|
||||
dds_return_t ret;
|
||||
char name[100];
|
||||
|
||||
participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0);
|
||||
|
||||
topic = dds_create_topic(participant, &RoundTripModule_DataType_desc, create_topic_name("ddsc_entity_implicit_subscriber_test", name, 100), NULL, NULL);
|
||||
cr_assert_gt(topic, 0);
|
||||
|
||||
reader = dds_create_reader(participant, topic, NULL, NULL);
|
||||
cr_assert_gt(reader, 0);
|
||||
|
||||
ret = dds_get_children(participant, NULL, 0);
|
||||
cr_assert_eq(ret, 2);
|
||||
|
||||
dds_delete(reader);
|
||||
|
||||
ret = dds_get_children(participant, NULL, 0);
|
||||
cr_assert_eq(ret, 1);
|
||||
|
||||
dds_delete(topic);
|
||||
dds_delete(participant);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_explicit_subscriber, invalid_topic)
|
||||
{
|
||||
dds_entity_t participant;
|
||||
dds_entity_t reader;
|
||||
dds_entity_t subscriber;
|
||||
|
||||
participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0);
|
||||
|
||||
subscriber = dds_create_subscriber(participant, NULL,NULL);
|
||||
/* Disable SAL warning on intentional misuse of the API */
|
||||
OS_WARNING_MSVC_OFF(28020);
|
||||
reader = dds_create_reader(subscriber, 0, NULL, NULL);
|
||||
OS_WARNING_MSVC_ON(28020);
|
||||
cr_assert_lt(reader, 0);
|
||||
|
||||
dds_delete(reader);
|
||||
dds_delete(participant);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_children, implicit_publisher)
|
||||
{
|
||||
dds_entity_t participant;
|
||||
dds_entity_t publisher;
|
||||
dds_entity_t writer;
|
||||
dds_entity_t topic;
|
||||
dds_entity_t child[2], child2[2];
|
||||
dds_return_t ret;
|
||||
char name[100];
|
||||
|
||||
participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0);
|
||||
|
||||
topic = dds_create_topic(participant, &RoundTripModule_DataType_desc, create_topic_name("ddsc_entity_implicit_publisher_test", name, 100), NULL, NULL);
|
||||
cr_assert_gt(topic, 0);
|
||||
|
||||
writer = dds_create_writer(participant, topic, NULL, NULL);
|
||||
cr_assert_gt(writer, 0);
|
||||
ret = dds_get_children(participant, child, 2);
|
||||
cr_assert_eq(ret, 2);
|
||||
if(child[0] == topic){
|
||||
publisher = child[1];
|
||||
} else if(child[1] == topic){
|
||||
publisher = child[0];
|
||||
} else{
|
||||
cr_assert(false, "topic was not returned");
|
||||
}
|
||||
cr_assert_neq(publisher, topic);
|
||||
|
||||
cr_assert_gt(publisher, 0);
|
||||
cr_assert_neq(publisher, writer);
|
||||
|
||||
dds_delete(writer);
|
||||
|
||||
ret = dds_get_children(participant, child2, 2);
|
||||
cr_assert_eq(ret, 2);
|
||||
cr_assert( (child2[0] == child[0]) || (child2[0] == child[1]) );
|
||||
cr_assert( (child2[1] == child[0]) || (child2[1] == child[1]) );
|
||||
|
||||
dds_delete(topic);
|
||||
dds_delete(participant);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_children, implicit_subscriber)
|
||||
{
|
||||
dds_entity_t participant;
|
||||
dds_entity_t subscriber;
|
||||
dds_entity_t reader;
|
||||
dds_entity_t topic;
|
||||
dds_entity_t child[2], child2[2];
|
||||
dds_return_t ret;
|
||||
char name[100];
|
||||
|
||||
participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0);
|
||||
|
||||
topic = dds_create_topic(participant, &RoundTripModule_DataType_desc, create_topic_name("ddsc_entity_implicit_subscriber_test", name, 100), NULL, NULL);
|
||||
cr_assert_gt(topic, 0);
|
||||
|
||||
reader = dds_create_reader(participant, topic, NULL, NULL);
|
||||
cr_assert_gt(reader, 0);
|
||||
ret = dds_get_children(participant, child, 2);
|
||||
cr_assert_eq(ret, 2);
|
||||
if(child[0] == topic){
|
||||
subscriber = child[1];
|
||||
} else if(child[1] == topic){
|
||||
subscriber = child[0];
|
||||
} else{
|
||||
cr_assert(false, "topic was not returned");
|
||||
}
|
||||
cr_assert_neq(subscriber, topic);
|
||||
|
||||
cr_assert_gt(subscriber, 0);
|
||||
cr_assert_neq(subscriber, reader);
|
||||
|
||||
dds_delete(reader);
|
||||
|
||||
ret = dds_get_children(participant, child2, 2);
|
||||
cr_assert_eq(ret, 2);
|
||||
cr_assert( (child2[0] == child[0]) || (child2[0] == child[1]) );
|
||||
cr_assert( (child2[1] == child[0]) || (child2[1] == child[1]) );
|
||||
|
||||
dds_delete(topic);
|
||||
dds_delete(participant);
|
||||
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_parent, implicit_publisher)
|
||||
{
|
||||
dds_entity_t participant;
|
||||
dds_entity_t writer;
|
||||
dds_entity_t parent;
|
||||
dds_entity_t topic;
|
||||
dds_return_t ret;
|
||||
char name[100];
|
||||
|
||||
participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0);
|
||||
|
||||
topic = dds_create_topic(participant, &RoundTripModule_DataType_desc, create_topic_name("ddsc_entity_implicit_publisher_promotion_test", name, 100), NULL, NULL);
|
||||
cr_assert_gt(topic, 0);
|
||||
|
||||
writer = dds_create_writer(participant, topic, NULL, NULL);
|
||||
cr_assert_gt(writer, 0);
|
||||
|
||||
parent = dds_get_parent(writer);
|
||||
cr_assert_neq(parent, participant);
|
||||
cr_assert_gt(parent, 0);
|
||||
|
||||
dds_delete(writer);
|
||||
|
||||
ret = dds_delete(parent);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_OK);
|
||||
dds_delete(participant);
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_entity_get_parent, implicit_subscriber)
|
||||
{
|
||||
dds_entity_t participant;
|
||||
dds_entity_t reader;
|
||||
dds_entity_t parent;
|
||||
dds_entity_t topic;
|
||||
dds_return_t ret;
|
||||
char name[100];
|
||||
|
||||
participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0);
|
||||
|
||||
topic = dds_create_topic(participant, &RoundTripModule_DataType_desc, create_topic_name("ddsc_entity_implicit_subscriber_promotion_test", name, 100), NULL, NULL);
|
||||
cr_assert_gt(topic, 0);
|
||||
|
||||
reader = dds_create_reader(participant, topic, NULL, NULL);
|
||||
cr_assert_gt(reader, 0);
|
||||
|
||||
parent = dds_get_parent(reader);
|
||||
cr_assert_neq(parent, participant);
|
||||
cr_assert_gt(parent, 0);
|
||||
|
||||
dds_delete(reader);
|
||||
|
||||
ret = dds_delete(parent);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_OK);
|
||||
dds_delete(participant);
|
||||
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#endif
|
||||
1335
src/core/ddsc/tests/entity_status.c
Normal file
1335
src/core/ddsc/tests/entity_status.c
Normal file
File diff suppressed because it is too large
Load diff
33
src/core/ddsc/tests/err.c
Normal file
33
src/core/ddsc/tests/err.c
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 "ddsc/dds.h"
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/logging.h>
|
||||
|
||||
Test(ddsc_err, str)
|
||||
{
|
||||
cr_assert_str_eq(dds_err_str(1 ), "Success");
|
||||
cr_assert_str_eq(dds_err_str(-255 ), "Unknown");
|
||||
cr_assert_str_eq(dds_err_str(DDS_RETCODE_OK * -1), "Success");
|
||||
cr_assert_str_eq(dds_err_str(DDS_RETCODE_ERROR * -1), "Error");
|
||||
cr_assert_str_eq(dds_err_str(DDS_RETCODE_UNSUPPORTED * -1), "Unsupported");
|
||||
cr_assert_str_eq(dds_err_str(DDS_RETCODE_BAD_PARAMETER * -1), "Bad Parameter");
|
||||
cr_assert_str_eq(dds_err_str(DDS_RETCODE_PRECONDITION_NOT_MET * -1), "Precondition Not Met");
|
||||
cr_assert_str_eq(dds_err_str(DDS_RETCODE_OUT_OF_RESOURCES * -1), "Out Of Resources");
|
||||
cr_assert_str_eq(dds_err_str(DDS_RETCODE_NOT_ENABLED * -1), "Not Enabled");
|
||||
cr_assert_str_eq(dds_err_str(DDS_RETCODE_IMMUTABLE_POLICY * -1), "Immutable Policy");
|
||||
cr_assert_str_eq(dds_err_str(DDS_RETCODE_INCONSISTENT_POLICY * -1), "Inconsistent Policy");
|
||||
cr_assert_str_eq(dds_err_str(DDS_RETCODE_ALREADY_DELETED * -1), "Already Deleted");
|
||||
cr_assert_str_eq(dds_err_str(DDS_RETCODE_TIMEOUT * -1), "Timeout");
|
||||
cr_assert_str_eq(dds_err_str(DDS_RETCODE_NO_DATA * -1), "No Data");
|
||||
cr_assert_str_eq(dds_err_str(DDS_RETCODE_ILLEGAL_OPERATION * -1), "Illegal Operation");
|
||||
}
|
||||
39
src/core/ddsc/tests/file_id.c
Normal file
39
src/core/ddsc/tests/file_id.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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 "ddsc/dds.h"
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/logging.h>
|
||||
#include "os/os.h"
|
||||
|
||||
Test(ddsc_err, unique_file_id)
|
||||
{
|
||||
dds_entity_t participant, reader, writer;
|
||||
|
||||
participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0);
|
||||
|
||||
/* Disable SAL warning on intentional misuse of the API */
|
||||
OS_WARNING_MSVC_OFF(28020);
|
||||
reader = dds_create_reader(0, 0, NULL, NULL);
|
||||
cr_assert_lt(reader, 0);
|
||||
|
||||
writer = dds_create_writer(0, 0, NULL, NULL);
|
||||
cr_assert_lt(writer, 0);
|
||||
|
||||
OS_WARNING_MSVC_ON(28020);
|
||||
cr_log_info("file_id for dds_create_reader: %d", dds_err_file_id(reader));
|
||||
cr_log_info("file_id for dds_create_writer: %d", dds_err_file_id(writer));
|
||||
|
||||
cr_assert_neq(dds_err_file_id(reader), dds_err_file_id(writer));
|
||||
|
||||
dds_delete(participant);
|
||||
}
|
||||
1044
src/core/ddsc/tests/listener.c
Normal file
1044
src/core/ddsc/tests/listener.c
Normal file
File diff suppressed because it is too large
Load diff
332
src/core/ddsc/tests/participant.c
Normal file
332
src/core/ddsc/tests/participant.c
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
/*
|
||||
* 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 "ddsc/dds.h"
|
||||
#include <criterion/criterion.h>
|
||||
#include <os/os.h>
|
||||
#include "config_env.h"
|
||||
#include "ddsc/ddsc_project.h"
|
||||
|
||||
|
||||
#define cr_assert_status_eq(s1, s2, ...) cr_assert_eq(dds_err_nr(s1), s2, __VA_ARGS__)
|
||||
|
||||
|
||||
Test(ddsc_participant, create_and_delete) {
|
||||
|
||||
dds_entity_t participant, participant2, participant3;
|
||||
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "dds_participant_create");
|
||||
|
||||
participant2 = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant2, 0, "dds_participant_create");
|
||||
|
||||
dds_delete (participant);
|
||||
dds_delete (participant2);
|
||||
|
||||
participant3 = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant3, 0, "dds_participant_create");
|
||||
|
||||
dds_delete (participant3);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Test for creating participant with no configuration file */
|
||||
Test(ddsc_participant, create_with_no_conf_no_env) {
|
||||
dds_entity_t participant, participant2, participant3;
|
||||
dds_return_t status;
|
||||
dds_domainid_t domain_id;
|
||||
dds_domainid_t valid_domain=0;
|
||||
|
||||
const char * env_uri = os_getenv(DDSC_PROJECT_NAME_NOSPACE_CAPS"_URI");
|
||||
cr_assert_eq(env_uri, NULL, DDSC_PROJECT_NAME_NOSPACE_CAPS"_URI must be NULL");
|
||||
|
||||
//invalid domain
|
||||
participant = dds_create_participant (1, NULL, NULL);
|
||||
cr_assert_lt(participant, 0, "Error must be received for invalid domain value");
|
||||
|
||||
//valid specific domain value
|
||||
participant2 = dds_create_participant (valid_domain, NULL, NULL);
|
||||
cr_assert_gt(participant2, 0, "Valid participant must be received for valid specific domain value");
|
||||
status = dds_get_domainid(participant2, &domain_id);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_domainid(participant, domain_id)");
|
||||
cr_assert_eq(domain_id, valid_domain, "Retrieved domain ID must be valid");
|
||||
|
||||
//DDS_DOMAIN_DEFAULT from user
|
||||
participant3 = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant3, 0, "Valid participant must be received for DDS_DOMAIN_DEFAULT");
|
||||
status = dds_get_domainid(participant3, &domain_id);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_domainid(participant, domain_id)");
|
||||
cr_assert_eq(domain_id, valid_domain, "Retrieved domain ID must be valid");
|
||||
|
||||
dds_delete(participant2);
|
||||
dds_delete(participant3);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
////WITH CONF
|
||||
|
||||
/* Test for creating participant with valid configuration file */
|
||||
Test(ddsc_participant, create_with_conf_no_env) {
|
||||
dds_entity_t participant, participant2, participant3;
|
||||
dds_return_t status;
|
||||
dds_domainid_t domain_id;
|
||||
dds_domainid_t valid_domain=3;
|
||||
|
||||
static char env_uri_str[1000];
|
||||
(void) sprintf(env_uri_str, "%s=%s", DDSC_PROJECT_NAME_NOSPACE_CAPS"_URI", CONFIG_ENV_SIMPLE_UDP);
|
||||
os_putenv(env_uri_str);
|
||||
|
||||
static char env_mp_str[100];
|
||||
(void) sprintf(env_mp_str, "%s=%s", "MAX_PARTICIPANTS", CONFIG_ENV_MAX_PARTICIPANTS);
|
||||
os_putenv(env_mp_str);
|
||||
|
||||
|
||||
const char * env_uri = os_getenv(DDSC_PROJECT_NAME_NOSPACE_CAPS"_URI");
|
||||
cr_assert_neq(env_uri, NULL, DDSC_PROJECT_NAME_NOSPACE_CAPS"_URI must be set");
|
||||
|
||||
//invalid domain
|
||||
participant = dds_create_participant (1, NULL, NULL);
|
||||
cr_assert_lt(participant, 0, "Error must be received for invalid domain value");
|
||||
|
||||
//valid specific domain value
|
||||
participant2 = dds_create_participant (valid_domain, NULL, NULL);
|
||||
cr_assert_gt(participant2, 0, "Valid participant must be received for valid specific domain value");
|
||||
status = dds_get_domainid(participant2, &domain_id);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_domainid(participant, domain_id)");
|
||||
cr_assert_eq(domain_id, valid_domain, "Retrieved domain ID must be valid");
|
||||
|
||||
|
||||
//DDS_DOMAIN_DEFAULT from the user
|
||||
participant3 = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant3, 0, "Valid participant must be received for DDS_DOMAIN_DEFAULT");
|
||||
status = dds_get_domainid(participant3, &domain_id);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_domainid(participant, domain_id)");
|
||||
cr_assert_eq(domain_id, valid_domain, "Retrieved domain ID must be valid");
|
||||
|
||||
dds_delete(participant2);
|
||||
dds_delete(participant3);
|
||||
|
||||
|
||||
}
|
||||
|
||||
Test(ddsc_participant_lookup, one) {
|
||||
|
||||
dds_entity_t participant;
|
||||
dds_entity_t participants[3];
|
||||
dds_domainid_t domain_id;
|
||||
dds_return_t status, num_of_found_pp;
|
||||
size_t size = 3;
|
||||
|
||||
/* Create a participant */
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "dds_participant_create");
|
||||
|
||||
/* Get domain id */
|
||||
status = dds_get_domainid(participant, &domain_id);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_domainid(participant, domain_id)");
|
||||
|
||||
num_of_found_pp = dds_lookup_participant( domain_id, participants, size);
|
||||
cr_assert_eq(num_of_found_pp, 1, "dds_lookup_participant(domain_id, participants, size)");
|
||||
cr_assert_eq(participants[0], participant,"dds_lookup_participant did not return the participant");
|
||||
|
||||
dds_delete (participant);
|
||||
}
|
||||
|
||||
Test(ddsc_participant_lookup, multiple) {
|
||||
|
||||
dds_entity_t participant, participant2;
|
||||
dds_entity_t participants[2];
|
||||
dds_domainid_t domain_id;
|
||||
dds_return_t status, num_of_found_pp;
|
||||
size_t size = 2;
|
||||
|
||||
/* Create participants */
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "dds_participant_create");
|
||||
|
||||
participant2 = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant2, 0, "dds_participant_create");
|
||||
|
||||
/* Get domain id */
|
||||
status = dds_get_domainid(participant, &domain_id);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_domainid(participant, domain_id)");
|
||||
|
||||
num_of_found_pp = dds_lookup_participant( domain_id, participants, size);
|
||||
cr_assert_eq(num_of_found_pp, 2, "dds_lookup_participant(domain_id, participants, size)");
|
||||
cr_assert(participants[0] == participant || participants[0] == participant2,"ddsc_participant_lookup");
|
||||
cr_assert(participants[1] == participant || participants[1] == participant2,"ddsc_participant_lookup");
|
||||
cr_assert_neq(participants[0], participants[1], "dds_lookup_participant returned a participant twice");
|
||||
|
||||
dds_delete (participant2);
|
||||
dds_delete (participant);
|
||||
}
|
||||
|
||||
Test(ddsc_participant_lookup, array_too_small) {
|
||||
|
||||
dds_entity_t participant, participant2, participant3;
|
||||
dds_entity_t participants[2];
|
||||
dds_domainid_t domain_id;
|
||||
dds_return_t status, num_of_found_pp;
|
||||
size_t size = 2;
|
||||
|
||||
/* Create participants */
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "dds_participant_create");
|
||||
|
||||
participant2 = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant2, 0, "dds_participant_create");
|
||||
|
||||
participant3 = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant3, 0, "dds_participant_create");
|
||||
|
||||
/* Get domain id */
|
||||
status = dds_get_domainid(participant, &domain_id);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_domainid(participant, domain_id)");
|
||||
|
||||
num_of_found_pp = dds_lookup_participant( domain_id, participants, size);
|
||||
cr_assert_eq(num_of_found_pp, 3, "dds_lookup_participant(domain_id, participants, size)");
|
||||
cr_assert(participants[0] == participant || participants[0] == participant2 || participants[0] == participant3,"ddsc_participant_lookup");
|
||||
cr_assert(participants[1] == participant || participants[1] == participant2 || participants[1] == participant3,"ddsc_participant_lookup");
|
||||
cr_assert_neq(participants[0], participants[1], "dds_lookup_participant returned a participant twice");
|
||||
|
||||
dds_delete (participant3);
|
||||
dds_delete (participant2);
|
||||
dds_delete (participant);
|
||||
}
|
||||
|
||||
Test(ddsc_participant_lookup, null_zero){
|
||||
|
||||
dds_entity_t participant;
|
||||
dds_domainid_t domain_id;
|
||||
dds_return_t status, num_of_found_pp;
|
||||
size_t size = 0;
|
||||
|
||||
/* Create a participant */
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "dds_participant_create");
|
||||
|
||||
/* Get domain id */
|
||||
status = dds_get_domainid(participant, &domain_id);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_domainid(participant, domain_id)");
|
||||
|
||||
num_of_found_pp = dds_lookup_participant( domain_id, NULL, size);
|
||||
cr_assert_eq(num_of_found_pp, 1, "dds_lookup_participant(domain_id, participants, size)");
|
||||
|
||||
dds_delete (participant);
|
||||
}
|
||||
|
||||
Test(ddsc_participant_lookup, null_nonzero){
|
||||
|
||||
dds_entity_t participant;
|
||||
dds_domainid_t domain_id;
|
||||
dds_return_t status, num_of_found_pp;
|
||||
size_t size = 2;
|
||||
|
||||
/* Create a participant */
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "dds_participant_create");
|
||||
|
||||
/* Get domain id */
|
||||
status = dds_get_domainid(participant, &domain_id);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_domainid(participant, domain_id)");
|
||||
|
||||
num_of_found_pp = dds_lookup_participant( domain_id, NULL, size);
|
||||
cr_assert_status_eq(num_of_found_pp, DDS_RETCODE_BAD_PARAMETER, "dds_lookup_participant did not return bad parameter");
|
||||
|
||||
dds_delete (participant);
|
||||
}
|
||||
|
||||
Test(ddsc_participant_lookup, unknown_id) {
|
||||
|
||||
dds_entity_t participant;
|
||||
dds_entity_t participants[3];
|
||||
dds_domainid_t domain_id;
|
||||
dds_return_t status, num_of_found_pp;
|
||||
size_t size = 3;
|
||||
|
||||
/* Create a participant */
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "dds_participant_create");
|
||||
|
||||
/* Get domain id */
|
||||
status = dds_get_domainid(participant, &domain_id);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_domainid(participant, domain_id)");
|
||||
domain_id ++;
|
||||
|
||||
num_of_found_pp = dds_lookup_participant( domain_id, participants, size);
|
||||
cr_assert_eq(num_of_found_pp, 0, "dds_lookup_participant(domain_id, participants, size)");
|
||||
|
||||
dds_delete (participant);
|
||||
}
|
||||
|
||||
Test(ddsc_participant_lookup, none) {
|
||||
|
||||
dds_entity_t participants[2];
|
||||
dds_return_t num_of_found_pp;
|
||||
size_t size = 2;
|
||||
|
||||
num_of_found_pp = dds_lookup_participant( 0, participants, size);
|
||||
cr_assert_eq(num_of_found_pp, 0, "dds_lookup_participant did not return 0");
|
||||
}
|
||||
|
||||
Test(ddsc_participant_lookup, no_more) {
|
||||
|
||||
dds_entity_t participant;
|
||||
dds_entity_t participants[3];
|
||||
dds_domainid_t domain_id;
|
||||
dds_return_t status, num_of_found_pp;
|
||||
size_t size = 3;
|
||||
|
||||
/* Create a participant */
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "dds_participant_create");
|
||||
|
||||
/* Get domain id */
|
||||
status = dds_get_domainid(participant, &domain_id);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_domainid(participant, domain_id)");
|
||||
|
||||
dds_delete (participant);
|
||||
|
||||
num_of_found_pp = dds_lookup_participant( domain_id, participants, size);
|
||||
cr_assert_eq(num_of_found_pp, 0, "dds_lookup_participant did not return 0");
|
||||
}
|
||||
|
||||
Test(ddsc_participant_lookup, deleted) {
|
||||
|
||||
dds_entity_t participant, participant2;
|
||||
dds_entity_t participants[2];
|
||||
dds_domainid_t domain_id;
|
||||
dds_return_t status, num_of_found_pp;
|
||||
size_t size = 2;
|
||||
|
||||
/* Create participants */
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "dds_participant_create");
|
||||
|
||||
participant2 = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant2, 0, "dds_participant_create");
|
||||
|
||||
/* Get domain id */
|
||||
status = dds_get_domainid(participant, &domain_id);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_OK, "dds_get_domainid(participant, domain_id)");
|
||||
|
||||
dds_delete (participant2);
|
||||
|
||||
num_of_found_pp = dds_lookup_participant( domain_id, participants, size);
|
||||
cr_assert_eq(num_of_found_pp, 1, "dds_lookup_participant did not return one participant");
|
||||
cr_assert(participants[0] == participant,"ddsc_participant_lookup");
|
||||
|
||||
dds_delete (participant);
|
||||
}
|
||||
268
src/core/ddsc/tests/publisher.c
Normal file
268
src/core/ddsc/tests/publisher.c
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
* 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 "ddsc/dds.h"
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/logging.h>
|
||||
|
||||
/* We are deliberately testing some bad arguments that SAL will complain about.
|
||||
* So, silence SAL regarding these issues. */
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 28020)
|
||||
|
||||
|
||||
#define cr_assert_status_eq(s1, s2, ...) cr_assert_eq(dds_err_nr(s1), s2, __VA_ARGS__)
|
||||
|
||||
/* Dummy callback */
|
||||
static void data_available_cb(dds_entity_t reader, void* arg) {}
|
||||
|
||||
|
||||
Test(ddsc_publisher, create)
|
||||
{
|
||||
const char *singlePartitions[] = { "partition" };
|
||||
const char *multiplePartitions[] = { "partition1", "partition2" };
|
||||
const char *duplicatePartitions[] = { "partition", "partition" };
|
||||
|
||||
dds_entity_t participant;
|
||||
dds_entity_t publisher, publisher1;
|
||||
dds_listener_t *listener;
|
||||
dds_qos_t *qos;
|
||||
|
||||
/* Use NULL participant */
|
||||
publisher = dds_create_publisher(0, NULL, NULL);
|
||||
cr_assert_eq(dds_err_nr(publisher), DDS_RETCODE_BAD_PARAMETER, "dds_create_publisher(NULL,NULL,NULL)");
|
||||
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "dds_create_participant(DDS_DOMAIN_DEFAULT,NULL,NULL)");
|
||||
|
||||
/* Use non-null participant */
|
||||
publisher = dds_create_publisher(participant, NULL, NULL);
|
||||
cr_assert_gt(publisher, 0, "dds_create_publisher(participant,NULL,NULL)");
|
||||
|
||||
/* Use entity that is not a participant */
|
||||
publisher1 = dds_create_publisher(publisher, NULL, NULL);
|
||||
cr_assert_eq(dds_err_nr(publisher1), DDS_RETCODE_ILLEGAL_OPERATION, "dds_create_publisher(publisher,NULL,NULL)");
|
||||
dds_delete(publisher);
|
||||
|
||||
/* Create a non-null qos */
|
||||
qos = dds_qos_create();
|
||||
cr_assert_neq(qos, NULL, "dds_qos_create()");
|
||||
|
||||
/* Use qos without partition; in that case the default partition should be used */
|
||||
publisher = dds_create_publisher(participant, qos, NULL);
|
||||
cr_assert_gt(publisher, 0, "dds_create_publisher(participant,qos,NULL) where qos with default partition");
|
||||
dds_delete(publisher);
|
||||
|
||||
/* Somehow, the compiler thinks the char arrays might not be zero-terminated... */
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 6054)
|
||||
|
||||
/* Use qos with single partition */
|
||||
dds_qset_partition (qos, 1, singlePartitions);
|
||||
publisher = dds_create_publisher(participant, qos, NULL);
|
||||
cr_assert_gt(publisher, 0, "dds_create_publisher(participant,qos,NULL) where qos with single partition");
|
||||
dds_delete(publisher);
|
||||
|
||||
/* Use qos with multiple partitions */
|
||||
dds_qset_partition (qos, 2, multiplePartitions);
|
||||
publisher = dds_create_publisher(participant, qos, NULL);
|
||||
cr_assert_gt(publisher, 0, "dds_create_publisher(participant,qos,NULL) where qos with multiple partitions");
|
||||
dds_delete(publisher);
|
||||
|
||||
/* Use qos with multiple partitions */
|
||||
dds_qset_partition (qos, 2, duplicatePartitions);
|
||||
publisher = dds_create_publisher(participant, qos, NULL);
|
||||
cr_assert_gt(publisher, 0, "dds_create_publisher(participant,qos,NULL) where qos with duplicate partitions");
|
||||
dds_delete(publisher);
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
/* Use listener(NULL) */
|
||||
listener = dds_listener_create(NULL);
|
||||
cr_assert_neq(listener, NULL, "dds_listener_create(NULL)");
|
||||
publisher = dds_create_publisher(participant, NULL, listener);
|
||||
cr_assert_gt(publisher, 0, "dds_create_publisher(participant,NULL,listener(NULL))");
|
||||
dds_delete(publisher);
|
||||
|
||||
dds_listener_reset(listener);
|
||||
|
||||
/* Use listener for data_available */
|
||||
dds_lset_data_available(listener, NULL);
|
||||
publisher = dds_create_publisher(participant, NULL, listener);
|
||||
cr_assert_gt(publisher, 0, "dds_create_publisher(participant,NULL,listener) with dds_lset_data_available(listener, NULL)");
|
||||
dds_delete(publisher);
|
||||
|
||||
dds_listener_reset(listener);
|
||||
|
||||
/* Use DDS_LUNSET for data_available */
|
||||
dds_lset_data_available(listener, DDS_LUNSET);
|
||||
publisher = dds_create_publisher(participant, NULL, listener);
|
||||
cr_assert_gt(publisher, 0, "dds_create_publisher(participant,NULL,listener) with dds_lset_data_available(listener, DDS_LUNSET)");
|
||||
dds_delete(publisher);
|
||||
|
||||
dds_listener_reset(listener);
|
||||
|
||||
/* Use callback for data_available */
|
||||
dds_lset_data_available(listener, data_available_cb);
|
||||
publisher = dds_create_publisher(participant, NULL, listener);
|
||||
cr_assert_gt(publisher, 0, "dds_create_publisher(participant,NULL,listener) with dds_lset_data_available(listener, data_available_cb)");
|
||||
dds_delete(publisher);
|
||||
|
||||
/* Use both qos setting and callback listener */
|
||||
dds_lset_data_available(listener, data_available_cb);
|
||||
publisher = dds_create_publisher(participant, qos, listener);
|
||||
cr_assert_gt(publisher, 0, "dds_create_publisher(participant,qos,listener) with dds_lset_data_available(listener, data_available_cb)");
|
||||
dds_delete(publisher);
|
||||
|
||||
dds_listener_delete(listener);
|
||||
dds_qos_delete(qos);
|
||||
dds_delete (participant);
|
||||
}
|
||||
|
||||
Test(ddsc_publisher, suspend_resume)
|
||||
{
|
||||
|
||||
dds_entity_t participant, publisher;
|
||||
dds_return_t status;
|
||||
|
||||
/* Suspend a 0 publisher */
|
||||
status = dds_suspend(0);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_suspend(NULL)");
|
||||
|
||||
/* Resume a 0 publisher */
|
||||
status = dds_resume(0);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_resume(NULL)");
|
||||
|
||||
/* Uae dds_suspend on something else than a publisher */
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "dds_create_participant(DDS_DOMAIN_DEFAULT,NULL,NULL)");
|
||||
status = dds_suspend(participant);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_suspend(participant)");
|
||||
|
||||
/* Use dds_resume on something else than a publisher */
|
||||
status = dds_resume(participant);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_resume(participant)");
|
||||
|
||||
/* Use dds_resume without calling dds_suspend */
|
||||
publisher = dds_create_publisher(participant, NULL, NULL);
|
||||
cr_assert_gt(publisher, 0, "dds_create_publisher(participant,NULL,NULL)");
|
||||
status = dds_resume(publisher); /* Should be precondition not met? */
|
||||
cr_assert_status_eq(status, DDS_RETCODE_UNSUPPORTED, "dds_resume(publisher) without prior suspend");
|
||||
|
||||
/* Use dds_suspend on non-null publisher */
|
||||
status = dds_suspend(publisher);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_UNSUPPORTED, "dds_suspend(publisher)");
|
||||
|
||||
/* Use dds_resume on non-null publisher */
|
||||
status = dds_resume(publisher);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_UNSUPPORTED, "dds_resume(publisher)");
|
||||
|
||||
dds_delete(publisher);
|
||||
dds_delete(participant);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Test(ddsc_publisher, wait_for_acks)
|
||||
{
|
||||
dds_entity_t participant, publisher;
|
||||
dds_return_t status;
|
||||
dds_duration_t zeroSec = ((dds_duration_t)DDS_SECS(0));
|
||||
dds_duration_t oneSec = ((dds_duration_t)DDS_SECS(1));
|
||||
dds_duration_t minusOneSec = ((dds_duration_t)DDS_SECS(-1));
|
||||
|
||||
/* Wait_for_acks on 0 publisher or writer and minusOneSec timeout */
|
||||
status = dds_wait_for_acks(0, minusOneSec);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_wait_for_acks(NULL,-1)");
|
||||
|
||||
/* Wait_for_acks on NULL publisher or writer and zeroSec timeout */
|
||||
status = dds_wait_for_acks(0, zeroSec);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_wait_for_acks(NULL,0)");
|
||||
|
||||
/* wait_for_acks on NULL publisher or writer and oneSec timeout */
|
||||
status = dds_wait_for_acks(0, oneSec);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_wait_for_acks(NULL,1)");
|
||||
|
||||
/* wait_for_acks on NULL publisher or writer and DDS_INFINITE timeout */
|
||||
status = dds_wait_for_acks(0, DDS_INFINITY);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_wait_for_acks(NULL,DDS_INFINITY)");
|
||||
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "dds_create_participant(DDS_DOMAIN_DEFAULT,NULL,NULL)");
|
||||
|
||||
/* Wait_for_acks on participant and minusOneSec timeout */
|
||||
status = dds_wait_for_acks(participant, minusOneSec);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_wait_for_acks(participant,-1)");
|
||||
|
||||
/* Wait_for_acks on participant and zeroSec timeout */
|
||||
status = dds_wait_for_acks(participant, zeroSec);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_wait_for_acks(participant,0)");
|
||||
|
||||
/* Wait_for_acks on participant and oneSec timeout */
|
||||
status = dds_wait_for_acks(participant, oneSec);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_wait_for_acks(participant,1)");
|
||||
|
||||
/* Wait_for_acks on participant and DDS_INFINITE timeout */
|
||||
status = dds_wait_for_acks(participant, DDS_INFINITY);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_BAD_PARAMETER, "dds_wait_for_acks(participant,DDS_INFINITY)");
|
||||
|
||||
publisher = dds_create_publisher(participant, NULL, NULL);
|
||||
cr_assert_gt(publisher, 0, "dds_create_publisher(participant,NULL,NULL)");
|
||||
|
||||
/* Wait_for_acks on publisher and minusOneSec timeout */
|
||||
status = dds_wait_for_acks(publisher, minusOneSec);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_UNSUPPORTED, "dds_wait_for_acks(publisher,-1)");
|
||||
|
||||
/* Wait_for_acks on publisher and zeroSec timeout */
|
||||
status = dds_wait_for_acks(publisher, zeroSec);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_UNSUPPORTED, "dds_wait_for_acks(publisher,0)");
|
||||
|
||||
/* Wait_for_acks on publisher and oneSec timeout */
|
||||
status = dds_wait_for_acks(publisher, oneSec);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_UNSUPPORTED, "dds_wait_for_acks(publisher,1)");
|
||||
|
||||
/* Wait_for_acks on publisher and DDS_INFINITE timeout */
|
||||
status = dds_wait_for_acks(publisher, DDS_INFINITY);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_UNSUPPORTED, "dds_wait_for_acks(publisher,DDS_INFINITY)");
|
||||
|
||||
/* TODO: create tests by calling dds_qwait_for_acks on writers */
|
||||
|
||||
status = dds_suspend(publisher);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_UNSUPPORTED, "dds_suspend(publisher)");
|
||||
|
||||
/* Wait_for_acks on suspended publisher and minusOneSec timeout */
|
||||
status = dds_wait_for_acks(publisher, minusOneSec);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_UNSUPPORTED, "dds_wait_for_acks(suspended_publisher,-1)");
|
||||
|
||||
/* Wait_for_acks on suspended publisher and zeroSec timeout */
|
||||
status = dds_wait_for_acks(publisher, zeroSec);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_UNSUPPORTED, "dds_wait_for_acks(suspended_publisher,0)");
|
||||
|
||||
/* Wait_for_acks on suspended publisher and oneSec timeout */
|
||||
status = dds_wait_for_acks(publisher, oneSec);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_UNSUPPORTED, "dds_wait_for_acks(suspended_publisher,1)");
|
||||
|
||||
/* Wait_for_acks on suspended publisher and DDS_INFINITE timeout */
|
||||
status = dds_wait_for_acks(publisher, DDS_INFINITY);
|
||||
cr_assert_status_eq(status, DDS_RETCODE_UNSUPPORTED, "dds_wait_for_acks(suspended_publisher,DDS_INFINITY)");
|
||||
|
||||
dds_delete(publisher);
|
||||
dds_delete(participant);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Test(ddsc_publisher, coherency)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
621
src/core/ddsc/tests/qos.c
Normal file
621
src/core/ddsc/tests/qos.c
Normal file
|
|
@ -0,0 +1,621 @@
|
|||
/*
|
||||
* 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 "ddsc/dds.h"
|
||||
#include "os/os.h"
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/logging.h>
|
||||
|
||||
|
||||
#if 0
|
||||
#else
|
||||
/* We are deliberately testing some bad arguments that SAL will complain about.
|
||||
* So, silence SAL regarding these issues. */
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 6387 28020)
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Convenience global policies
|
||||
****************************************************************************/
|
||||
struct pol_userdata {
|
||||
void *value;
|
||||
size_t sz;
|
||||
};
|
||||
|
||||
struct pol_topicdata {
|
||||
void *value;
|
||||
size_t sz;
|
||||
};
|
||||
|
||||
struct pol_groupdata {
|
||||
void *value;
|
||||
size_t sz;
|
||||
};
|
||||
|
||||
struct pol_durability {
|
||||
dds_durability_kind_t kind;
|
||||
};
|
||||
|
||||
struct pol_history {
|
||||
dds_history_kind_t kind;
|
||||
int32_t depth;
|
||||
};
|
||||
|
||||
struct pol_resource_limits {
|
||||
int32_t max_samples;
|
||||
int32_t max_instances;
|
||||
int32_t max_samples_per_instance;
|
||||
};
|
||||
|
||||
struct pol_presentation {
|
||||
dds_presentation_access_scope_kind_t access_scope;
|
||||
bool coherent_access;
|
||||
bool ordered_access;
|
||||
};
|
||||
|
||||
struct pol_lifespan {
|
||||
dds_duration_t lifespan;
|
||||
};
|
||||
|
||||
struct pol_deadline {
|
||||
dds_duration_t deadline;
|
||||
};
|
||||
|
||||
struct pol_latency_budget {
|
||||
dds_duration_t duration;
|
||||
};
|
||||
|
||||
struct pol_ownership {
|
||||
dds_ownership_kind_t kind;
|
||||
};
|
||||
|
||||
struct pol_ownership_strength {
|
||||
int32_t value;
|
||||
};
|
||||
|
||||
struct pol_liveliness {
|
||||
dds_liveliness_kind_t kind;
|
||||
dds_duration_t lease_duration;
|
||||
};
|
||||
|
||||
struct pol_time_based_filter {
|
||||
dds_duration_t minimum_separation;
|
||||
};
|
||||
|
||||
struct pol_partition {
|
||||
uint32_t n;
|
||||
char **ps;
|
||||
};
|
||||
|
||||
struct pol_reliability {
|
||||
dds_reliability_kind_t kind;
|
||||
dds_duration_t max_blocking_time;
|
||||
};
|
||||
|
||||
struct pol_transport_priority {
|
||||
int32_t value;
|
||||
};
|
||||
|
||||
struct pol_destination_order {
|
||||
dds_destination_order_kind_t kind;
|
||||
};
|
||||
|
||||
struct pol_writer_data_lifecycle {
|
||||
bool autodispose;
|
||||
};
|
||||
|
||||
struct pol_reader_data_lifecycle {
|
||||
dds_duration_t autopurge_nowriter_samples_delay;
|
||||
dds_duration_t autopurge_disposed_samples_delay;
|
||||
};
|
||||
|
||||
struct pol_durability_service {
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct pol_userdata g_pol_userdata;
|
||||
static struct pol_topicdata g_pol_topicdata;
|
||||
static struct pol_groupdata g_pol_groupdata;
|
||||
static struct pol_durability g_pol_durability;
|
||||
static struct pol_history g_pol_history;
|
||||
static struct pol_resource_limits g_pol_resource_limits;
|
||||
static struct pol_presentation g_pol_presentation;
|
||||
static struct pol_lifespan g_pol_lifespan;
|
||||
static struct pol_deadline g_pol_deadline;
|
||||
static struct pol_latency_budget g_pol_latency_budget;
|
||||
static struct pol_ownership g_pol_ownership;
|
||||
static struct pol_ownership_strength g_pol_ownership_strength;
|
||||
static struct pol_liveliness g_pol_liveliness;
|
||||
static struct pol_time_based_filter g_pol_time_based_filter;
|
||||
static struct pol_partition g_pol_partition;
|
||||
static struct pol_reliability g_pol_reliability;
|
||||
static struct pol_transport_priority g_pol_transport_priority;
|
||||
static struct pol_destination_order g_pol_destination_order;
|
||||
static struct pol_writer_data_lifecycle g_pol_writer_data_lifecycle;
|
||||
static struct pol_reader_data_lifecycle g_pol_reader_data_lifecycle;
|
||||
static struct pol_durability_service g_pol_durability_service;
|
||||
|
||||
|
||||
|
||||
static const char* c_userdata = "user_key";
|
||||
static const char* c_topicdata = "topic_key";
|
||||
static const char* c_groupdata = "group_key";
|
||||
static const char* c_partitions[] = {"Partition1", "Partition2"};
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Test initializations and teardowns.
|
||||
****************************************************************************/
|
||||
static dds_qos_t *g_qos = NULL;
|
||||
|
||||
static void
|
||||
qos_init(void)
|
||||
{
|
||||
g_qos = dds_qos_create();
|
||||
cr_assert_not_null(g_qos);
|
||||
|
||||
g_pol_userdata.value = (void*)c_userdata;
|
||||
g_pol_userdata.sz = strlen((char*)g_pol_userdata.value) + 1;
|
||||
|
||||
g_pol_topicdata.value = (void*)c_topicdata;
|
||||
g_pol_topicdata.sz = strlen((char*)g_pol_topicdata.value) + 1;
|
||||
|
||||
g_pol_groupdata.value = (void*)c_groupdata;
|
||||
g_pol_groupdata.sz = strlen((char*)g_pol_groupdata.value) + 1;
|
||||
|
||||
g_pol_durability.kind = DDS_DURABILITY_TRANSIENT;
|
||||
|
||||
g_pol_history.kind = DDS_HISTORY_KEEP_LAST;
|
||||
g_pol_history.depth = 1;
|
||||
|
||||
g_pol_resource_limits.max_samples = 1;
|
||||
g_pol_resource_limits.max_instances = 1;
|
||||
g_pol_resource_limits.max_samples_per_instance = 1;
|
||||
|
||||
g_pol_presentation.access_scope = DDS_PRESENTATION_INSTANCE;
|
||||
g_pol_presentation.coherent_access = true;
|
||||
g_pol_presentation.ordered_access = true;
|
||||
|
||||
g_pol_lifespan.lifespan = 10000;
|
||||
|
||||
g_pol_deadline.deadline = 20000;
|
||||
|
||||
g_pol_latency_budget.duration = 30000;
|
||||
|
||||
g_pol_ownership.kind = DDS_OWNERSHIP_EXCLUSIVE;
|
||||
|
||||
g_pol_ownership_strength.value = 10;
|
||||
|
||||
g_pol_liveliness.kind = DDS_LIVELINESS_AUTOMATIC;
|
||||
g_pol_liveliness.lease_duration = 40000;
|
||||
|
||||
g_pol_time_based_filter.minimum_separation = 50000;
|
||||
|
||||
g_pol_partition.ps = (char**)c_partitions;
|
||||
g_pol_partition.n = 2;
|
||||
|
||||
g_pol_reliability.kind = DDS_RELIABILITY_RELIABLE;
|
||||
g_pol_reliability.max_blocking_time = 60000;
|
||||
|
||||
g_pol_transport_priority.value = 42;
|
||||
|
||||
g_pol_destination_order.kind = DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP;
|
||||
|
||||
g_pol_writer_data_lifecycle.autodispose = true;
|
||||
|
||||
g_pol_reader_data_lifecycle.autopurge_disposed_samples_delay = 70000;
|
||||
g_pol_reader_data_lifecycle.autopurge_nowriter_samples_delay = 80000;
|
||||
|
||||
g_pol_durability_service.history_depth = 1;
|
||||
g_pol_durability_service.history_kind = DDS_HISTORY_KEEP_LAST;
|
||||
g_pol_durability_service.max_samples = 2;
|
||||
g_pol_durability_service.max_instances = 3;
|
||||
g_pol_durability_service.max_samples_per_instance = 4;
|
||||
g_pol_durability_service.service_cleanup_delay = 90000;
|
||||
}
|
||||
|
||||
static void
|
||||
qos_fini(void)
|
||||
{
|
||||
dds_qos_delete(g_qos);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* API tests
|
||||
****************************************************************************/
|
||||
Test(ddsc_qos, userdata, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_userdata p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_userdata(NULL, g_pol_userdata.value, g_pol_userdata.sz);
|
||||
dds_qget_userdata(NULL, &p.value, &p.sz);
|
||||
dds_qget_userdata(g_qos, NULL, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_userdata(g_qos, g_pol_userdata.value, g_pol_userdata.sz);
|
||||
dds_qget_userdata(g_qos, &p.value, &p.sz);
|
||||
cr_assert_eq(p.sz, g_pol_userdata.sz);
|
||||
cr_assert_str_eq(p.value, g_pol_userdata.value);
|
||||
|
||||
dds_free(p.value);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, topicdata, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_topicdata p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_topicdata(NULL, g_pol_topicdata.value, g_pol_topicdata.sz);
|
||||
dds_qget_topicdata(NULL, &p.value, &p.sz);
|
||||
dds_qget_topicdata(g_qos, NULL, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_topicdata(g_qos, g_pol_topicdata.value, g_pol_topicdata.sz);
|
||||
dds_qget_topicdata(g_qos, &p.value, &p.sz);
|
||||
cr_assert_eq(p.sz, g_pol_topicdata.sz);
|
||||
cr_assert_str_eq(p.value, g_pol_topicdata.value);
|
||||
|
||||
dds_free(p.value);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, groupdata, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_groupdata p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_groupdata(NULL, g_pol_groupdata.value, g_pol_groupdata.sz);
|
||||
dds_qget_groupdata(NULL, &p.value, &p.sz);
|
||||
dds_qget_groupdata(g_qos, NULL, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_groupdata(g_qos, g_pol_groupdata.value, g_pol_groupdata.sz);
|
||||
dds_qget_groupdata(g_qos, &p.value, &p.sz);
|
||||
cr_assert_eq(p.sz, g_pol_groupdata.sz);
|
||||
cr_assert_str_eq(p.value, g_pol_groupdata.value);
|
||||
|
||||
dds_free(p.value);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, durability, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_durability p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_durability(NULL, g_pol_durability.kind);
|
||||
dds_qget_durability(NULL, &p.kind);
|
||||
dds_qget_durability(g_qos, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_durability(g_qos, g_pol_durability.kind);
|
||||
dds_qget_durability(g_qos, &p.kind);
|
||||
cr_assert_eq(p.kind, g_pol_durability.kind);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, history, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_history p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_history(NULL, g_pol_history.kind, g_pol_history.depth);
|
||||
dds_qget_history(NULL, &p.kind, &p.depth);
|
||||
dds_qget_history(g_qos, NULL, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_history(g_qos, g_pol_history.kind, g_pol_history.depth);
|
||||
dds_qget_history(g_qos, &p.kind, &p.depth);
|
||||
cr_assert_eq(p.kind, g_pol_history.kind);
|
||||
cr_assert_eq(p.depth, g_pol_history.depth);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, resource_limits, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_resource_limits p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_resource_limits(NULL, g_pol_resource_limits.max_samples, g_pol_resource_limits.max_instances, g_pol_resource_limits.max_samples_per_instance);
|
||||
dds_qget_resource_limits(NULL, &p.max_samples, &p.max_instances, &p.max_samples_per_instance);
|
||||
dds_qget_resource_limits(g_qos, NULL, NULL, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_resource_limits(g_qos, g_pol_resource_limits.max_samples, g_pol_resource_limits.max_instances, g_pol_resource_limits.max_samples_per_instance);
|
||||
dds_qget_resource_limits(g_qos, &p.max_samples, &p.max_instances, &p.max_samples_per_instance);
|
||||
cr_assert_eq(p.max_samples, g_pol_resource_limits.max_samples);
|
||||
cr_assert_eq(p.max_instances, g_pol_resource_limits.max_instances);
|
||||
cr_assert_eq(p.max_samples_per_instance, g_pol_resource_limits.max_samples_per_instance);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, presentation, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_presentation p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_presentation(NULL, g_pol_presentation.access_scope, g_pol_presentation.coherent_access, g_pol_presentation.ordered_access);
|
||||
dds_qget_presentation(NULL, &p.access_scope, &p.coherent_access, &p.ordered_access);
|
||||
dds_qget_presentation(g_qos, NULL, NULL, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_presentation(g_qos, g_pol_presentation.access_scope, g_pol_presentation.coherent_access, g_pol_presentation.ordered_access);
|
||||
dds_qget_presentation(g_qos, &p.access_scope, &p.coherent_access, &p.ordered_access);
|
||||
cr_assert_eq(p.access_scope, g_pol_presentation.access_scope);
|
||||
cr_assert_eq(p.coherent_access, g_pol_presentation.coherent_access);
|
||||
cr_assert_eq(p.ordered_access, g_pol_presentation.ordered_access);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, lifespan, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_lifespan p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_lifespan(NULL, g_pol_lifespan.lifespan);
|
||||
dds_qget_lifespan(NULL, &p.lifespan);
|
||||
dds_qget_lifespan(g_qos, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_lifespan(g_qos, g_pol_lifespan.lifespan);
|
||||
dds_qget_lifespan(g_qos, &p.lifespan);
|
||||
cr_assert_eq(p.lifespan, g_pol_lifespan.lifespan);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, deadline, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_deadline p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_deadline(NULL, g_pol_deadline.deadline);
|
||||
dds_qget_deadline(NULL, &p.deadline);
|
||||
dds_qget_deadline(g_qos, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_deadline(g_qos, g_pol_deadline.deadline);
|
||||
dds_qget_deadline(g_qos, &p.deadline);
|
||||
cr_assert_eq(p.deadline, g_pol_deadline.deadline);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, latency_budget, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_latency_budget p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_latency_budget(NULL, g_pol_latency_budget.duration);
|
||||
dds_qget_latency_budget(NULL, &p.duration);
|
||||
dds_qget_latency_budget(g_qos, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_latency_budget(g_qos, g_pol_latency_budget.duration);
|
||||
dds_qget_latency_budget(g_qos, &p.duration);
|
||||
cr_assert_eq(p.duration, g_pol_latency_budget.duration);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, ownership, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_ownership p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_ownership(NULL, g_pol_ownership.kind);
|
||||
dds_qget_ownership(NULL, &p.kind);
|
||||
dds_qget_ownership(g_qos, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_ownership(g_qos, g_pol_ownership.kind);
|
||||
dds_qget_ownership(g_qos, &p.kind);
|
||||
cr_assert_eq(p.kind, g_pol_ownership.kind);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, ownership_strength, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_ownership_strength p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_ownership_strength(NULL, g_pol_ownership_strength.value);
|
||||
dds_qget_ownership_strength(NULL, &p.value);
|
||||
dds_qget_ownership_strength(g_qos, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_ownership_strength(g_qos, g_pol_ownership_strength.value);
|
||||
dds_qget_ownership_strength(g_qos, &p.value);
|
||||
cr_assert_eq(p.value, g_pol_ownership_strength.value);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, liveliness, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_liveliness p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_liveliness(NULL, g_pol_liveliness.kind, g_pol_liveliness.lease_duration);
|
||||
dds_qget_liveliness(NULL, &p.kind, &p.lease_duration);
|
||||
dds_qget_liveliness(g_qos, NULL, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_liveliness(g_qos, g_pol_liveliness.kind, g_pol_liveliness.lease_duration);
|
||||
dds_qget_liveliness(g_qos, &p.kind, &p.lease_duration);
|
||||
cr_assert_eq(p.kind, g_pol_liveliness.kind);
|
||||
cr_assert_eq(p.lease_duration, g_pol_liveliness.lease_duration);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, time_base_filter, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_time_based_filter p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_time_based_filter(NULL, g_pol_time_based_filter.minimum_separation);
|
||||
dds_qget_time_based_filter(NULL, &p.minimum_separation);
|
||||
dds_qget_time_based_filter(g_qos, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_time_based_filter(g_qos, g_pol_time_based_filter.minimum_separation);
|
||||
dds_qget_time_based_filter(g_qos, &p.minimum_separation);
|
||||
cr_assert_eq(p.minimum_separation, g_pol_time_based_filter.minimum_separation);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, partition, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_partition p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_partition(NULL, g_pol_partition.n, c_partitions);
|
||||
dds_qget_partition(NULL, &p.n, &p.ps);
|
||||
dds_qget_partition(g_qos, NULL, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_partition(g_qos, g_pol_partition.n, c_partitions);
|
||||
dds_qget_partition(g_qos, &p.n, &p.ps);
|
||||
cr_assert_eq(p.n, 2);
|
||||
cr_assert_eq(p.n, g_pol_partition.n);
|
||||
cr_assert_str_eq(p.ps[0], g_pol_partition.ps[0]);
|
||||
cr_assert_str_eq(p.ps[1], g_pol_partition.ps[1]);
|
||||
|
||||
dds_free(p.ps[0]);
|
||||
dds_free(p.ps[1]);
|
||||
dds_free(p.ps);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, reliability, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_reliability p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_reliability(NULL, g_pol_reliability.kind, g_pol_reliability.max_blocking_time);
|
||||
dds_qget_reliability(NULL, &p.kind, &p.max_blocking_time);
|
||||
dds_qget_reliability(g_qos, NULL, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_reliability(g_qos, g_pol_reliability.kind, g_pol_reliability.max_blocking_time);
|
||||
dds_qget_reliability(g_qos, &p.kind, &p.max_blocking_time);
|
||||
cr_assert_eq(p.kind, g_pol_reliability.kind);
|
||||
cr_assert_eq(p.max_blocking_time, g_pol_reliability.max_blocking_time);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, transport_priority, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_transport_priority p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_transport_priority(NULL, g_pol_transport_priority.value);
|
||||
dds_qget_transport_priority(NULL, &p.value);
|
||||
dds_qget_transport_priority(g_qos, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_transport_priority(g_qos, g_pol_transport_priority.value);
|
||||
dds_qget_transport_priority(g_qos, &p.value);
|
||||
cr_assert_eq(p.value, g_pol_transport_priority.value);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, destination_order, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_destination_order p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_destination_order(NULL, g_pol_destination_order.kind);
|
||||
dds_qget_destination_order(NULL, &p.kind);
|
||||
dds_qget_destination_order(g_qos, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_destination_order(g_qos, g_pol_destination_order.kind);
|
||||
dds_qget_destination_order(g_qos, &p.kind);
|
||||
cr_assert_eq(p.kind, g_pol_destination_order.kind);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, writer_data_lifecycle, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_writer_data_lifecycle p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_writer_data_lifecycle(NULL, g_pol_writer_data_lifecycle.autodispose);
|
||||
dds_qget_writer_data_lifecycle(NULL, &p.autodispose);
|
||||
dds_qget_writer_data_lifecycle(g_qos, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_writer_data_lifecycle(g_qos, g_pol_writer_data_lifecycle.autodispose);
|
||||
dds_qget_writer_data_lifecycle(g_qos, &p.autodispose);
|
||||
cr_assert_eq(p.autodispose, g_pol_writer_data_lifecycle.autodispose);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, reader_data_lifecycle, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_reader_data_lifecycle p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_reader_data_lifecycle(NULL, g_pol_reader_data_lifecycle.autopurge_nowriter_samples_delay, g_pol_reader_data_lifecycle.autopurge_disposed_samples_delay);
|
||||
dds_qget_reader_data_lifecycle(NULL, &p.autopurge_nowriter_samples_delay, &p.autopurge_disposed_samples_delay);
|
||||
dds_qget_reader_data_lifecycle(g_qos, NULL, NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_reader_data_lifecycle(g_qos, g_pol_reader_data_lifecycle.autopurge_nowriter_samples_delay, g_pol_reader_data_lifecycle.autopurge_disposed_samples_delay);
|
||||
dds_qget_reader_data_lifecycle(g_qos, &p.autopurge_nowriter_samples_delay, &p.autopurge_disposed_samples_delay);
|
||||
cr_assert_eq(p.autopurge_nowriter_samples_delay, g_pol_reader_data_lifecycle.autopurge_nowriter_samples_delay);
|
||||
cr_assert_eq(p.autopurge_disposed_samples_delay, g_pol_reader_data_lifecycle.autopurge_disposed_samples_delay);
|
||||
}
|
||||
|
||||
Test(ddsc_qos, durability_service, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
struct pol_durability_service p = { 0 };
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
dds_qset_durability_service(NULL,
|
||||
g_pol_durability_service.service_cleanup_delay,
|
||||
g_pol_durability_service.history_kind,
|
||||
g_pol_durability_service.history_depth,
|
||||
g_pol_durability_service.max_samples,
|
||||
g_pol_durability_service.max_instances,
|
||||
g_pol_durability_service.max_samples_per_instance);
|
||||
dds_qget_durability_service(NULL,
|
||||
&p.service_cleanup_delay,
|
||||
&p.history_kind,
|
||||
&p.history_depth,
|
||||
&p.max_samples,
|
||||
&p.max_instances,
|
||||
&p.max_samples_per_instance);
|
||||
dds_qget_durability_service(g_qos,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_durability_service(g_qos,
|
||||
g_pol_durability_service.service_cleanup_delay,
|
||||
g_pol_durability_service.history_kind,
|
||||
g_pol_durability_service.history_depth,
|
||||
g_pol_durability_service.max_samples,
|
||||
g_pol_durability_service.max_instances,
|
||||
g_pol_durability_service.max_samples_per_instance);
|
||||
dds_qget_durability_service(g_qos,
|
||||
&p.service_cleanup_delay,
|
||||
&p.history_kind,
|
||||
&p.history_depth,
|
||||
&p.max_samples,
|
||||
&p.max_instances,
|
||||
&p.max_samples_per_instance);
|
||||
cr_assert_eq(p.service_cleanup_delay, g_pol_durability_service.service_cleanup_delay);
|
||||
cr_assert_eq(p.history_kind, g_pol_durability_service.history_kind);
|
||||
cr_assert_eq(p.history_depth, g_pol_durability_service.history_depth);
|
||||
cr_assert_eq(p.max_samples, g_pol_durability_service.max_samples);
|
||||
cr_assert_eq(p.max_instances, g_pol_durability_service.max_instances);
|
||||
cr_assert_eq(p.max_samples_per_instance, g_pol_durability_service.max_samples_per_instance);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#pragma warning(pop)
|
||||
1521
src/core/ddsc/tests/querycondition.c
Normal file
1521
src/core/ddsc/tests/querycondition.c
Normal file
File diff suppressed because it is too large
Load diff
1258
src/core/ddsc/tests/read_instance.c
Normal file
1258
src/core/ddsc/tests/read_instance.c
Normal file
File diff suppressed because it is too large
Load diff
1514
src/core/ddsc/tests/readcondition.c
Normal file
1514
src/core/ddsc/tests/readcondition.c
Normal file
File diff suppressed because it is too large
Load diff
3208
src/core/ddsc/tests/reader.c
Normal file
3208
src/core/ddsc/tests/reader.c
Normal file
File diff suppressed because it is too large
Load diff
769
src/core/ddsc/tests/reader_iterator.c
Normal file
769
src/core/ddsc/tests/reader_iterator.c
Normal file
|
|
@ -0,0 +1,769 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
|
||||
#include "ddsc/dds.h"
|
||||
#include "os/os.h"
|
||||
#include "Space.h"
|
||||
#include "RoundTrip.h"
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/logging.h>
|
||||
#include <criterion/theories.h>
|
||||
|
||||
#if 0
|
||||
#define PRINT_SAMPLE(info, sample) cr_log_info("%s (%d, %d, %d)\n", info, sample.long_1, sample.long_2, sample.long_3);
|
||||
#else
|
||||
#define PRINT_SAMPLE(info, sample)
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* Test fixtures
|
||||
*
|
||||
*************************************************************************************************/
|
||||
|
||||
/*
|
||||
* By writing, disposing, unregistering, reading and re-writing, the following
|
||||
* data will be available in the reader history (but not in this order).
|
||||
* | long_1 | long_2 | long_3 | sst | vst | ist |
|
||||
* ----------------------------------------------------------
|
||||
* | 0 | 0 | 0 | not_read | new | alive |
|
||||
* | 0 | 1 | 2 | not_read | new | alive |
|
||||
* | 0 | 2 | 4 | not_read | new | alive |
|
||||
* | 1 | 3 | 6 | read | old | alive |
|
||||
* | 1 | 4 | 8 | read | old | alive |
|
||||
* | 1 | 5 | 10 | read | old | alive |
|
||||
* | 2 | 6 | 12 | not_read | old | alive |
|
||||
* | 2 | 7 | 14 | not_read | old | alive |
|
||||
* | 2 | 8 | 16 | read | old | alive |
|
||||
* | 3 | 9 | 18 | not_read | old | alive |
|
||||
* | 3 | 10 | 20 | read | old | alive |
|
||||
* | 3 | 11 | 22 | not_read | old | alive |
|
||||
* | 4 | 12 | 24 | read | old | alive |
|
||||
* | 4 | 13 | 26 | not_read | old | alive |
|
||||
* | 4 | 14 | 28 | not_read | old | alive |
|
||||
* | 5 | 15 | 30 | read | old | disposed |
|
||||
* | 5 | 16 | 32 | not_read | old | disposed |
|
||||
* | 5 | 17 | 34 | read | old | disposed |
|
||||
* | 6 | 18 | 36 | read | old | no_writers |
|
||||
* | 6 | 19 | 38 | not_read | old | no_writers |
|
||||
* | 6 | 20 | 40 | read | old | no_writers |
|
||||
*
|
||||
*/
|
||||
#define MAX_SAMPLES 21
|
||||
|
||||
#define RDR_NOT_READ_CNT 11
|
||||
int rdr_expected_long_2[RDR_NOT_READ_CNT] = { 0, 1, 2, 6, 7, 9, 11, 13, 14, 16, 19 };
|
||||
|
||||
/* Because we only read one sample at a time, only the first sample of an instance
|
||||
* can be new. This turns out to be only the very first sample. */
|
||||
#define SAMPLE_VST(long_2) ((long_2 == 0) ? DDS_VST_NEW : DDS_VST_OLD)
|
||||
|
||||
#define SAMPLE_IST(long_1) ((long_1 == 5) ? DDS_IST_NOT_ALIVE_DISPOSED : \
|
||||
(long_1 == 6) ? DDS_IST_NOT_ALIVE_NO_WRITERS : \
|
||||
DDS_IST_ALIVE )
|
||||
|
||||
static dds_entity_t g_participant = 0;
|
||||
static dds_entity_t g_subscriber = 0;
|
||||
static dds_entity_t g_publisher = 0;
|
||||
static dds_entity_t g_topic = 0;
|
||||
static dds_entity_t g_reader = 0;
|
||||
static dds_entity_t g_writer = 0;
|
||||
static dds_entity_t g_waitset = 0;
|
||||
static dds_entity_t g_rcond = 0;
|
||||
static dds_entity_t g_qcond = 0;
|
||||
|
||||
static void* g_loans[MAX_SAMPLES];
|
||||
static void* g_samples[MAX_SAMPLES];
|
||||
static Space_Type1 g_data[MAX_SAMPLES];
|
||||
static dds_sample_info_t g_info[MAX_SAMPLES];
|
||||
|
||||
static dds_instance_handle_t g_hdl_valid;
|
||||
static dds_instance_handle_t g_hdl_nil = DDS_HANDLE_NIL;
|
||||
|
||||
static char*
|
||||
create_topic_name(const char *prefix, char *name, size_t size)
|
||||
{
|
||||
/* Get semi random g_topic name. */
|
||||
os_procId pid = os_procIdSelf();
|
||||
uintmax_t tid = os_threadIdToInteger(os_threadIdSelf());
|
||||
(void) snprintf(name, size, "%s_pid%"PRIprocId"_tid%"PRIuMAX"", prefix, pid, tid);
|
||||
return name;
|
||||
}
|
||||
|
||||
static bool
|
||||
filter_init(const void * sample)
|
||||
{
|
||||
const Space_Type1 *s = sample;
|
||||
return ((s->long_2 == 3) ||
|
||||
(s->long_2 == 4) ||
|
||||
(s->long_2 == 5) ||
|
||||
(s->long_2 == 8) ||
|
||||
(s->long_2 == 10) ||
|
||||
(s->long_2 == 12) ||
|
||||
(s->long_2 == 15) ||
|
||||
(s->long_2 == 17) ||
|
||||
(s->long_2 == 18) ||
|
||||
(s->long_2 == 20));
|
||||
}
|
||||
|
||||
static bool
|
||||
filter_mod2(const void * sample)
|
||||
{
|
||||
const Space_Type1 *s = sample;
|
||||
return (s->long_2 % 2 == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
reader_iterator_init(void)
|
||||
{
|
||||
Space_Type1 sample = { 0 };
|
||||
dds_attach_t triggered;
|
||||
dds_return_t ret;
|
||||
char name[100];
|
||||
dds_qos_t *qos;
|
||||
|
||||
qos = dds_qos_create();
|
||||
cr_assert_not_null(qos, "Failed to create prerequisite qos");
|
||||
|
||||
g_participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(g_participant, 0, "Failed to create prerequisite g_participant");
|
||||
|
||||
g_subscriber = dds_create_subscriber(g_participant, NULL, NULL);
|
||||
cr_assert_gt(g_subscriber, 0, "Failed to create prerequisite g_subscriber");
|
||||
|
||||
g_publisher = dds_create_publisher(g_participant, NULL, NULL);
|
||||
cr_assert_gt(g_publisher, 0, "Failed to create prerequisite g_publisher");
|
||||
|
||||
g_waitset = dds_create_waitset(g_participant);
|
||||
cr_assert_gt(g_waitset, 0, "Failed to create g_waitset");
|
||||
|
||||
g_topic = dds_create_topic(g_participant, &Space_Type1_desc, create_topic_name("ddsc_read_iterator_test", name, sizeof name), NULL, NULL);
|
||||
cr_assert_gt(g_topic, 0, "Failed to create prerequisite g_topic");
|
||||
|
||||
/* Create a writer that will not automatically dispose unregistered samples. */
|
||||
dds_qset_writer_data_lifecycle(qos, false);
|
||||
g_writer = dds_create_writer(g_publisher, g_topic, qos, NULL);
|
||||
cr_assert_gt(g_writer, 0, "Failed to create prerequisite g_writer");
|
||||
|
||||
/* Create a reader that keeps all samples when not taken. */
|
||||
dds_qset_history(qos, DDS_HISTORY_KEEP_ALL, DDS_LENGTH_UNLIMITED);
|
||||
g_reader = dds_create_reader(g_subscriber, g_topic, qos, NULL);
|
||||
cr_assert_gt(g_reader, 0, "Failed to create prerequisite g_reader");
|
||||
|
||||
/* Create a read condition that only reads old samples. */
|
||||
g_rcond = dds_create_readcondition(g_reader, DDS_NOT_READ_SAMPLE_STATE | DDS_NOT_NEW_VIEW_STATE | DDS_ANY_INSTANCE_STATE);
|
||||
cr_assert_gt(g_rcond, 0, "Failed to create prerequisite g_rcond");
|
||||
|
||||
/* Create a query condition that only reads of instances mod2. */
|
||||
g_qcond = dds_create_querycondition(g_reader, DDS_NOT_READ_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE, filter_mod2);
|
||||
cr_assert_gt(g_qcond, 0, "Failed to create prerequisite g_qcond");
|
||||
|
||||
/* Sync g_reader to g_writer. */
|
||||
ret = dds_set_enabled_status(g_reader, DDS_SUBSCRIPTION_MATCHED_STATUS);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed to set prerequisite g_reader status");
|
||||
ret = dds_waitset_attach(g_waitset, g_reader, g_reader);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed to attach prerequisite g_reader");
|
||||
ret = dds_waitset_wait(g_waitset, &triggered, 1, DDS_SECS(1));
|
||||
cr_assert_eq(ret, 1, "Failed prerequisite dds_waitset_wait g_reader r");
|
||||
cr_assert_eq(g_reader, (dds_entity_t)(intptr_t)triggered, "Failed prerequisite dds_waitset_wait g_reader a");
|
||||
ret = dds_waitset_detach(g_waitset, g_reader);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed to detach prerequisite g_reader");
|
||||
|
||||
/* Sync g_writer to g_reader. */
|
||||
ret = dds_set_enabled_status(g_writer, DDS_PUBLICATION_MATCHED_STATUS);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed to set prerequisite g_writer status");
|
||||
ret = dds_waitset_attach(g_waitset, g_writer, g_writer);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed to attach prerequisite g_writer");
|
||||
ret = dds_waitset_wait(g_waitset, &triggered, 1, DDS_SECS(1));
|
||||
cr_assert_eq(ret, 1, "Failed prerequisite dds_waitset_wait g_writer r");
|
||||
cr_assert_eq(g_writer, (dds_entity_t)(intptr_t)triggered, "Failed prerequisite dds_waitset_wait g_writer a");
|
||||
ret = dds_waitset_detach(g_waitset, g_writer);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed to detach prerequisite g_writer");
|
||||
|
||||
/* Initialize reading buffers. */
|
||||
memset (g_data, 0, sizeof (g_data));
|
||||
for (int i = 0; i < MAX_SAMPLES; i++) {
|
||||
g_samples[i] = &g_data[i];
|
||||
}
|
||||
for (int i = 0; i < MAX_SAMPLES; i++) {
|
||||
g_loans[i] = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Write the samples. */
|
||||
for (int i = 0; i < MAX_SAMPLES; i++) {
|
||||
sample.long_1 = i/3;
|
||||
sample.long_2 = i;
|
||||
sample.long_3 = i*2;
|
||||
ret = dds_write(g_writer, &sample);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed prerequisite write");
|
||||
}
|
||||
/* | long_1 | long_2 | long_3 | sst | vst | ist |
|
||||
* -----------------------------------------------------
|
||||
* | 0 | 0 | 0 | not_read | new | alive |
|
||||
* | 0 | 1 | 2 | not_read | new | alive |
|
||||
* | 0 | 2 | 4 | not_read | new | alive |
|
||||
* | 1 | 3 | 6 | not_read | new | alive |
|
||||
* | 1 | 4 | 8 | not_read | new | alive |
|
||||
* | 1 | 5 | 10 | not_read | new | alive |
|
||||
* | 2 | 6 | 12 | not_read | new | alive |
|
||||
* | 2 | 7 | 14 | not_read | new | alive |
|
||||
* | 2 | 8 | 16 | not_read | new | alive |
|
||||
* | 3 | 9 | 18 | not_read | new | alive |
|
||||
* | 3 | 10 | 20 | not_read | new | alive |
|
||||
* | 3 | 11 | 22 | not_read | new | alive |
|
||||
* | 4 | 12 | 24 | not_read | new | alive |
|
||||
* | 4 | 13 | 26 | not_read | new | alive |
|
||||
* | 4 | 14 | 28 | not_read | new | alive |
|
||||
* | 5 | 15 | 30 | not_read | new | alive |
|
||||
* | 5 | 16 | 32 | not_read | new | alive |
|
||||
* | 5 | 17 | 34 | not_read | new | alive |
|
||||
* | 6 | 18 | 36 | not_read | new | alive |
|
||||
* | 6 | 19 | 38 | not_read | new | alive |
|
||||
* | 6 | 20 | 40 | not_read | new | alive |
|
||||
*/
|
||||
|
||||
/* Set the sst to read for the proper samples by using a query
|
||||
* condition that filters for these specific samples. */
|
||||
{
|
||||
dds_entity_t qcond = 0;
|
||||
|
||||
/* Create a query condition that reads the specific sample to get a set of 'read' samples after init. */
|
||||
qcond = dds_create_querycondition(g_reader, DDS_ANY_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE, filter_init);
|
||||
cr_assert_gt(g_qcond, 0, "Failed to create prerequisite qcond");
|
||||
|
||||
ret = dds_read(qcond, g_samples, g_info, MAX_SAMPLES, MAX_SAMPLES);
|
||||
cr_assert_gt(ret, 0, "Failed prerequisite read: %d", dds_err_nr(ret));
|
||||
|
||||
dds_delete(qcond);
|
||||
}
|
||||
/* | long_1 | long_2 | long_3 | sst | vst | ist |
|
||||
* -----------------------------------------------------
|
||||
* | 0 | 0 | 0 | not_read | new | alive |
|
||||
* | 0 | 1 | 2 | not_read | new | alive |
|
||||
* | 0 | 2 | 4 | not_read | new | alive |
|
||||
* | 1 | 3 | 6 | read | old | alive |
|
||||
* | 1 | 4 | 8 | read | old | alive |
|
||||
* | 1 | 5 | 10 | read | old | alive |
|
||||
* | 2 | 6 | 12 | not_read | old | alive |
|
||||
* | 2 | 7 | 14 | not_read | old | alive |
|
||||
* | 2 | 8 | 16 | read | old | alive |
|
||||
* | 3 | 9 | 18 | not_read | old | alive |
|
||||
* | 3 | 10 | 20 | read | old | alive |
|
||||
* | 3 | 11 | 22 | not_read | old | alive |
|
||||
* | 4 | 12 | 24 | read | old | alive |
|
||||
* | 4 | 13 | 26 | not_read | old | alive |
|
||||
* | 4 | 14 | 28 | not_read | old | alive |
|
||||
* | 5 | 15 | 30 | read | old | alive |
|
||||
* | 5 | 16 | 32 | not_read | old | alive |
|
||||
* | 5 | 17 | 34 | read | old | alive |
|
||||
* | 6 | 18 | 36 | read | old | alive |
|
||||
* | 6 | 19 | 38 | not_read | old | alive |
|
||||
* | 6 | 20 | 40 | read | old | alive |
|
||||
*/
|
||||
|
||||
|
||||
/* Dispose and unregister the last two samples. */
|
||||
sample.long_1 = 5;
|
||||
sample.long_2 = 15;
|
||||
sample.long_3 = 30;
|
||||
ret = dds_dispose(g_writer, &sample);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed prerequisite dispose");
|
||||
sample.long_1 = 6;
|
||||
sample.long_2 = 16;
|
||||
sample.long_3 = 32;
|
||||
ret = dds_unregister_instance(g_writer, &sample);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed prerequisite unregister");
|
||||
/* | long_1 | long_2 | long_3 | sst | vst | ist |
|
||||
* ----------------------------------------------------------
|
||||
* | 0 | 0 | 0 | not_read | new | alive |
|
||||
* | 0 | 1 | 2 | not_read | new | alive |
|
||||
* | 0 | 2 | 4 | not_read | new | alive |
|
||||
* | 1 | 3 | 6 | read | old | alive |
|
||||
* | 1 | 4 | 8 | read | old | alive |
|
||||
* | 1 | 5 | 10 | read | old | alive |
|
||||
* | 2 | 6 | 12 | not_read | old | alive |
|
||||
* | 2 | 7 | 14 | not_read | old | alive |
|
||||
* | 2 | 8 | 16 | read | old | alive |
|
||||
* | 3 | 9 | 18 | not_read | old | alive |
|
||||
* | 3 | 10 | 20 | read | old | alive |
|
||||
* | 3 | 11 | 22 | not_read | old | alive |
|
||||
* | 4 | 12 | 24 | read | old | alive |
|
||||
* | 4 | 13 | 26 | not_read | old | alive |
|
||||
* | 4 | 14 | 28 | not_read | old | alive |
|
||||
* | 5 | 15 | 30 | read | old | disposed |
|
||||
* | 5 | 16 | 32 | not_read | old | disposed |
|
||||
* | 5 | 17 | 34 | read | old | disposed |
|
||||
* | 6 | 18 | 36 | read | old | no_writers |
|
||||
* | 6 | 19 | 38 | not_read | old | no_writers |
|
||||
* | 6 | 20 | 40 | read | old | no_writers |
|
||||
*/
|
||||
|
||||
dds_qos_delete(qos);
|
||||
}
|
||||
|
||||
static void
|
||||
reader_iterator_fini(void)
|
||||
{
|
||||
dds_delete(g_rcond);
|
||||
dds_delete(g_qcond);
|
||||
dds_delete(g_reader);
|
||||
dds_delete(g_writer);
|
||||
dds_delete(g_subscriber);
|
||||
dds_delete(g_publisher);
|
||||
dds_delete(g_waitset);
|
||||
dds_delete(g_topic);
|
||||
dds_delete(g_participant);
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
samples_cnt(void)
|
||||
{
|
||||
dds_return_t ret;
|
||||
ret = dds_read(g_reader, g_samples, g_info, MAX_SAMPLES, MAX_SAMPLES);
|
||||
cr_assert_geq(ret, 0, "Failed samples count read: %d", dds_err_nr(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* These will check the dds_read_next() in various ways.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_read_next, reader, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t cnt = 0;
|
||||
dds_return_t ret = 1;
|
||||
|
||||
while (ret == 1){
|
||||
ret = dds_read_next(g_reader, g_samples, g_info);
|
||||
cr_assert_geq(ret, 0 , "# read %d", ret);
|
||||
if(ret == 1){
|
||||
Space_Type1 *sample = (Space_Type1*)g_samples[0];
|
||||
PRINT_SAMPLE("ddsc_read_next::reader: Read", (*sample));
|
||||
|
||||
/* Expected states. */
|
||||
int expected_long_2 = rdr_expected_long_2[cnt];
|
||||
int expected_long_1 = expected_long_2/3;
|
||||
int expected_long_3 = expected_long_2*2;
|
||||
dds_sample_state_t expected_sst = DDS_SST_NOT_READ;
|
||||
dds_view_state_t expected_vst = SAMPLE_VST(expected_long_2);
|
||||
dds_instance_state_t expected_ist = SAMPLE_IST(expected_long_1);
|
||||
|
||||
/* Check data. */
|
||||
cr_assert_eq(sample->long_1, expected_long_1 );
|
||||
cr_assert_eq(sample->long_2, expected_long_2 );
|
||||
cr_assert_eq(sample->long_3, expected_long_2 *2);
|
||||
|
||||
/* Check states. */
|
||||
cr_assert_eq(g_info[0].valid_data, true);
|
||||
cr_assert_eq(g_info[0].sample_state, expected_sst);
|
||||
cr_assert_eq(g_info[0].view_state, expected_vst);
|
||||
cr_assert_eq(g_info[0].instance_state, expected_ist);
|
||||
cnt ++;
|
||||
}
|
||||
}
|
||||
|
||||
cr_assert_eq(cnt, RDR_NOT_READ_CNT);
|
||||
|
||||
/* All samples should still be available. */
|
||||
ret = samples_cnt();
|
||||
cr_assert_eq(ret, MAX_SAMPLES, "# samples %d, expected %d", ret, MAX_SAMPLES);
|
||||
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_read_next, invalid_readers) = {
|
||||
DataPoints(dds_entity_t, -2, -1, 0, 1, 100, INT_MAX, INT_MIN),
|
||||
};
|
||||
Theory((dds_entity_t rdr), ddsc_read_next, invalid_readers, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_entity_t exp = DDS_RETCODE_BAD_PARAMETER * -1;
|
||||
dds_return_t ret;
|
||||
|
||||
ret = dds_read_next(rdr, g_samples, g_info);
|
||||
cr_assert_eq(dds_err_nr(ret), dds_err_nr(exp), "returned %d != expected %d", dds_err_str(ret), dds_err_nr(exp));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_read_next, non_readers) = {
|
||||
DataPoints(dds_entity_t*, &g_participant, &g_topic, &g_writer, &g_subscriber, &g_publisher, &g_waitset, &g_rcond, &g_qcond),
|
||||
};
|
||||
Theory((dds_entity_t *rdr), ddsc_read_next, non_readers, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
ret = dds_read_next(*rdr, g_samples, g_info);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ILLEGAL_OPERATION, "returned %d", dds_err_nr(ret));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_read_next, already_deleted) = {
|
||||
DataPoints(dds_entity_t*, &g_rcond, &g_qcond, &g_reader),
|
||||
};
|
||||
Theory((dds_entity_t *rdr), ddsc_read_next, already_deleted, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
ret = dds_delete(*rdr);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "prerequisite delete failed: %d", dds_err_nr(ret));
|
||||
ret = dds_read_next(*rdr, g_samples, g_info);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED, "returned %d", dds_err_nr(ret));
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_read_next, invalid_buffers) = {
|
||||
DataPoints(void**, g_samples, g_loans, (void**)0),
|
||||
DataPoints(dds_sample_info_t*, g_info, (dds_sample_info_t*)0 ),
|
||||
};
|
||||
Theory((void **buf, dds_sample_info_t *si), ddsc_read_next, invalid_buffers, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
cr_assume((buf != g_samples) || (si != g_info));
|
||||
cr_assume(buf != g_loans);
|
||||
ret = dds_read_next(g_reader, buf, si);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_BAD_PARAMETER, "returned %d", dds_err_nr(ret));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* These will check the dds_read_next_wl() in various ways.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_read_next_wl, reader, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t cnt = 0;
|
||||
dds_return_t ret = 1;
|
||||
|
||||
while (ret == 1){
|
||||
ret = dds_read_next_wl(g_reader, g_loans, g_info);
|
||||
cr_assert_geq(ret, 0 , "# read %d", ret);
|
||||
if(ret == 1){
|
||||
Space_Type1 *sample = (Space_Type1*)g_loans[0];
|
||||
PRINT_SAMPLE("ddsc_read_next_wl::reader: Read", (*sample));
|
||||
|
||||
/* Expected states. */
|
||||
int expected_long_2 = rdr_expected_long_2[cnt];
|
||||
int expected_long_1 = expected_long_2/3;
|
||||
int expected_long_3 = expected_long_2*2;
|
||||
dds_sample_state_t expected_sst = DDS_SST_NOT_READ;
|
||||
dds_view_state_t expected_vst = SAMPLE_VST(expected_long_2);
|
||||
dds_instance_state_t expected_ist = SAMPLE_IST(expected_long_1);
|
||||
|
||||
/* Check data. */
|
||||
cr_assert_eq(sample->long_1, expected_long_2/3 );
|
||||
cr_assert_eq(sample->long_2, expected_long_2 );
|
||||
cr_assert_eq(sample->long_3, expected_long_2 *2);
|
||||
|
||||
/* Check states. */
|
||||
cr_assert_eq(g_info[0].valid_data, true);
|
||||
cr_assert_eq(g_info[0].sample_state, expected_sst);
|
||||
cr_assert_eq(g_info[0].view_state, expected_vst);
|
||||
cr_assert_eq(g_info[0].instance_state, expected_ist);
|
||||
cnt ++;
|
||||
}
|
||||
}
|
||||
|
||||
cr_assert_eq(cnt, RDR_NOT_READ_CNT);
|
||||
|
||||
ret = dds_return_loan(g_reader, g_loans, ret);
|
||||
cr_assert_eq (ret, DDS_RETCODE_OK);
|
||||
|
||||
/* All samples should still be available. */
|
||||
ret = samples_cnt();
|
||||
cr_assert_eq(ret, MAX_SAMPLES, "# samples %d, expected %d", ret, MAX_SAMPLES);
|
||||
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_read_next_wl, invalid_readers) = {
|
||||
DataPoints(dds_entity_t, -2, -1, 0, 1, 100, INT_MAX, INT_MIN),
|
||||
};
|
||||
Theory((dds_entity_t rdr), ddsc_read_next_wl, invalid_readers, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_entity_t exp = DDS_RETCODE_BAD_PARAMETER * -1;
|
||||
dds_return_t ret;
|
||||
|
||||
ret = dds_read_next_wl(rdr, g_loans, g_info);
|
||||
cr_assert_eq(dds_err_nr(ret), dds_err_nr(exp), "returned %d != expected %d", dds_err_nr(ret), dds_err_nr(exp));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_read_next_wl, non_readers) = {
|
||||
DataPoints(dds_entity_t*, &g_participant, &g_topic, &g_writer, &g_subscriber, &g_publisher, &g_waitset, &g_rcond, &g_qcond),
|
||||
};
|
||||
Theory((dds_entity_t *rdr), ddsc_read_next_wl, non_readers, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
ret = dds_read_next_wl(*rdr, g_loans, g_info);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ILLEGAL_OPERATION, "returned %d", dds_err_nr(ret));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_read_next_wl, already_deleted) = {
|
||||
DataPoints(dds_entity_t*, &g_rcond, &g_qcond, &g_reader),
|
||||
};
|
||||
Theory((dds_entity_t *rdr), ddsc_read_next_wl, already_deleted, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
ret = dds_delete(*rdr);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "prerequisite delete failed: %d", dds_err_nr(ret));
|
||||
ret = dds_read_next_wl(*rdr, g_loans, g_info);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED, "returned %d", dds_err_nr(ret));
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_read_next_wl, invalid_buffers) = {
|
||||
DataPoints(void**, g_loans, (void**)0),
|
||||
DataPoints(dds_sample_info_t*, g_info, (dds_sample_info_t*)0 ),
|
||||
};
|
||||
Theory((void **buf, dds_sample_info_t *si), ddsc_read_next_wl, invalid_buffers, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
cr_assume((buf != g_loans) || (si != g_info));
|
||||
ret = dds_read_next_wl(g_reader, buf, si);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_BAD_PARAMETER, "returned %d", dds_err_nr(ret));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* These will check the dds_take_next() in various ways.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_take_next, reader, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t cnt = 0;
|
||||
dds_return_t ret = 1;
|
||||
|
||||
while (ret == 1){
|
||||
ret = dds_take_next(g_reader, g_samples, g_info);
|
||||
cr_assert_geq(ret, 0 , "# read %d", ret);
|
||||
if(ret == 1){
|
||||
Space_Type1 *sample = (Space_Type1*)g_samples[0];
|
||||
PRINT_SAMPLE("ddsc_take_next::reader: Read", (*sample));
|
||||
|
||||
/* Expected states. */
|
||||
int expected_long_2 = rdr_expected_long_2[cnt];
|
||||
int expected_long_1 = expected_long_2/3;
|
||||
int expected_long_3 = expected_long_2*2;
|
||||
dds_sample_state_t expected_sst = DDS_SST_NOT_READ;
|
||||
dds_view_state_t expected_vst = SAMPLE_VST(expected_long_2);
|
||||
dds_instance_state_t expected_ist = SAMPLE_IST(expected_long_1);
|
||||
|
||||
/* Check data. */
|
||||
cr_assert_eq(sample->long_1, expected_long_1 );
|
||||
cr_assert_eq(sample->long_2, expected_long_2 );
|
||||
cr_assert_eq(sample->long_3, expected_long_2 *2);
|
||||
|
||||
/* Check states. */
|
||||
cr_assert_eq(g_info[0].valid_data, true);
|
||||
cr_assert_eq(g_info[0].sample_state, expected_sst);
|
||||
cr_assert_eq(g_info[0].view_state, expected_vst);
|
||||
cr_assert_eq(g_info[0].instance_state, expected_ist);
|
||||
cnt ++;
|
||||
}
|
||||
}
|
||||
|
||||
cr_assert_eq(cnt, RDR_NOT_READ_CNT);
|
||||
|
||||
/* All samples should still be available. */
|
||||
ret = samples_cnt();
|
||||
cr_assert_eq(ret, (MAX_SAMPLES - RDR_NOT_READ_CNT), "# samples %d, expected %d", ret, MAX_SAMPLES);
|
||||
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_take_next, invalid_readers) = {
|
||||
DataPoints(dds_entity_t, -2, -1, 0, 1, 100, INT_MAX, INT_MIN),
|
||||
};
|
||||
Theory((dds_entity_t rdr), ddsc_take_next, invalid_readers, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_entity_t exp = DDS_RETCODE_BAD_PARAMETER * -1;
|
||||
dds_return_t ret;
|
||||
|
||||
ret = dds_take_next(rdr, g_samples, g_info);
|
||||
cr_assert_eq(dds_err_nr(ret), dds_err_nr(exp), "returned %d != expected %d", dds_err_nr(ret), dds_err_nr(exp));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_take_next, non_readers) = {
|
||||
DataPoints(dds_entity_t*, &g_participant, &g_topic, &g_writer, &g_subscriber, &g_publisher, &g_waitset, &g_rcond, &g_qcond),
|
||||
};
|
||||
Theory((dds_entity_t *rdr), ddsc_take_next, non_readers, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
ret = dds_take_next(*rdr, g_samples, g_info);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ILLEGAL_OPERATION, "returned %d", dds_err_nr(ret));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_take_next, already_deleted) = {
|
||||
DataPoints(dds_entity_t*, &g_rcond, &g_qcond, &g_reader),
|
||||
};
|
||||
Theory((dds_entity_t *rdr), ddsc_take_next, already_deleted, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
ret = dds_delete(*rdr);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "prerequisite delete failed: %d", dds_err_nr(ret));
|
||||
ret = dds_take_next(*rdr, g_samples, g_info);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED, "returned %d", dds_err_nr(ret));
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_take_next, invalid_buffers) = {
|
||||
DataPoints(void**, g_samples, g_loans, (void**)0),
|
||||
DataPoints(dds_sample_info_t*, g_info, (dds_sample_info_t*)0 ),
|
||||
};
|
||||
Theory((void **buf, dds_sample_info_t *si), ddsc_take_next, invalid_buffers, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
cr_assume((buf != g_samples) || (si != g_info));
|
||||
cr_assume(buf != g_loans);
|
||||
ret = dds_take_next(g_reader, buf, si);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_BAD_PARAMETER, "returned %d", dds_err_nr(ret));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* These will check the dds_take_next_wl() in various ways.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_take_next_wl, reader, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t cnt = 0;
|
||||
dds_return_t ret = 1;
|
||||
|
||||
while (ret == 1){
|
||||
ret = dds_take_next_wl(g_reader, g_loans, g_info);
|
||||
cr_assert_geq(ret, 0 , "# read %d", ret);
|
||||
if(ret == 1){
|
||||
Space_Type1 *sample = (Space_Type1*)g_loans[0];
|
||||
PRINT_SAMPLE("ddsc_read_next_wl::reader: Read", (*sample));
|
||||
|
||||
/* Expected states. */
|
||||
int expected_long_2 = rdr_expected_long_2[cnt];
|
||||
int expected_long_1 = expected_long_2/3;
|
||||
int expected_long_3 = expected_long_2*2;
|
||||
dds_sample_state_t expected_sst = DDS_SST_NOT_READ;
|
||||
dds_view_state_t expected_vst = SAMPLE_VST(expected_long_2);
|
||||
dds_instance_state_t expected_ist = SAMPLE_IST(expected_long_1);
|
||||
|
||||
/* Check data. */
|
||||
cr_assert_eq(sample->long_1, expected_long_2/3 );
|
||||
cr_assert_eq(sample->long_2, expected_long_2 );
|
||||
cr_assert_eq(sample->long_3, expected_long_2 *2);
|
||||
|
||||
/* Check states. */
|
||||
cr_assert_eq(g_info[0].valid_data, true);
|
||||
cr_assert_eq(g_info[0].sample_state, expected_sst);
|
||||
cr_assert_eq(g_info[0].view_state, expected_vst);
|
||||
cr_assert_eq(g_info[0].instance_state, expected_ist);
|
||||
cnt ++;
|
||||
}
|
||||
}
|
||||
|
||||
cr_assert_eq(cnt, RDR_NOT_READ_CNT);
|
||||
|
||||
ret = dds_return_loan(g_reader, g_loans, ret);
|
||||
cr_assert_eq (ret, DDS_RETCODE_OK);
|
||||
|
||||
/* All samples should still be available. */
|
||||
ret = samples_cnt();
|
||||
cr_assert_eq(ret, (MAX_SAMPLES - RDR_NOT_READ_CNT), "# samples %d, expected %d", ret, MAX_SAMPLES);
|
||||
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_take_next_wl, invalid_readers) = {
|
||||
DataPoints(dds_entity_t, -2, -1, 0, 1, 100, INT_MAX, INT_MIN),
|
||||
};
|
||||
Theory((dds_entity_t rdr), ddsc_take_next_wl, invalid_readers, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_entity_t exp = DDS_RETCODE_BAD_PARAMETER * -1;
|
||||
dds_return_t ret;
|
||||
|
||||
ret = dds_take_next_wl(rdr, g_loans, g_info);
|
||||
cr_assert_eq(dds_err_nr(ret), dds_err_nr(exp), "returned %d != expected %d", dds_err_nr(ret), dds_err_nr(exp));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_take_next_wl, non_readers) = {
|
||||
DataPoints(dds_entity_t*, &g_participant, &g_topic, &g_writer, &g_subscriber, &g_publisher, &g_waitset, &g_rcond, &g_qcond),
|
||||
};
|
||||
Theory((dds_entity_t *rdr), ddsc_take_next_wl, non_readers, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
ret = dds_take_next_wl(*rdr, g_loans, g_info);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ILLEGAL_OPERATION, "returned %d", dds_err_nr(ret));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_take_next_wl, already_deleted) = {
|
||||
DataPoints(dds_entity_t*, &g_rcond, &g_qcond, &g_reader),
|
||||
};
|
||||
Theory((dds_entity_t *rdr), ddsc_take_next_wl, already_deleted, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
ret = dds_delete(*rdr);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "prerequisite delete failed: %d", dds_err_nr(ret));
|
||||
ret = dds_take_next_wl(*rdr, g_loans, g_info);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED, "returned %d", dds_err_nr(ret));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
TheoryDataPoints(ddsc_take_next_wl, invalid_buffers) = {
|
||||
DataPoints(void**, g_loans, (void**)0),
|
||||
DataPoints(dds_sample_info_t*, g_info, (dds_sample_info_t*)0 ),
|
||||
};
|
||||
Theory((void **buf, dds_sample_info_t *si), ddsc_take_next_wl, invalid_buffers, .init=reader_iterator_init, .fini=reader_iterator_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
cr_assume((buf != g_loans) || (si != g_info));
|
||||
ret = dds_take_next_wl(g_reader, buf, si);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_BAD_PARAMETER, "returned %d", dds_err_nr(ret));
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
227
src/core/ddsc/tests/register.c
Normal file
227
src/core/ddsc/tests/register.c
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
|
||||
#include "ddsc/dds.h"
|
||||
#include "os/os.h"
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/logging.h>
|
||||
#include <criterion/theories.h>
|
||||
#include "Space.h"
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* Test fixtures
|
||||
*
|
||||
*************************************************************************************************/
|
||||
#define MAX_SAMPLES 7
|
||||
#define INITIAL_SAMPLES 2
|
||||
|
||||
|
||||
static dds_entity_t g_participant = 0;
|
||||
static dds_entity_t g_topic = 0;
|
||||
static dds_entity_t g_reader = 0;
|
||||
static dds_entity_t g_writer = 0;
|
||||
static dds_entity_t g_waitset = 0;
|
||||
|
||||
static dds_time_t g_past = 0;
|
||||
static dds_time_t g_present = 0;
|
||||
|
||||
static void* g_samples[MAX_SAMPLES];
|
||||
static Space_Type1 g_data[MAX_SAMPLES];
|
||||
static dds_sample_info_t g_info[MAX_SAMPLES];
|
||||
|
||||
static char*
|
||||
create_topic_name(const char *prefix, char *name, size_t size)
|
||||
{
|
||||
/* Get semi random g_topic name. */
|
||||
os_procId pid = os_procIdSelf();
|
||||
uintmax_t tid = os_threadIdToInteger(os_threadIdSelf());
|
||||
(void) snprintf(name, size, "%s_pid%"PRIprocId"_tid%"PRIuMAX"", prefix, pid, tid);
|
||||
return name;
|
||||
}
|
||||
|
||||
static void
|
||||
registering_init(void)
|
||||
{
|
||||
Space_Type1 sample = { 0 };
|
||||
dds_qos_t *qos = dds_qos_create ();
|
||||
dds_attach_t triggered;
|
||||
dds_return_t ret;
|
||||
char name[100];
|
||||
|
||||
/* Use by source timestamp to be able to check the time related funtions. */
|
||||
dds_qset_destination_order(qos, DDS_DESTINATIONORDER_BY_SOURCE_TIMESTAMP);
|
||||
|
||||
g_participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(g_participant, 0, "Failed to create prerequisite g_participant");
|
||||
|
||||
g_waitset = dds_create_waitset(g_participant);
|
||||
cr_assert_gt(g_waitset, 0, "Failed to create g_waitset");
|
||||
|
||||
g_topic = dds_create_topic(g_participant, &Space_Type1_desc, create_topic_name("ddsc_registering_test", name, sizeof name), qos, NULL);
|
||||
cr_assert_gt(g_topic, 0, "Failed to create prerequisite g_topic");
|
||||
|
||||
/* Create a reader that keeps one sample on three instances. */
|
||||
dds_qset_reliability(qos, DDS_RELIABILITY_RELIABLE, DDS_MSECS(100));
|
||||
dds_qset_resource_limits(qos, DDS_LENGTH_UNLIMITED, 3, 1);
|
||||
g_reader = dds_create_reader(g_participant, g_topic, qos, NULL);
|
||||
cr_assert_gt(g_reader, 0, "Failed to create prerequisite g_reader");
|
||||
|
||||
/* Create a writer that will not automatically dispose unregistered samples. */
|
||||
dds_qset_writer_data_lifecycle(qos, false);
|
||||
g_writer = dds_create_writer(g_participant, g_topic, qos, NULL);
|
||||
cr_assert_gt(g_writer, 0, "Failed to create prerequisite g_writer");
|
||||
|
||||
/* Sync g_writer to g_reader. */
|
||||
ret = dds_set_enabled_status(g_writer, DDS_PUBLICATION_MATCHED_STATUS);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed to set prerequisite g_writer status");
|
||||
ret = dds_waitset_attach(g_waitset, g_writer, g_writer);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed to attach prerequisite g_writer");
|
||||
ret = dds_waitset_wait(g_waitset, &triggered, 1, DDS_SECS(1));
|
||||
cr_assert_eq(ret, 1, "Failed prerequisite dds_waitset_wait g_writer r");
|
||||
cr_assert_eq(g_writer, (dds_entity_t)(intptr_t)triggered, "Failed prerequisite dds_waitset_wait g_writer a");
|
||||
ret = dds_waitset_detach(g_waitset, g_writer);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed to detach prerequisite g_writer");
|
||||
|
||||
/* Sync g_reader to g_writer. */
|
||||
ret = dds_set_enabled_status(g_reader, DDS_SUBSCRIPTION_MATCHED_STATUS);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed to set prerequisite g_reader status");
|
||||
ret = dds_waitset_attach(g_waitset, g_reader, g_reader);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed to attach prerequisite g_reader");
|
||||
ret = dds_waitset_wait(g_waitset, &triggered, 1, DDS_SECS(1));
|
||||
cr_assert_eq(ret, 1, "Failed prerequisite dds_waitset_wait g_reader r");
|
||||
cr_assert_eq(g_reader, (dds_entity_t)(intptr_t)triggered, "Failed prerequisite dds_waitset_wait g_reader a");
|
||||
ret = dds_waitset_detach(g_waitset, g_reader);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed to detach prerequisite g_reader");
|
||||
|
||||
/* Write initial samples. */
|
||||
for (int i = 0; i < INITIAL_SAMPLES; i++) {
|
||||
sample.long_1 = i;
|
||||
sample.long_2 = i*2;
|
||||
sample.long_3 = i*3;
|
||||
ret = dds_write(g_writer, &sample);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK, "Failed prerequisite write");
|
||||
}
|
||||
|
||||
/* Initialize reading buffers. */
|
||||
memset (g_data, 0, sizeof (g_data));
|
||||
for (int i = 0; i < MAX_SAMPLES; i++) {
|
||||
g_samples[i] = &g_data[i];
|
||||
}
|
||||
|
||||
/* Initialize times. */
|
||||
g_present = dds_time();
|
||||
g_past = g_present - DDS_SECS(1);
|
||||
|
||||
dds_qos_delete(qos);
|
||||
}
|
||||
|
||||
static void
|
||||
registering_fini(void)
|
||||
{
|
||||
dds_delete(g_reader);
|
||||
dds_delete(g_writer);
|
||||
dds_delete(g_waitset);
|
||||
dds_delete(g_topic);
|
||||
dds_delete(g_participant);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#else
|
||||
/**************************************************************************************************
|
||||
*
|
||||
* These will check the dds_register_instance() in various ways.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
Test(ddsc_register_instance, deleted_entity, .init=registering_init, .fini=registering_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds_instance_handle_t handle;
|
||||
dds_delete(g_writer);
|
||||
ret = dds_register_instance(g_writer, &handle, g_data);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ALREADY_DELETED, "returned %d", dds_err_nr(ret));
|
||||
}
|
||||
|
||||
static dds_instance_handle_t hndle = 0;
|
||||
static Space_Type1 data;
|
||||
TheoryDataPoints(ddsc_register_instance, invalid_params) = {
|
||||
DataPoints(dds_instance_handle_t *, &hndle, NULL),
|
||||
DataPoints(void*, &data, NULL)
|
||||
};
|
||||
Theory((dds_instance_handle_t *hndl2, void *datap), ddsc_register_instance, invalid_params/*, .init=registering_init, .fini=registering_fini*/)
|
||||
{
|
||||
dds_return_t exp = DDS_RETCODE_BAD_PARAMETER * -1;
|
||||
dds_return_t ret;
|
||||
|
||||
/* Only test when the combination of parameters is actually invalid.*/
|
||||
cr_assume((hndl2 == NULL) || (datap == NULL));
|
||||
|
||||
OS_WARNING_MSVC_OFF(6387); /* Disable SAL warning on intentional misuse of the API */
|
||||
ret = dds_register_instance(g_writer, hndl2, datap);
|
||||
OS_WARNING_MSVC_ON(6387);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_BAD_PARAMETER, "returned %d != expected %d", dds_err_nr(ret), DDS_RETCODE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
TheoryDataPoints(ddsc_register_instance, invalid_writers) = {
|
||||
DataPoints(dds_entity_t, -2, -1, 0, 1, 100, INT_MAX, INT_MIN),
|
||||
};
|
||||
Theory((dds_entity_t writer), ddsc_register_instance, invalid_writers, .init=registering_init, .fini=registering_fini)
|
||||
{
|
||||
dds_entity_t exp = DDS_RETCODE_BAD_PARAMETER * -1;
|
||||
dds_return_t ret;
|
||||
dds_instance_handle_t handle;
|
||||
|
||||
ret = dds_register_instance(writer, &handle, g_data);
|
||||
cr_assert_eq(dds_err_nr(ret), dds_err_nr(exp), "returned %d != expected %d", dds_err_nr(ret), dds_err_nr(exp));
|
||||
}
|
||||
|
||||
TheoryDataPoints(ddsc_register_instance, non_writers) = {
|
||||
DataPoints(dds_entity_t*, &g_waitset, &g_reader, &g_topic, &g_participant),
|
||||
};
|
||||
Theory((dds_entity_t *writer), ddsc_register_instance, non_writers, .init=registering_init, .fini=registering_fini)
|
||||
{
|
||||
dds_return_t ret;
|
||||
dds_instance_handle_t handle;
|
||||
ret = dds_register_instance(*writer, &handle, g_data);
|
||||
cr_assert_eq(dds_err_nr(ret), DDS_RETCODE_ILLEGAL_OPERATION, "returned %d", dds_err_nr(ret));
|
||||
}
|
||||
|
||||
Test(ddsc_register_instance, registering_new_instance, .init=registering_init, .fini=registering_fini)
|
||||
{
|
||||
dds_instance_handle_t instHndl, instHndl2;
|
||||
dds_return_t ret;
|
||||
Space_Type1 newInstance = { INITIAL_SAMPLES, 0, 0 };
|
||||
instHndl = dds_instance_lookup(g_writer, &newInstance);
|
||||
cr_assert_eq(instHndl, DDS_HANDLE_NIL);
|
||||
ret = dds_register_instance(g_writer, &instHndl2, &newInstance);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK);
|
||||
instHndl = dds_instance_lookup(g_writer, &newInstance);
|
||||
cr_assert_eq(instHndl, instHndl2);
|
||||
}
|
||||
|
||||
Test(ddsc_register_instance, data_already_available, .init=registering_init, .fini=registering_fini)
|
||||
{
|
||||
dds_instance_handle_t instHndl, instHndl2;
|
||||
dds_return_t ret;
|
||||
instHndl = dds_instance_lookup(g_writer, &g_data);
|
||||
cr_assert_neq(instHndl, DDS_HANDLE_NIL);
|
||||
ret = dds_register_instance(g_writer, &instHndl2, &g_data);
|
||||
cr_assert_eq(ret, DDS_RETCODE_OK);
|
||||
cr_assert_eq(instHndl2, instHndl);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
150
src/core/ddsc/tests/return_loan.c
Normal file
150
src/core/ddsc/tests/return_loan.c
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* 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 "ddsc/dds.h"
|
||||
#include "RoundTrip.h"
|
||||
#include "os/os.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/logging.h>
|
||||
|
||||
dds_entity_t participant = 0, topic = 0, reader = 0, read_condition = 0;
|
||||
|
||||
void create_entities(void)
|
||||
{
|
||||
participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0);
|
||||
|
||||
topic = dds_create_topic(participant, &RoundTripModule_DataType_desc, "ddsc_reader_return_loan_RoundTrip", NULL, NULL);
|
||||
cr_assert_gt(topic, 0);
|
||||
|
||||
reader = dds_create_reader(participant, topic, NULL, NULL);
|
||||
cr_assert_gt(reader, 0);
|
||||
|
||||
read_condition = dds_create_readcondition(reader, DDS_ANY_STATE);
|
||||
cr_assert_gt(read_condition, 0);
|
||||
}
|
||||
|
||||
void delete_entities(void)
|
||||
{
|
||||
dds_return_t result;
|
||||
result = dds_delete(participant);
|
||||
cr_assert_eq(dds_err_nr(result), DDS_RETCODE_OK, "Recursively delete entities, Expected(%s) Returned(%s)", DDS_TO_STRING(DDS_RETCODE_OK), dds_err_str(result));
|
||||
dds_delete(read_condition);
|
||||
}
|
||||
|
||||
static void** create_loan_buf(size_t sz, bool empty)
|
||||
{
|
||||
size_t i;
|
||||
void **buf = NULL;
|
||||
buf = dds_alloc(sz * sizeof(*buf));
|
||||
for (i = 0; i < sz; i++) {
|
||||
buf[i] = dds_alloc(sizeof(RoundTripModule_DataType));
|
||||
if (empty) {
|
||||
memset(buf[i], 0, sizeof(RoundTripModule_DataType));
|
||||
} else {
|
||||
RoundTripModule_DataType *s = buf[i];
|
||||
s->payload._maximum = 0;
|
||||
s->payload._length = 25;
|
||||
s->payload._buffer = dds_alloc(25);
|
||||
memset(s->payload._buffer, 'z', 25);
|
||||
s->payload._release = true;
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void delete_loan_buf(void **buf, size_t sz, bool empty)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < sz; i++) {
|
||||
RoundTripModule_DataType *s = buf[i];
|
||||
if (!empty) {
|
||||
cr_expect_gt(s->payload._length, 0, "Expected allocated 'payload'-sequence in sample-contents of loan");
|
||||
if (s->payload._length > 0) {
|
||||
/* Freed by a successful dds_return_loan */
|
||||
dds_free(s->payload._buffer);
|
||||
}
|
||||
}
|
||||
/* dds_return_loan only free's sample contents */
|
||||
dds_free(s);
|
||||
}
|
||||
dds_free(buf);
|
||||
}
|
||||
|
||||
/* Verify DDS_RETCODE_BAD_PARAMETER is returned */
|
||||
Test(ddsc_reader, return_loan_bad_params, .init = create_entities, .fini = delete_entities)
|
||||
{
|
||||
dds_return_t result;
|
||||
void **buf = NULL;
|
||||
|
||||
result = dds_return_loan(reader, NULL, 0);
|
||||
cr_expect_eq(dds_err_nr(result), DDS_RETCODE_BAD_PARAMETER, "Invalid buffer(null), Expected(%s) Returned(%s)",
|
||||
DDS_TO_STRING(DDS_RETCODE_BAD_PARAMETER),
|
||||
dds_err_str(result));
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 6387)
|
||||
result = dds_return_loan(reader, buf, 10);
|
||||
#pragma warning(pop)
|
||||
cr_expect_eq(dds_err_nr(result), DDS_RETCODE_BAD_PARAMETER, "Invalid buffer size, Expected(%s) Returned(%s)",
|
||||
DDS_TO_STRING(DDS_RETCODE_BAD_PARAMETER),
|
||||
dds_err_str(result));
|
||||
|
||||
buf = create_loan_buf(10, false);
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 28020)
|
||||
result = dds_return_loan(0, buf, 10);
|
||||
#pragma warning(pop)
|
||||
cr_expect_eq(dds_err_nr(result), DDS_RETCODE_BAD_PARAMETER, "Invalid entity, Expected(%s) Returned(%s)",
|
||||
DDS_TO_STRING(DDS_RETCODE_BAD_PARAMETER),
|
||||
dds_err_str(result));
|
||||
|
||||
result = dds_return_loan(participant, buf, 0);
|
||||
cr_expect_eq(dds_err_nr(result), DDS_RETCODE_ILLEGAL_OPERATION, "Invalid entity-kind, Expected(%s) Returned(%s)",
|
||||
DDS_TO_STRING(DDS_RETCODE_ILLEGAL_OPERATION),
|
||||
dds_err_str(result));
|
||||
|
||||
delete_loan_buf(buf, 10, false);
|
||||
}
|
||||
|
||||
/* Verify DDS_RETCODE_OK is returned */
|
||||
Test(ddsc_reader, return_loan_success, .init = create_entities, .fini = delete_entities)
|
||||
{
|
||||
void **buf;
|
||||
void *buf2 = NULL;
|
||||
dds_return_t result;
|
||||
|
||||
buf = create_loan_buf(10, false);
|
||||
result = dds_return_loan(reader, buf, 10);
|
||||
cr_expect_eq(dds_err_nr(result), DDS_RETCODE_OK, "Return loan of size 10 via reader entity, Expected(%s) Returned(%s)",
|
||||
DDS_TO_STRING(DDS_RETCODE_OK),
|
||||
dds_err_str(result));
|
||||
|
||||
result = dds_return_loan(reader, &buf2, 0);
|
||||
cr_expect_eq(dds_err_nr(result), DDS_RETCODE_OK, "Return empty loan via reader entity, Expected(%s) Returned(%s)",
|
||||
DDS_TO_STRING(DDS_RETCODE_OK),
|
||||
dds_err_str(result));
|
||||
delete_loan_buf(buf, 10, true);
|
||||
|
||||
buf = create_loan_buf(10, false);
|
||||
result = dds_return_loan(read_condition, buf, 10);
|
||||
cr_expect_eq(dds_err_nr(result), DDS_RETCODE_OK, "Return loan of size 10 via read-condition entity, Expected(%s) Returned(%s)",
|
||||
DDS_TO_STRING(DDS_RETCODE_OK),
|
||||
dds_err_str(result));
|
||||
|
||||
result = dds_return_loan(read_condition, &buf2, 0);
|
||||
cr_expect_eq(dds_err_nr(result), DDS_RETCODE_OK, "Return empty loan via read-condition entity, Expected(%s) Returned(%s)",
|
||||
DDS_TO_STRING(DDS_RETCODE_OK),
|
||||
dds_err_str(result));
|
||||
delete_loan_buf(buf, 10, true);
|
||||
}
|
||||
111
src/core/ddsc/tests/subscriber.c
Normal file
111
src/core/ddsc/tests/subscriber.c
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* 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 "ddsc/dds.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/logging.h>
|
||||
|
||||
/* We are deliberately testing some bad arguments that SAL will complain about.
|
||||
* So, silence SAL regarding these issues. */
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 6387 28020)
|
||||
|
||||
static void on_data_available(dds_entity_t reader, void* arg) {}
|
||||
static void on_publication_matched(dds_entity_t writer, const dds_publication_matched_status_t status, void* arg) {}
|
||||
|
||||
Test(ddsc_subscriber, notify_readers) {
|
||||
dds_entity_t participant;
|
||||
dds_entity_t subscriber;
|
||||
dds_return_t ret;
|
||||
|
||||
participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "Failed to create prerequisite participant");
|
||||
|
||||
|
||||
subscriber = dds_create_subscriber(participant, NULL, NULL);
|
||||
cr_assert_gt(subscriber, 0, "Failed to create prerequisite subscriber");
|
||||
|
||||
/* todo implement tests */
|
||||
ret = dds_notify_readers(subscriber);
|
||||
cr_expect_eq(dds_err_nr(ret), DDS_RETCODE_UNSUPPORTED, "Invalid return code %d", ret);
|
||||
|
||||
dds_delete(subscriber);
|
||||
dds_delete(participant);
|
||||
}
|
||||
|
||||
Test(ddsc_subscriber, create) {
|
||||
|
||||
dds_entity_t participant;
|
||||
dds_entity_t subscriber;
|
||||
dds_listener_t *listener;
|
||||
dds_qos_t *sqos;
|
||||
|
||||
participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
cr_assert_gt(participant, 0, "Failed to create prerequisite participant");
|
||||
|
||||
/*** Verify participant parameter ***/
|
||||
|
||||
subscriber = dds_create_subscriber(0, NULL, NULL);
|
||||
cr_assert_eq(dds_err_nr(subscriber), DDS_RETCODE_BAD_PARAMETER, "dds_create_subscriber: invalid participant parameter");
|
||||
|
||||
subscriber = dds_create_subscriber(participant, NULL, NULL);
|
||||
cr_assert_gt(subscriber, 0, "dds_create_subscriber: valid participant parameter");
|
||||
dds_delete(subscriber);
|
||||
|
||||
/*** Verify qos parameter ***/
|
||||
|
||||
sqos = dds_qos_create(); /* Use defaults (no user-defined policies) */
|
||||
subscriber = dds_create_subscriber(participant, sqos, NULL);
|
||||
cr_assert_gt(subscriber, 0, "dds_create_subscriber: default QoS parameter");
|
||||
dds_delete(subscriber);
|
||||
dds_qos_delete(sqos);
|
||||
|
||||
sqos = dds_qos_create();
|
||||
dds_qset_destination_order(sqos, 3); /* Set invalid dest. order (ignored, not applicable for subscriber) */
|
||||
subscriber = dds_create_subscriber(participant, sqos, NULL);
|
||||
cr_assert_gt(subscriber, 0, "dds_create_subscriber: invalid non-applicable QoS parameter");
|
||||
dds_delete(subscriber);
|
||||
dds_qos_delete(sqos);
|
||||
|
||||
sqos = dds_qos_create();
|
||||
dds_qset_presentation(sqos, 123, 1, 1); /* Set invalid presentation policy */
|
||||
subscriber = dds_create_subscriber(participant, sqos, NULL);
|
||||
cr_assert_eq(dds_err_nr(subscriber), DDS_RETCODE_INCONSISTENT_POLICY, "dds_create_subscriber: invalid presentation access_scope QoS parameter");
|
||||
dds_qos_delete(sqos);
|
||||
|
||||
/*** Verify listener parameter ***/
|
||||
|
||||
listener = dds_listener_create(NULL); /* Use defaults (all listeners unset) */
|
||||
subscriber = dds_create_subscriber(participant, NULL, listener);
|
||||
cr_assert_gt(subscriber, 0, "dds_create_subscriber: unset listeners");
|
||||
dds_delete(subscriber);
|
||||
dds_listener_delete(listener);
|
||||
|
||||
listener = dds_listener_create(NULL);
|
||||
dds_lset_data_available(listener, &on_data_available); /* Set on_data_available listener */
|
||||
subscriber = dds_create_subscriber(participant, NULL, listener);
|
||||
cr_assert_gt(subscriber, 0, "dds_create_subscriber: on_data_available listener");
|
||||
dds_delete(subscriber);
|
||||
dds_listener_delete(listener);
|
||||
|
||||
listener = dds_listener_create(NULL);
|
||||
dds_lset_publication_matched(listener, &on_publication_matched); /* Set on_publication_matched listener (ignored, not applicable for subscriber) */
|
||||
subscriber = dds_create_subscriber(participant, NULL, listener);
|
||||
cr_assert_gt(subscriber, 0, "dds_create_subscriber: on_publication_matched listener");
|
||||
dds_delete(subscriber);
|
||||
dds_listener_delete(listener);
|
||||
|
||||
dds_delete(participant);
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
1258
src/core/ddsc/tests/take_instance.c
Normal file
1258
src/core/ddsc/tests/take_instance.c
Normal file
File diff suppressed because it is too large
Load diff
31
src/core/ddsc/tests/test-common.c
Normal file
31
src/core/ddsc/tests/test-common.c
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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 "ddsc/dds.h"
|
||||
|
||||
const char*
|
||||
entity_kind_str(dds_entity_t ent) {
|
||||
if(ent <= 0) {
|
||||
return "(ERROR)";
|
||||
}
|
||||
switch(ent & DDS_ENTITY_KIND_MASK) {
|
||||
case DDS_KIND_TOPIC: return "Topic";
|
||||
case DDS_KIND_PARTICIPANT: return "Participant";
|
||||
case DDS_KIND_READER: return "Reader";
|
||||
case DDS_KIND_WRITER: return "Writer";
|
||||
case DDS_KIND_SUBSCRIBER: return "Subscriber";
|
||||
case DDS_KIND_PUBLISHER: return "Publisher";
|
||||
case DDS_KIND_COND_READ: return "ReadCondition";
|
||||
case DDS_KIND_COND_QUERY: return "QueryCondition";
|
||||
case DDS_KIND_WAITSET: return "WaitSet";
|
||||
default: return "(INVALID_ENTITY)";
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue