Initial contribution
This commit is contained in:
		
							parent
							
								
									7b5cc4fa59
								
							
						
					
					
						commit
						11d9ce37aa
					
				
					 580 changed files with 155133 additions and 162 deletions
				
			
		
							
								
								
									
										68
									
								
								src/core/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/core/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,68 @@
 | 
			
		|||
#
 | 
			
		||||
# 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
 | 
			
		||||
#
 | 
			
		||||
find_package(Abstraction REQUIRED)
 | 
			
		||||
 | 
			
		||||
include (GenerateExportHeader)
 | 
			
		||||
 | 
			
		||||
FUNCTION(PREPEND var prefix)
 | 
			
		||||
   SET(listVar "")
 | 
			
		||||
   FOREACH(f ${ARGN})
 | 
			
		||||
      LIST(APPEND listVar "${prefix}/${f}")
 | 
			
		||||
   ENDFOREACH(f)
 | 
			
		||||
   SET(${var} "${listVar}" PARENT_SCOPE)
 | 
			
		||||
ENDFUNCTION(PREPEND)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
option(DDSC_SHARED "Build DDSC as a shared library" ON)
 | 
			
		||||
 | 
			
		||||
if(DDSC_SHARED AND ((NOT DEFINED BUILD_SHARED_LIBS) OR BUILD_SHARED_LIBS))
 | 
			
		||||
  # BUILD_SHARED_LIBS is set to off by for example VxWorks DKM environment
 | 
			
		||||
  add_library(ddsc SHARED "")
 | 
			
		||||
else()
 | 
			
		||||
  if(DDSC_SHARED)
 | 
			
		||||
    message(STATUS "Option DDSC_SHARED ignored. Only static libraries supported on this platform.")
 | 
			
		||||
  endif()
 | 
			
		||||
  add_library(ddsc "")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
include(ddsi/CMakeLists.txt)
 | 
			
		||||
include(ddsc/CMakeLists.txt)
 | 
			
		||||
include(security/CMakeLists.txt)
 | 
			
		||||
 | 
			
		||||
target_link_libraries(ddsc PRIVATE util)
 | 
			
		||||
target_link_libraries(ddsc PRIVATE OSAPI)
 | 
			
		||||
 | 
			
		||||
# SOVERSION should increase on incompatible ABI change
 | 
			
		||||
set_target_properties(ddsc PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR})
 | 
			
		||||
 | 
			
		||||
get_target_property(os_api_src_dir OSAPI SOURCE_DIR)
 | 
			
		||||
# We need to expose some of the OS headers as well.
 | 
			
		||||
target_include_directories(ddsc
 | 
			
		||||
    PUBLIC
 | 
			
		||||
        "$<BUILD_INTERFACE:${os_api_src_dir}/include>")
 | 
			
		||||
 | 
			
		||||
set_target_file_ids(ddsc)
 | 
			
		||||
 | 
			
		||||
# Create a pseudo-target that other targets (i.e. examples, tests) can depend
 | 
			
		||||
# on and can also be provided as import-target by a package-file when building
 | 
			
		||||
# those targets outside the regular Cyclone build-tree (i.e. the installed tree)
 | 
			
		||||
add_library(${CMAKE_PROJECT_NAME}::ddsc ALIAS ddsc)
 | 
			
		||||
 | 
			
		||||
install(
 | 
			
		||||
  TARGETS ddsc
 | 
			
		||||
  EXPORT "${CMAKE_PROJECT_NAME}"
 | 
			
		||||
  RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT lib
 | 
			
		||||
  LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib
 | 
			
		||||
  ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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
											
										
									
								
							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