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