Merge pull request #511 from eboasson/security

Merge master into security
This commit is contained in:
eboasson 2020-05-12 19:00:52 +02:00 committed by GitHub
commit 82af49172d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 671 additions and 157 deletions

View file

@ -45,7 +45,7 @@ linux_gcc8: &linux_gcc8
apt:
update: true
sources: [ ubuntu-toolchain-r-test ]
packages: [ gcc-8 g++-8 ]
packages: [ gcc-8, g++-8, trang ]
before_install:
- eval "export CC=gcc-8"
- eval "export CXX=g++-8"
@ -61,6 +61,7 @@ linux_clang: &linux_clang
addons:
apt:
update: true
packages: [ trang ]
before_install:
- eval "export CC=clang"
- eval "export CXX=clang++"
@ -74,7 +75,7 @@ osx_xcode: &osx_xcode
compiler: clang
addons:
homebrew:
packages: [ python3 ]
packages: [ python3, trang ]
before_install:
- eval "export CC=clang"
- eval "export CXX=clang++"
@ -88,7 +89,7 @@ osx_xcode9: &osx_xcode9
osx_image: xcode9
addons:
homebrew:
packages: [ python3 ]
packages: [ python3, trang ]
# Homebrew must be updated before packages can be installed on outdated
# macOS images. The update process unfortunately takes a VERY long time
# and can even cause Travis to terminate the build. Travis caching is
@ -197,6 +198,7 @@ script:
- mkdir build
- cd build
- conan install -b missing -s arch=${ARCH} -s build_type=${BUILD_TYPE} ..
- which trang && BUILD_SCHEMA=1 || BUILD_SCHEMA=0
- cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
-DCMAKE_INSTALL_PREFIX=${INSTALLPREFIX}
-DUSE_SANITIZER=${ASAN}
@ -205,9 +207,11 @@ script:
-DENABLE_LIFESPAN=${LIFESPAN}
-DENABLE_DEADLINE_MISSED=${DEADLINE}
-DBUILD_TESTING=on
-DBUILD_SCHEMA=${BUILD_SCHEMA}
-DWERROR=on
-G "${GENERATOR}" ..
- case "${GENERATOR}" in
- |
case "${GENERATOR}" in
"Unix Makefiles")
${SCAN_BUILD} cmake --build . --config ${BUILD_TYPE} --target install -- -j 4
;;
@ -219,14 +223,20 @@ script:
;;
esac
- CYCLONEDDS_URI='<CycloneDDS><Domain><Internal><EnableExpensiveChecks>all</EnableExpensiveChecks><LivelinessMonitoring>true</LivelinessMonitoring></Internal><Tracing><Verbosity>config</Verbosity><OutputFile>stderr</OutputFile></Tracing></Domain></CycloneDDS>' ctest -j 4 --output-on-failure -T test -E '^CUnit_ddsrt_random_default_random$' -C ${BUILD_TYPE}
- if [ "${ASAN}" = "none" ]; then
- |
if [ "${ASAN}" = "none" ]; then
${SHELL} ../src/tools/ddsperf/sanity.bash;
fi
- if [ "${ASAN}" != "none" ]; then
- |
if [ "${ASAN}" != "none" ]; then
CMAKE_LINKER_FLAGS="-DCMAKE_LINKER_FLAGS=-fsanitize=${USE_SANITIZER}";
CMAKE_C_FLAGS="-DCMAKE_C_FLAGS=-fsanitize=${USE_SANITIZER}";
fi
- cd ..
- |
if [ ${BUILD_SCHEMA} ]; then
git diff --exit-code; # check that no files (e.g. generated schemas) are changed
fi
- mkdir helloworld_build
- cd helloworld_build
- cmake -DCMAKE_PREFIX_PATH=${INSTALLPREFIX}

59
CHANGELOG.rst Normal file
View file

@ -0,0 +1,59 @@
Changelog for Eclipse Cyclone DDS
=================================
`Unreleased <https://github.com/eclipse-cyclonedds/cyclonedds/compare/0.6.0...master>`_
---------------------------------------------------------------------------------------
`V0.6.0 (2020-05-21) <https://github.com/eclipse-cyclonedds/cyclonedds/compare/V0.5.0...0.6.0>`_
-----------------------------------------------------------------------------------------------
* Support for mixed-language programming by supporting multiple (de)serializers for a single topic in a single process. This way, a program that consists of, say, C and C++ can use a different representation of the data in C than in C++. Before, all readers/writers in the process would be forced to use the same representation (or perform an additional copy). Currently C is still the only natively supported language, but one can use an evolving-but-reasonable-stable interface to implement different mappings.
* Improved QoS support: full support for deadline, lifespan and liveliness. The first is for generating notifications when a configured instance update rate is not achieved, the second for automatically removing stale samples, the third for different modes of monitoring the liveliness of peers.
* Improved scalability in matching readers and writers. Before it used to try matching a new local or remote reader or writer with all known local & remote entities, now only with the right group with the correct topic name.
* Improved tracing: discovery data is now printed properly and user samples have more type information allowing floating-point and signed numbers to be traced in a more readable form.
* Extension of platform support
* Known to work on FreeBSD, CheriBSD
* Known to work with the musl C library
* Windows-specific changes
* Fixes multicasts to addresses also used by non-Cyclone processes (caused by accidentally linking with an old sockets library)
* Correct handling of non-English network interface names
`0.5.1 (2020-03-11) <https://github.com/eclipse-cyclonedds/cyclonedds/compare/V0.5.0...0.5.1>`_
-----------------------------------------------------------------------------------------------
An interim tag for the benefit of ROS2
* Enable QOS features: liveliness, lifespan, deadline
* Fix issues on Windows where multicast data was not received
`V0.5.0 (2019-11-21) <https://github.com/eclipse-cyclonedds/cyclonedds/compare/V0.1.0...V0.5.0>`_
-------------------------------------------------------------------------------------------------
This is the fist release candidate for the long overdue second release of Eclipse Cyclone DDS.
We are updating the version number from 0.1 to 0.5 to make up for the lack of more timely releases and to reflect that progress towards a 1.0 release (a minimum profile DDS implementation + DDS security) has been more significant than a version of "0.2" would suggest.
Updates since the first release have been legion, pretty much without impact on application code or interoperatbility on the network.
Some of the highlights:
* Support for ROS2 Dashing and Eloquent (via an adaption layer).
* Support for an arbitrary number of concurrent DDS domains (fully independent instantiations of DDS) in a single process.
* Abstracting the notion of samples, types and reader history caches, allowing overriding the default implementations of these to get behaviours more suited to the applications.
This is particularly relevant to language bindings and embedding Cyclone DDS in other frameworks, such as ROS2.
* Platform support is extended beyond the usual Linux/Windows/macOS: FreeRTOS is now known to work, as is Solaris 2.6 on sun4m machines.
* Acceptance of some malformed messages from certain implementations improved interoperability on the wire.
.......................................
Limitations on backwards compatibility:
.......................................
* A change in how implicitly created "publisher" and "subscriber" entities are handled: they now never lose their "implicitness", and in consequence, are now deleted when their last child disappears rather than deleted when their one child disappears.
* The set of entities that can be attached to a waitset is now restricted to those owned by the parent of the waitset, before one was allowed to attach entities from different participants to the same waitset, which is tantamount to a bug.
* A participant entity now has a parent. The "get_parent" operation no longer returns 0 for a participant because of the addition of two additional levels to the entity hierarchy: a domain, possibly containing multiple participants; and one that represents the entire library.
* The data from a reader for a built-in topic has been extended, breaking binary compatibility.
`V0.1.0 (2019-03-06) <https://github.com/eclipse-cyclonedds/cyclonedds/compare/7b5cc4fa59ba57a3b796a48bc80bb1e8527fc7f3...V0.1.0>`_
-------------------------------------------------------------------------------------------------------------------------------------
Eclipse Cyclone DDS first release!

View file

@ -10,7 +10,7 @@
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#
cmake_minimum_required(VERSION 3.7)
project(CycloneDDS VERSION 0.5.0)
project(CycloneDDS VERSION 0.7.0)
# Set a default build type if none was specified
set(default_build_type "RelWithDebInfo")
@ -205,6 +205,9 @@ set(MEMORYCHECK_COMMAND_OPTIONS "--track-origins=yes --leak-check=full --trace-c
option(BUILD_TESTING "Build the testing tree." OFF)
include(CTest)
option(BUILD_DOCS "Build documentation." OFF)
option(BUILD_SCHEMA "Build generated schema for configuration options." OFF)
# Build all executables and libraries into the top-level /bin and /lib folders.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
@ -215,7 +218,7 @@ if(BUILD_IDLC)
add_subdirectory(examples)
endif()
option(BUILD_DOCS "Build documentation." OFF)
add_subdirectory(docs)
# Pull-in CPack and support for generating <Package>Config.cmake and packages.

View file

@ -1,7 +1,7 @@
# Eclipse Cyclone DDS
Eclipse Cyclone DDS is a very performant and robust open-source DDS implementation. Cyclone DDS is developed completely in the open as an Eclipse IoT project
(see [eclipse-cyclone-dds](https://projects.eclipse.org/projects/iot.cyclonedds)).
(see [eclipse-cyclone-dds](https://projects.eclipse.org/projects/iot.cyclonedds)) with a growing list of [adopters](https://iot.eclipse.org/adopters/?#iot.cyclonedds) (if you're one of them, please add your [logo](https://github.com/EclipseFdn/iot.eclipse.org/issues/new?template=adopter_request.md)). It is a tier-1 middleware for the Robot Operating System [ROS 2](https://index.ros.org/doc/ros2/).
* [Getting Started](#getting-started)
* [Performance](#performance)
@ -11,8 +11,7 @@ Eclipse Cyclone DDS is a very performant and robust open-source DDS implementati
## Building Eclipse Cyclone DDS
In order to build Cyclone DDS you need a Linux, Mac or Windows 10 machine (or, with some caveats, an
OpenIndiana one or a Solaris 2.6 one) with the following installed on your host:
In order to build Cyclone DDS you need a Linux, Mac or Windows 10 machine (or, with some caveats, a *BSD, OpenIndiana or a Solaris 2.6 one) with the following installed on your host:
* C compiler (most commonly GCC on Linux, Visual Studio on Windows, Xcode on macOS);
* GIT version control system;
@ -28,7 +27,7 @@ installed, and the rest should already be there. On Windows, installing chocola
install git cmake openjdk maven`` should get you a long way. On macOS, ``brew install maven cmake``
and downloading and installing the JDK is easiest.
The Java-based components are the preprocessor and a configurator tool. The run-time
The only Java-based component is the IDL preprocessor. The run-time
libraries are pure C code, so there is no need to have Java available on "target"
machines. If desired, it is possible to do a build without Java or Maven installed by
defining ``BUILD_IDLC=NO``, but that effectively only gets you the core library. For the
@ -185,7 +184,7 @@ the
the
[throughput](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/sub.log) and
[latency](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/ping.log) data
underlying the graphs. These also include CPU usage ([thoughput](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/throughput-async-listener-cpu.png) and [latency](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/latency-sync-listener-bwcpu.png)) and [memory usage](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/throughput-async-listener-memory.png).
underlying the graphs. These also include CPU usage ([throughput](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/throughput-async-listener-cpu.png) and [latency](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/latency-sync-listener-bwcpu.png)) and [memory usage](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/throughput-async-listener-memory.png).
# Configuration
@ -250,3 +249,5 @@ Background information on configuring Cyclone DDS can be found
* "Eclipse Cyclone DDS" and "Cyclone DDS" are trademarks of the Eclipse Foundation.
* "DDS" is a trademark of the Object Management Group, Inc.
* "ROS" is a trademark of Open Source Robotics Foundation, Inc.

View file

@ -319,7 +319,7 @@ function(sphinx_add_docs _target)
endif()
add_custom_target(
${_target}
${_target} ALL
COMMAND ${SPHINX_BUILD_EXECUTABLE}
-b ${_builder}
-d "${CMAKE_CURRENT_BINARY_DIR}/${_target}.cache/_doctrees"

View file

@ -0,0 +1,53 @@
# Copyright(c) 2020 ADLINK Technology Limited and others
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
# v. 1.0 which is available at
# http://www.eclipse.org/org/documents/edl-v10.php.
#
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#
#[=======================================================================[.rst:
FindTrang
---------
Finds Trang, an xml schema transpiler
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``Trang_FOUND``
True if the system has the Foo library.
``Trang_VERSION``
The version of the Foo library which was found.
``Trang_TRANG_CMD``
List of command line args to run Trang.
``Trang_TRANG_EXECUTABLE``
Path to the Trang executable file
#]=======================================================================]
find_program(Trang_TRANG_EXECUTABLE trang)
execute_process(
COMMAND "${Trang_TRANG_EXECUTABLE}"
ERROR_VARIABLE trang_output
)
if(trang_output MATCHES "Trang version ([0-9]+)")
set(TRANG_VERSION "${CMAKE_MATCH_1}")
else()
message(ERROR "Could not parse version from Trang output: '${trang_output}'")
set(TRANG_VERSION "0")
endif()
set(Trang_TRANG_CMD "${Trang_TRANG_EXECUTABLE}")
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(
Trang
REQUIRED_VARS Trang_TRANG_CMD
VERSION_VAR TRANG_VERSION
)

View file

@ -8,43 +8,49 @@
# http://www.eclipse.org/org/documents/edl-v10.php.
#
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
include(FindPerl)
if(PERL_FOUND)
# These are all various expressions of the configuration schema
get_filename_component(config_c_PATH "../src/core/ddsi/src/q_config.c" REALPATH BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
# although the following files are generated, we check them into source control for convenience
get_filename_component(config_rnc_PATH "../etc/cyclonedds.rnc" REALPATH BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
get_filename_component(config_xsd_PATH "../etc/cyclonedds.xsd" REALPATH BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
get_filename_component(config_md_PATH "./manual/options.md" REALPATH BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
if(BUILD_SCHEMA OR BUILD_DOCS)
find_package(Perl REQUIRED)
add_custom_command(
OUTPUT
options.md cyclonedds.rnc
"${config_md_PATH}" "${config_rnc_PATH}"
COMMAND
${PERL_EXECUTABLE} -w "${CMAKE_CURRENT_SOURCE_DIR}/makernc.pl" "${CMAKE_CURRENT_SOURCE_DIR}/../src/core/ddsi/src/q_config.c" options.md cyclonedds.rnc
COMMAND
${PERL_EXECUTABLE} -w "${CMAKE_CURRENT_SOURCE_DIR}/compare.pl" options.md "${CMAKE_CURRENT_SOURCE_DIR}/manual/options.md"
COMMAND
${PERL_EXECUTABLE} -w "${CMAKE_CURRENT_SOURCE_DIR}/compare.pl" cyclonedds.rnc "${CMAKE_CURRENT_SOURCE_DIR}/../etc/cyclonedds.rnc"
${PERL_EXECUTABLE} -w "${CMAKE_CURRENT_SOURCE_DIR}/makernc.pl" "${config_c_PATH}" "${config_md_PATH}" "${config_rnc_PATH}"
COMMENT "Generating Relax NG schema and Markdown documentation for config options"
DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/makernc.pl"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/core/ddsi/src/q_config.c")
add_custom_target(options_doc ALL DEPENDS "options.md" "cyclonedds.rnc")
"${config_c_PATH}")
add_custom_target(options_doc ALL DEPENDS "${config_md_PATH}" "${config_rnc_PATH}")
find_package(Trang REQUIRED)
find_package(Java COMPONENTS Runtime)
if(JAVA_FOUND AND EXISTS "${TRANG_PATH}" OR EXISTS "$ENV{TRANG}")
if(NOT EXISTS "${TRANG_PATH}" AND EXISTS "$ENV{TRANG}")
message(STATUS "Setting TRANG_PATH to $ENV{TRANG}")
set(TRANG_PATH "$ENV{TRANG}" CACHE FILEPATH "Location of 'trang' for converting XML schemas" FORCE)
endif()
add_custom_command(
OUTPUT
cyclonedds.xsd
COMMAND
${Java_JAVA_EXECUTABLE} -jar "${TRANG_PATH}" -I rnc -O xsd cyclonedds.rnc cyclonedds.xsd
COMMAND
${PERL_EXECUTABLE} -w "${CMAKE_CURRENT_SOURCE_DIR}/compare.pl" cyclonedds.xsd "${CMAKE_CURRENT_SOURCE_DIR}/../etc/cyclonedds.xsd"
DEPENDS
"cyclonedds.rnc")
add_custom_target(options_xsd ALL DEPENDS "cyclonedds.xsd")
else()
message(STATUS "Java or not trang not found: not converting/checking RNC to XSD")
endif()
else()
message(STATUS "perl not found: not generating/checking options documentation and RNC")
OUTPUT "${config_xsd_PATH}"
COMMAND ${Trang_TRANG_CMD} -I rnc -O xsd "${config_rnc_PATH}" "${config_xsd_PATH}"
COMMENT "Translating schema into XSD"
DEPENDS "${config_rnc_PATH}")
add_custom_target(options_xsd ALL DEPENDS "${config_xsd_PATH}")
endif()
add_subdirectory(manual)
if(BUILD_DOCS)
find_package(Sphinx REQUIRED breathe)
sphinx_add_docs(
docs
BREATHE_PROJECTS ddsc_api_docs
BUILDER html
SOURCE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/manual")
add_dependencies(docs options_doc)
install(
DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/docs"
DESTINATION "${CMAKE_INSTALL_DOCDIR}/manual"
COMPONENT dev)
endif()

View file

@ -1,8 +0,0 @@
open A, "< $ARGV[0]" or die "can't open $ARGV[0]";
open B, "< $ARGV[1]" or die "can't open $ARGV[1]";
while (defined ($a = <A>) && defined ($b = <B>)) {
$a =~ s/[\r\n]+$//s;
$b =~ s/[\r\n]+$//s;
print "$ARGV[0] difference detected\n" and exit 1 unless $a eq $b;
}
exit 0;

View file

@ -56,7 +56,7 @@ su - travis
5. Install The [Conan C/C++ Package Manager](https://conan.io).
```
$ pip intall conan --upgrade --user
$ pip install conan --upgrade --user
$ conan user
```

View file

@ -66,7 +66,7 @@ priority member that is passed to the handler consists of the priority,
e.g. error, info, etc and (if it's a trace message) the category.
To be specific. The last four bits of the 32-bit integer contain the priority.
The other bits implicity indicate it's a trace message and are reserved to
The other bits implicitly indicate it's a trace message and are reserved to
specify the category to which a message belongs.
```C
@ -89,7 +89,7 @@ the internal log and trace functions depends on it. The user is strongly
discouraged to enable all categories and filter messages in the registered
handler, because of the performance impact!
> Tests have shown performance to decrease by roughly 5% if the descision on
> Tests have shown performance to decrease by roughly 5% if the decision on
> whether or not to write the message is done outside the function. The reason
> obviously not being the *if*-statement, but the creation of the stack frame.
@ -143,7 +143,7 @@ that can print to the native log api offered by a target. e.g.
* Use the name of the parameter as it appears in the documentation for that
language binding to reference a parameter where applicable.
* Use the same formatting style as other messages in the same module.
* e.g. use "could not ..." or "failed to ..." consitently.
* e.g. use "could not ..." or "failed to ..." consistently.
* Avoid duplicate reports as much as possible.
e.g. if a problem is reported in a lower layer, do not report it again when
the error is propagated.
@ -173,7 +173,7 @@ that can print to the native log api offered by a target. e.g.
* Cyclone assumes files can always be written. For a number of supported
targets, e.g. FreeRTOS and VxWorks, this is often not the case. Also,
filling the memory with log files is proably undesirable.
filling the memory with log files is probably undesirable.
* Cyclone (except for DDSI) does not support log categories to selectively
enable/disable messages that the user is interested in. Causing trace logs

View file

@ -1,7 +1,7 @@
# Eclipse Cyclone DDS Module Layout
Cyclone DDS is made up of multiple modules, each of which provides a certain
set of functionality, either private, public or a combination therof. Since
set of functionality, either private, public or a combination thereof. Since
Cyclone DDS is a middleware product, the api is of course the most visible
interface. Cyclone DDS uses the *dds* (not followed by an underscore) prefix
to avoid name collisions with other code.
@ -32,7 +32,7 @@ but does offer a neat way to separate features logically.
> restructuring of the runtime module. The two will be merged in the not too
> distant future.
All modules are exported seperately, for convenience. e.g. the *ddsrt* module
All modules are exported separately, for convenience. e.g. the *ddsrt* module
offers target agnostic interfaces to create and manage threads and
synchronization primitives, retrieve resource usage, system time, etc.
However, all symbols not referenced by including *dds.h* or prefixed with
@ -54,12 +54,12 @@ the target supports IPv6 addresses.
### Feature discovery
Discovery of target features at compile time is lagely dynamic. Various target
Discovery of target features at compile time is largely dynamic. Various target
specific predefined macros determine if a feature is supported and which
implementation is built. This is on purpose, to avoid a target specific
include directory and an abundance of configuration header files and works
well for most use cases. Of course, there are exceptions where the preprocessor
requires some hints to make the right the descision. e.g. when the lwIP TCP/IP
requires some hints to make the right decision. e.g. when the lwIP TCP/IP
stack should be used as opposed to the native stack. The build system is
responsible for the availability of the proper macros at compile time.
@ -82,10 +82,10 @@ target architecture specific implementation.
#### Network stack
General purpose operating systems like Microsoft Windows and Linux come with
a network stack, as does VxWorks. FreeRTOS, however, does not and requires a
seperate TCP/IP stack, which is often part of the Board Support Package (BSP).
separate TCP/IP stack, which is often part of the Board Support Package (BSP).
But separate stacks can be used on Microsoft Windows and Linux too. e.g. the
network stack in Tizen RT is based on lwIP, but the platform uses the Linux
kernel. Wheter or not lwIP must be used cannot be determined automatically and
kernel. Whether or not lwIP must be used cannot be determined automatically and
the build system must hint which implementation is to be used.
@ -158,7 +158,7 @@ directory.
### Development guidelines
* Be pragmatic. Use ifdefs (only) where it makes sense. Do not ifdef if target
implementations are completely different. Add a seperate implementation. If
implementations are completely different. Add a separate implementation. If
there are only minor differences, as is typically the case between unices,
use an ifdef.
* Header and source files are not prefixed. Instead they reside in a directory

View file

@ -1,23 +0,0 @@
#
# Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
# v. 1.0 which is available at
# http://www.eclipse.org/org/documents/edl-v10.php.
#
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
if(BUILD_DOCS)
find_package(Sphinx REQUIRED breathe)
sphinx_add_docs(
docs
BREATHE_PROJECTS ddsc_api_docs
BUILDER html
SOURCE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
install(
DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/docs/"
DESTINATION "${CMAKE_INSTALL_DOCDIR}/manual"
COMPONENT dev)
endif()

View file

@ -377,7 +377,7 @@ can be done to properly connect readers and writers:
The use of these events will be outside the scope of this example
* Poll for the publication/subscription matches statusses
* Poll for the publication/subscription matches statuses
* The Subscriber should poll for a subscription matched status to be set
* The Publisher should poll for a publication matched status to be set

View file

@ -106,7 +106,7 @@ from its WHC when it fills up too far, and allows readers to always receive all
complication exists in the case of unresponsive readers, readers that do not respond to
a Heartbeat at all, or that for some reason fail to receive some samples despite
resending it. The specification leaves the way these get treated unspecified. The
default beahviour of Eclipse Cyclone DDS is to never consider readers unresponsive, but it can
default behaviour of Eclipse Cyclone DDS is to never consider readers unresponsive, but it can
be configured to consider them so after a certain length of time has passed at which
point the participant containing the reader is undiscovered.
@ -214,7 +214,7 @@ settings.
Proxies have the same natural hierarchy that normal DDSI entities have: each proxy
endpoint is owned by some proxy participant, and once the proxy participant is deleted,
all of its proxy endpoints are deleted as well. Participants assert their liveliness
periodically (called *automic* liveliness in the DCPS specification and the only mode
periodically (called *automatic* liveliness in the DCPS specification and the only mode
currently supported by Eclipse Cyclone DDS), and when nothing has been heard from a participant
for the lease duration published by that participant in its SPDP message, the lease
becomes expired triggering a clean-up.
@ -807,7 +807,7 @@ size of the second to ``Internal/SecondaryReorderMaxSamples``.
In between the receive thread and the delivery threads sit queues, of which the maximum
size is controlled by the ``Internal/DeliveryQueueMaxSamples`` setting. Generally there
is no need for these queues to be very large (unless one has very small samples in very
large messaegs), their primary function is to smooth out the processing when batches of
large messages), their primary function is to smooth out the processing when batches of
samples become available at once, for example following a retransmission.
When any of these receive buffers hit their size limit and it concerns application data,

View file

@ -64,7 +64,7 @@ One of: false, true, single, none, many
This option specifies whether a network socket will be created for each
domain participant on a host. The specification seems to assume that each
participant has a unique address, and setting this option will ensure
this to be the case. This is not the defeault.
this to be the case. This is not the default.
Disabling it slightly improves performance and reduces network traffic
somewhat. It also causes the set of port numbers needed by Cyclone DDS to
@ -644,7 +644,7 @@ The default value is: "0".
##### //CycloneDDS/Domain/Discovery/Ports/ParticipantGain
Integer
This element specifies the participant gain, relating p0, articipant
This element specifies the participant gain, relating p0, participant
index to sets of port numbers (refer to the DDSI 2.1 specification,
section 9.6.1, constant PG).
@ -1050,8 +1050,8 @@ Attributes: [max](#cycloneddsdomaininternalheartbeatintervalmax), [min](#cyclone
Number-with-unit
This elemnents allows configuring the base interval for sending writer
heartbeats and the bounds within it can vary.
This element allows configuring the base interval for sending writer
heartbeats and the bounds within which it can vary.
Valid values are finite durations with an explicit unit or the keyword
'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.
@ -1600,8 +1600,8 @@ transport. Enabling write batching causes multiple small write operations
to be aggregated within the write cache into a single larger write. This
gives greater throughput at the expense of latency. Currently there is no
mechanism for the write cache to automatically flush itself, so that if
write batching is enabled, the application may havee to use the
dds_write_flush function to ensure thta all samples are written.
write batching is enabled, the application may have to use the
dds_write_flush function to ensure that all samples are written.
The default value is: "false".
@ -2140,10 +2140,10 @@ Text
This option specifies the file to which received and sent packets will be
logged in the "pcap" format suitable for analysis using common networking
tools, such as WireShark. IP and UDP headers are ficitious, in particular
the destination address of received packets. The TTL may be used to
distinguish between sent and received packets: it is 255 for sent packets
and 128 for received ones. Currently IPv4 only.
tools, such as WireShark. IP and UDP headers are fictitious, in
particular the destination address of received packets. The TTL may be
used to distinguish between sent and received packets: it is 255 for sent
packets and 128 for received ones. Currently IPv4 only.
The default value is: "".

View file

@ -44,7 +44,7 @@ will help.</p><p>The default value is: &quot;false&quot;.</p>""" ] ]
<p>This option specifies whether a network socket will be created for
each domain participant on a host. The specification seems to assume that
each participant has a unique address, and setting this option will
ensure this to be the case. This is not the defeault.</p>
ensure this to be the case. This is not the default.</p>
<p>Disabling it slightly improves performance and reduces network traffic
somewhat. It also causes the set of port numbers needed by Cyclone DDS to
@ -532,7 +532,7 @@ d0).</p><p>The default value is: &quot;0&quot;.</p>""" ] ]
xsd:integer
}?
& [ a:documentation [ xml:lang="en" """
<p>This element specifies the participant gain, relating p0, articipant
<p>This element specifies the participant gain, relating p0, participant
index to sets of port numbers (refer to the DDSI 2.1 specification,
section 9.6.1, constant PG).</p><p>The default value is:
&quot;2&quot;.</p>""" ] ]
@ -873,8 +873,8 @@ keys.</p><p>The default value is: &quot;false&quot;.</p>""" ] ]
xsd:boolean
}?
& [ a:documentation [ xml:lang="en" """
<p>This elemnents allows configuring the base interval for sending writer
heartbeats and the bounds within it can vary.</p>
<p>This element allows configuring the base interval for sending writer
heartbeats and the bounds within which it can vary.</p>
<p>Valid values are finite durations with an explicit unit or the keyword
'inf' for infinity. Recognised units: ns, us, ms, s, min, hr,
@ -1314,8 +1314,8 @@ transport. Enabling write batching causes multiple small write operations
to be aggregated within the write cache into a single larger write. This
gives greater throughput at the expense of latency. Currently there is no
mechanism for the write cache to automatically flush itself, so that if
write batching is enabled, the application may havee to use the
dds_write_flush function to ensure thta all samples are
write batching is enabled, the application may have to use the
dds_write_flush function to ensure that all samples are
written.</p><p>The default value is: &quot;false&quot;.</p>""" ] ]
element WriteBatch {
xsd:boolean
@ -1739,8 +1739,8 @@ or Tracing/EnabledCategory settings.</p><p>The default value is:
& [ a:documentation [ xml:lang="en" """
<p>This option specifies the file to which received and sent packets will
be logged in the "pcap" format suitable for analysis using common
networking tools, such as WireShark. IP and UDP headers are ficitious, in
particular the destination address of received packets. The TTL may be
networking tools, such as WireShark. IP and UDP headers are fictitious,
in particular the destination address of received packets. The TTL may be
used to distinguish between sent and received packets: it is 255 for sent
packets and 128 for received ones. Currently IPv4 only.</p><p>The default
value is: &quot;&quot;.</p>""" ] ]

View file

@ -95,7 +95,7 @@ will help.&lt;/p&gt;&lt;p&gt;The default value is: &amp;quot;false&amp;quot;.&lt
&lt;p&gt;This option specifies whether a network socket will be created for
each domain participant on a host. The specification seems to assume that
each participant has a unique address, and setting this option will
ensure this to be the case. This is not the defeault.&lt;/p&gt;
ensure this to be the case. This is not the default.&lt;/p&gt;
&lt;p&gt;Disabling it slightly improves performance and reduces network traffic
somewhat. It also causes the set of port numbers needed by Cyclone DDS to
@ -712,7 +712,7 @@ d0).&lt;/p&gt;&lt;p&gt;The default value is: &amp;quot;0&amp;quot;.&lt;/p&gt;</x
<xs:element name="ParticipantGain" type="xs:integer">
<xs:annotation>
<xs:documentation>
&lt;p&gt;This element specifies the participant gain, relating p0, articipant
&lt;p&gt;This element specifies the participant gain, relating p0, participant
index to sets of port numbers (refer to the DDSI 2.1 specification,
section 9.6.1, constant PG).&lt;/p&gt;&lt;p&gt;The default value is:
&amp;quot;2&amp;quot;.&lt;/p&gt;</xs:documentation>
@ -1187,8 +1187,8 @@ keys.&lt;/p&gt;&lt;p&gt;The default value is: &amp;quot;false&amp;quot;.&lt;/p&g
<xs:element name="HeartbeatInterval">
<xs:annotation>
<xs:documentation>
&lt;p&gt;This elemnents allows configuring the base interval for sending writer
heartbeats and the bounds within it can vary.&lt;/p&gt;
&lt;p&gt;This element allows configuring the base interval for sending writer
heartbeats and the bounds within which it can vary.&lt;/p&gt;
&lt;p&gt;Valid values are finite durations with an explicit unit or the keyword
'inf' for infinity. Recognised units: ns, us, ms, s, min, hr,
@ -1725,8 +1725,8 @@ transport. Enabling write batching causes multiple small write operations
to be aggregated within the write cache into a single larger write. This
gives greater throughput at the expense of latency. Currently there is no
mechanism for the write cache to automatically flush itself, so that if
write batching is enabled, the application may havee to use the
dds_write_flush function to ensure thta all samples are
write batching is enabled, the application may have to use the
dds_write_flush function to ensure that all samples are
written.&lt;/p&gt;&lt;p&gt;The default value is: &amp;quot;false&amp;quot;.&lt;/p&gt;</xs:documentation>
</xs:annotation>
</xs:element>
@ -2309,8 +2309,8 @@ or Tracing/EnabledCategory settings.&lt;/p&gt;&lt;p&gt;The default value is:
<xs:documentation>
&lt;p&gt;This option specifies the file to which received and sent packets will
be logged in the "pcap" format suitable for analysis using common
networking tools, such as WireShark. IP and UDP headers are ficitious, in
particular the destination address of received packets. The TTL may be
networking tools, such as WireShark. IP and UDP headers are fictitious,
in particular the destination address of received packets. The TTL may be
used to distinguish between sent and received packets: it is 255 for sent
packets and 128 for received ones. Currently IPv4 only.&lt;/p&gt;&lt;p&gt;The default
value is: &amp;quot;&amp;quot;.&lt;/p&gt;</xs:documentation>

View file

@ -2,7 +2,7 @@
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>cyclonedds</name>
<version>0.5.1</version>
<version>0.7.0</version>
<description>Eclipse Cyclone DDS is a very performant and robust open-source DDS implementation. Cyclone DDS is developed completely in the open as an Eclipse IoT project.</description>
<maintainer email="cyclonedds-dev@eclipse.org">Eclipse Foundation, Inc.</maintainer>
<license>Eclipse Public License 2.0</license>
@ -12,9 +12,15 @@
<url type="repository">https://github.com/eclipse-cyclonedds/cyclonedds</url>
<buildtool_depend>cmake</buildtool_depend>
<depend>openssl</depend>
<test_depend>libcunit-dev</test_depend>
<doc_depend>doxygen</doc_depend>
<doc_depend>perl</doc_depend>
<doc_depend>python3-breathe</doc_depend>
<doc_depend>python3-sphinx</doc_depend>
<doc_depend>trang</doc_depend>
<export>
<build_type>cmake</build_type>

158
ports/android/README.md Normal file
View file

@ -0,0 +1,158 @@
# Android port
Building for Android 9 (codename Pie), or API level 28. Earlier versions of
Android may be supported at some point, but that would require implementing
replacements for `pthread_attr_setinheritsched` (introduced in level 28) and
`getifaddrs` (introduced in level 24), which is outside the scope of this
document.
> Linux, specifically Fedora 31, was used to create this guide. The steps to
> build Eclipse Cyclone DDS should be more-or-less the same on other
> platforms, the steps to setup the emulator are probably not.
## Installing the Android SDK
[1]: https://developer.android.com/studio
[2]: https://stackoverflow.com/questions/43923996/adb-root-is-not-working-on-emulator-cannot-run-as-root-in-production-builds
* Download [Android Studio](1) and extract the archive.
* Run `android-studio/bin/studio.sh` to launch the *Android Studio Setup
Wizard* and install the *Android SDK*. Select the *Android Virtual Device*
option to install the emulator.
* Click *Configure* from the *Android Studio* welcome screen and select
*SDK Manager*. Switch to the *SDK Tools* tab, select *NDK (Side by side)*,
click *Ok* and wait for the **Android Native Development Kit (NDK)** to
finish downloading.
> *Configure* is available from the *Welcome to Android Studio* window, but
> maybe hidden because it is not appropriatly sized. Resize the window so
> *Configure* and *Get Help* are shown.
* Click *Configure* from the *Android Studio* welcome screen and select
*AVD Manager*. Click *Create Virtual Device*, select the *Phone* category
and choose the *Pixel XL* device definition. Click *Next* and hit
*Download* next to *Q*. *Accept* the *License Agreement* and click *Next*
to download the emulator image. When the download is finished, select *Q*,
click *Next*, then *Finish* to create the *Android Virtual Device (AVD)*.
> As can be read from [this StackOverflow post](2), it is important to NOT
> select a *Google Play* image, as these images do not allow you to gain
> root privileges.
## Building Eclipse Cyclone DDS
[3]: https://developer.android.com/ndk/guides/cmake
[4]: https://developer.android.com/ndk/guides/cmake#variables
The [Android NDK supports CMake](3) via a toolchain file. Build parameters
such as ABI can specified on the command line. For the complete list of
supported variables, consult the [Toolchain Arguments](4) section.
```
$ cd cyclonedds
$ mkdir build.android
$ cd build.android
$ cmake -DCMAKE_TOOLCHAIN_FILE=<path/to/Android/Sdk>/ndk/<version>/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=x86 -DANDROID_NATIVE_API_LEVEL=28 -DBUILD_SHARED_LIBS=Off ..
$ cmake --build .
```
> Android supports shared libraries. `BUILD_SHARED_LIBS` is disabled solely
> for demonstration purposes.
## Deploying ddsperf
* Launch the emulator.
```
$ <path/to/Android/Sdk>/emulator/emulator -avd Pixel_XL_API_29 -netdelay none -netspeed full
```
* Push the `ddsperf` binary to the emulator.
```
$ <path/to/Android/Sdk>/platform-tools/adb push <path/to/cyclonedds>/build.android/bin/ddsperf /data/local/tmp
```
> The binary must be copied to the local filesystem, not the sd-card, as that
> is mounted with the `noexec` flag and will not allow you to execute
> binaries.
* Open a shell on the emulator.
```
$ <path/to/Android/Sdk>/platform-tools/adb shell
```
* Change to `/data/local/tmp` and make the binary executable.
```
$ cd /data/local/tmp
$ chmod 755 ddsperf
```
## Running ddsperf over the loopback interface
* Ensure the emulator is running.
* Open a shell on the emulator.
* Change to `/data/local/tmp`.
* Execute `./ddsperf -D10 pub & ./ddsperf -D10 sub`.
## Running ddsperf over a network interface
Each emulator instance runs behind a virtual router/firewall service that
isolates it from the host. The Android version running in the emulator can
communicate with the host over the loopback interface using the specialized
alias network address *10.0.2.2*, but IGMP and multicast are not supported.
To communicate with binaries not running in the QEMU guest an additional
network interface is required.
* Create a network bridge and a *tap* device for the emulator to use.
```
$ ip link add name br0 type bridge
$ ip link set br0 up
$ ip addr add 192.168.178.1/24 dev br0
$ ip tuntap add dev tap0 mode tap user $USER
$ ip link set tap0 master br0
$ ip link set dev tap0 up promisc on
```
* Launch the emulator with the *tap* device attached.
```
$ <path/to/Android/Sdk>/emulator/emulator -avd Pixel_XL_API_29 -netdelay none -netspeed full -qemu -device virtio-net-pci,netdev=eth1 -netdev tap,id=eth1,ifname=tap0,script=no
```
* Open a shell on the emulator.
* Execute `su` from the shell to become *root*.
* Bring up the interface and assign an IP address.
```
# ip link set dev eth1 up
# ip addr add 192.168.178.2/24 dev eth1
```
* Make normal routing take precedence over anything that google/qemu configured.
```
$ ip rule add from all lookup main pref 99
```
* You should now be able to ping the host from the emulator and vice versa.
> The [KDE Community Wiki](5) is an excellent source of information on the
> Android emulator. The second-to-last instruction stems from there and was
> vital to establish communication between the emulator and the host.
[5]: https://community.kde.org/KDEConnect/Android_Emulator
* Force the guest to use the `eth1` interface.
```
$ export CYCLONEDDS_URI='<CycloneDDS><Domain><General><NetworkInterfaceAddress>eth1</NetworkInterfaceAddress></General></Domain></CycloneDDS>'
```
* Change to `/data/local/tmp`.
* Execute `./ddsperf -D10 pub`.
* Switch to the host.
* Force the host to use the `br0` interface.
```
$ export CYCLONEDDS_URI='<CycloneDDS><Domain><General><NetworkInterfaceAddress>br0</NetworkInterfaceAddress></General></Domain></CycloneDDS>'
```
* Execute `./ddsperf -D10 sub` (native build).

View file

@ -187,17 +187,21 @@ typedef struct dds_builtintopic_guid
}
dds_builtintopic_guid_t;
/* "dds_builtintopic_guid_t" is a bit of a weird name for what everyone just calls a GUID,
so let us try and switch to using the more logical one */
typedef struct dds_builtintopic_guid dds_guid_t;
typedef struct dds_builtintopic_participant
{
dds_builtintopic_guid_t key;
dds_guid_t key;
dds_qos_t *qos;
}
dds_builtintopic_participant_t;
typedef struct dds_builtintopic_endpoint
{
dds_builtintopic_guid_t key;
dds_builtintopic_guid_t participant_key;
dds_guid_t key;
dds_guid_t participant_key;
dds_instance_handle_t participant_instance_handle;
char *topic_name;
char *type_name;
@ -415,6 +419,26 @@ dds_get_mask(dds_entity_t condition, uint32_t *mask);
DDS_EXPORT dds_return_t
dds_get_instance_handle(dds_entity_t entity, dds_instance_handle_t *ihdl);
/**
* @brief Returns the GUID that represents the entity in the network,
* and therefore only supports participants, readers and writers.
*
* @param[in] entity Entity of which to get the instance handle.
* @param[out] guid Where to store the GUID.
*
* @returns A dds_return_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Success.
* @retval DDS_RETCODE_ILLEGAL_OPERATION
* The operation is invoked on an inappropriate object.
* @retval DDS_RETCODE_ERROR
* An internal error has occurred.
*/
/* TODO: Check list of return codes is complete. */
DDS_EXPORT dds_return_t
dds_get_guid (dds_entity_t entity, dds_guid_t *guid);
/*
All entities have a set of "status conditions" (following the DCPS
spec), read peeks, take reads & resets (analogously to read & take

View file

@ -25,6 +25,7 @@
#include "dds/ddsi/ddsi_pmd.h"
#include "dds/ddsi/ddsi_xqos.h"
#include "dds/ddsi/q_transmit.h"
#include "dds/ddsi/q_bswap.h"
extern inline dds_entity *dds_entity_from_handle_link (struct dds_handle_link *hdllink);
extern inline bool dds_entity_is_enabled (const dds_entity *e);
@ -1285,6 +1286,36 @@ dds_return_t dds_get_instance_handle (dds_entity_t entity, dds_instance_handle_t
return ret;
}
dds_return_t dds_get_guid (dds_entity_t entity, dds_guid_t *guid)
{
dds_entity *e;
dds_return_t ret;
if (guid == NULL)
return DDS_RETCODE_BAD_PARAMETER;
if ((ret = dds_entity_pin (entity, &e)) != DDS_RETCODE_OK)
return ret;
switch (dds_entity_kind (e))
{
case DDS_KIND_PARTICIPANT:
case DDS_KIND_READER:
case DDS_KIND_WRITER: {
DDSRT_STATIC_ASSERT (sizeof (dds_guid_t) == sizeof (ddsi_guid_t));
ddsi_guid_t tmp = nn_ntoh_guid (e->m_guid);
memcpy (guid, &tmp, sizeof (*guid));
ret = DDS_RETCODE_OK;
break;
}
default: {
ret = DDS_RETCODE_ILLEGAL_OPERATION;
break;
}
}
dds_entity_unpin(e);
return ret;
}
dds_return_t dds_entity_pin (dds_entity_t hdl, dds_entity **eptr)
{
dds_return_t hres;

View file

@ -175,7 +175,7 @@ static struct ddsi_serdata *serdata_builtin_to_topicless (const struct ddsi_serd
return ddsi_serdata_ref (serdata_common);
}
static void convkey (dds_builtintopic_guid_t *key, const ddsi_guid_t *guid)
static void convkey (dds_guid_t *key, const ddsi_guid_t *guid)
{
ddsi_guid_t tmp;
tmp = nn_hton_guid (*guid);

View file

@ -15,6 +15,7 @@ idlc_generate(RoundTrip RoundTrip.idl)
idlc_generate(Space Space.idl)
idlc_generate(TypesArrayKey TypesArrayKey.idl)
idlc_generate(WriteTypes WriteTypes.idl)
idlc_generate(InstanceHandleTypes InstanceHandleTypes.idl)
set(ddsc_test_sources
"basic.c"
@ -28,6 +29,7 @@ set(ddsc_test_sources
"entity_status.c"
"err.c"
"instance_get_key.c"
"instance_handle.c"
"listener.c"
"liveliness.c"
"loan.c"
@ -73,7 +75,7 @@ target_include_directories(
"$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/src/include/>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../ddsc/src>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../ddsi/include>")
target_link_libraries(cunit_ddsc PRIVATE RoundTrip Space TypesArrayKey WriteTypes ddsc)
target_link_libraries(cunit_ddsc PRIVATE RoundTrip Space TypesArrayKey WriteTypes InstanceHandleTypes ddsc)
# Setup environment for config-tests
get_test_property(CUnit_ddsc_config_simple_udp ENVIRONMENT CUnit_ddsc_config_simple_udp_env)

View file

@ -0,0 +1,23 @@
/*
* Copyright(c) 2020 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.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 InstanceHandleTypes {
struct A {
unsigned long k; //@Key
unsigned long v;
};
#pragma keylist A k
struct C {
octet k[4]; //@Key
unsigned long v;
};
#pragma keylist C k
};

View file

@ -255,6 +255,28 @@ CU_Test(ddsc_entity, status, .init = create_entity, .fini = delete_entity)
CU_ASSERT_EQUAL_FATAL(status1, DDS_RETCODE_OK);
}
CU_Test(ddsc_entity, guid, .init = create_entity, .fini = delete_entity)
{
dds_return_t status;
dds_guid_t guid, zero;
memset(&zero, 0, sizeof(zero));
/* 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_guid (0, NULL);
CU_ASSERT_EQUAL_FATAL(status, DDS_RETCODE_BAD_PARAMETER);
status = dds_get_guid (entity, NULL);
CU_ASSERT_EQUAL_FATAL(status, DDS_RETCODE_BAD_PARAMETER);
status = dds_get_guid (0, &guid);
CU_ASSERT_EQUAL_FATAL(status, DDS_RETCODE_BAD_PARAMETER);
/* Get Instance Handle, which should not be 0 for a participant. */
status = dds_get_guid (entity, &guid);
CU_ASSERT_EQUAL_FATAL(status, DDS_RETCODE_OK);
CU_ASSERT_FATAL(memcmp(&guid, &zero, sizeof(guid)) != 0);
}
CU_Test(ddsc_entity, instance_handle, .init = create_entity, .fini = delete_entity)
{

View file

@ -0,0 +1,134 @@
/*
* Copyright(c) 2020 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.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 <limits.h>
#include "dds/dds.h"
#include "dds/ddsrt/bswap.h"
#include "test_common.h"
#include "InstanceHandleTypes.h"
static dds_entity_t dp, tp[3], rd[3], wr[3];
static void instance_handle_init (void)
{
char topicname[100];
dds_qos_t *qos;
dp = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
CU_ASSERT_FATAL (dp > 0);
/* not strictly necessary to explicitly set KEEP_LAST (it is the default), nor to make
it reliable (it is only used inside a process without any limits that might cause it
to drop samples) */
qos = dds_create_qos ();
CU_ASSERT_FATAL (qos != NULL);
dds_qset_history (qos, DDS_HISTORY_KEEP_LAST, 1);
dds_qset_reliability (qos, DDS_RELIABILITY_RELIABLE, DDS_INFINITY);
create_unique_topic_name ("instance_handle", topicname, sizeof (topicname));
tp[0] = dds_create_topic (dp, &InstanceHandleTypes_A_desc, topicname, NULL, NULL);
CU_ASSERT_FATAL (tp[0] > 0);
create_unique_topic_name ("instance_handle", topicname, sizeof (topicname));
tp[1] = dds_create_topic (dp, &InstanceHandleTypes_A_desc, topicname, NULL, NULL);
CU_ASSERT_FATAL (tp[1] > 0);
create_unique_topic_name ("instance_handle", topicname, sizeof (topicname));
tp[2] = dds_create_topic (dp, &InstanceHandleTypes_C_desc, topicname, NULL, NULL);
CU_ASSERT_FATAL (tp[2] > 0);
dds_delete_qos (qos);
for (size_t i = 0; i < 3; i++)
{
rd[i] = dds_create_reader (dp, tp[i], NULL, NULL);
CU_ASSERT_FATAL (rd[i] > 0);
wr[i] = dds_create_writer (dp, tp[i], NULL, NULL);
CU_ASSERT_FATAL (wr[i] > 0);
}
}
static void instance_handle_fini (void)
{
dds_return_t rc;
rc = dds_delete (dp);
CU_ASSERT_FATAL (rc == 0);
}
CU_Test (ddsc_instance_handle, a, .init = instance_handle_init, .fini = instance_handle_fini)
{
/* By design, Cyclone maintains a global map of (topic class, X, key value) to instance handle,
where the "topic class" is the implementation of the topic (e.g., "default" or "builtin"),
"X" is dependent on the topic class but by design is a fixed constant for the default one,
and key value, again by design, is taken as the serialised representation of the key value.
The point behind this model is that it allows one to use an instance handle obtained on
one reader and use it to read the matching instance in another reader. So that bit of
behaviour needs to be checked.
I'm not sure whether the "serialised" part should be included in the test, I don't think
that's something that should be guaranteed in the API. However, it is worth verifying that
it doesn't go off and do something weird. */
InstanceHandleTypes_A a, b;
InstanceHandleTypes_C c;
dds_return_t rc;
for (uint32_t i = 1; i <= 5; i++)
{
a.k = i;
a.v = i;
b.k = i;
b.v = 2 * a.k;
const uint32_t a_k_be = ddsrt_toBE4u (a.k);
memcpy (c.k, &a_k_be, sizeof (c.k));
c.v = 3 * a.k;
rc = dds_write (wr[0], &a);
CU_ASSERT_FATAL (rc == 0);
rc = dds_write (wr[1], &b);
CU_ASSERT_FATAL (rc == 0);
rc = dds_write (wr[2], &c);
CU_ASSERT_FATAL (rc == 0);
}
for (uint32_t i = 1; i <= 5; i++)
{
dds_sample_info_t siA, siB, siC;
void *rawA = &a, *rawB = &b, *rawC = &c;
/* take one sample from A; no guarantee about the order in which the data is returned */
rc = dds_take (rd[0], &rawA, &siA, 1, 1);
CU_ASSERT_FATAL (rc == 1);
CU_ASSERT_FATAL (siA.valid_data);
CU_ASSERT_FATAL (1 <= a.k && a.k <= 5 && a.v == a.k);
/* take one sample from B using the instance handle just returned */
rc = dds_take_instance (rd[1], &rawB, &siB, 1, 1, siA.instance_handle);
CU_ASSERT_FATAL (rc == 1);
CU_ASSERT_FATAL (siB.valid_data);
CU_ASSERT_FATAL (siB.instance_handle == siA.instance_handle);
CU_ASSERT_FATAL (b.k == a.k && b.v == 2 * a.k);
/* take one sample from C using the instance handle just returned, this should work
even though C uses an array of octets as key */
rc = dds_take_instance (rd[2], &rawC, &siC, 1, 1, siA.instance_handle);
CU_ASSERT_FATAL (rc == 1);
CU_ASSERT_FATAL (siC.valid_data);
CU_ASSERT_FATAL (siC.instance_handle == siA.instance_handle);
const uint32_t a_k_be = ddsrt_toBE4u (a.k);
CU_ASSERT_FATAL (memcmp (c.k, &a_k_be, sizeof (c.k)) == 0 && c.v == 3 * a.k);
}
/* there should be no data left */
for (size_t i = 0; i < 3; i++)
{
dds_sample_info_t si;
void *raw = NULL;
rc = dds_take (rd[0], &raw, &si, 1, 1);
CU_ASSERT_FATAL (rc == 0);
}
}

View file

@ -102,6 +102,13 @@ DDSRT_STATIC_ASSERT (sizeof (struct nn_rmsg) == offsetof (struct nn_rmsg, chunk)
#define NN_RMSG_PAYLOAD(m) ((unsigned char *) (m + 1))
#define NN_RMSG_PAYLOADOFF(m, o) (NN_RMSG_PAYLOAD (m) + (o))
/* Align rmsg chunks to the larger of sizeof(void*) or 8.
Ideally, we would use C11's alignof(struct nn_rmsg); however, to avoid dependency on C11,
we ensure rmsg chunks are at least aligned to sizeof(void *) or 8,
whichever is larger. */
#define ALIGNOF_RMSG (sizeof(void *) > 8 ? sizeof(void *) : 8)
struct receiver_state {
ddsi_guid_prefix_t src_guid_prefix; /* 12 */
ddsi_guid_prefix_t dst_guid_prefix; /* 12 */

View file

@ -562,7 +562,7 @@ static const struct cfgelem compatibility_cfgelems[] = {
BLURB("<p>This element specifies whether QoS settings set to default values are explicitly published in the discovery protocol. Implementations are to use the default value for QoS settings not published, which allows a significant reduction of the amount of data that needs to be exchanged for the discovery protocol, but this requires all implementations to adhere to the default values specified by the specifications.</p>\n\
<p>When interoperability is required with an implementation that does not follow the specifications in this regard, setting this option to true will help.</p>") },
{ LEAF ("ManySocketsMode"), 1, "single", ABSOFF (many_sockets_mode), 0, uf_many_sockets_mode, 0, pf_many_sockets_mode,
BLURB("<p>This option specifies whether a network socket will be created for each domain participant on a host. The specification seems to assume that each participant has a unique address, and setting this option will ensure this to be the case. This is not the defeault.</p>\n\
BLURB("<p>This option specifies whether a network socket will be created for each domain participant on a host. The specification seems to assume that each participant has a unique address, and setting this option will ensure this to be the case. This is not the default.</p>\n\
<p>Disabling it slightly improves performance and reduces network traffic somewhat. It also causes the set of port numbers needed by DDSI2E to become predictable, which may be useful for firewall and NAT configuration.</p>") },
{ LEAF("AssumeRtiHasPmdEndpoints"), 1, "false", ABSOFF(assume_rti_has_pmd_endpoints), 0, uf_boolean, 0, pf_boolean,
BLURB("<p>This option assumes ParticipantMessageData endpoints required by the liveliness protocol are present in RTI participants even when not properly advertised by the participant discovery protocol.</p>") },
@ -674,7 +674,7 @@ static const struct cfgelem internal_cfgelems[] = {
BLURB("<p>This setting determines the size of the time window in which a NACK of some sample is ignored because a retransmit of that sample has been multicasted too recently. This setting has no effect on unicasted retransmits.</p>\n\
<p>See also Internal/RetransmitMerging.</p>") },
{ LEAF_W_ATTRS("HeartbeatInterval", heartbeat_interval_attrs), 1, "100 ms", ABSOFF(const_hb_intv_sched), 0, uf_duration_inf, 0, pf_duration,
BLURB("<p>This elemnents allows configuring the base interval for sending writer heartbeats and the bounds within it can vary.</p>") },
BLURB("<p>This element allows configuring the base interval for sending writer heartbeats and the bounds within which it can vary.</p>") },
{ LEAF("MaxQueuedRexmitBytes"), 1, "50 kB", ABSOFF(max_queued_rexmit_bytes), 0, uf_memsize, 0, pf_memsize,
BLURB("<p>This setting limits the maximum number of bytes queued for retransmission. The default value of 0 is unlimited unless an AuxiliaryBandwidthLimit has been set, in which case it becomes NackDelay * AuxiliaryBandwidthLimit. It must be large enough to contain the largest sample that may need to be retransmitted.</p>") },
{ LEAF("MaxQueuedRexmitMessages"), 1, "200", ABSOFF(max_queued_rexmit_msgs), 0, uf_uint, 0, pf_uint,
@ -715,7 +715,7 @@ static const struct cfgelem internal_cfgelems[] = {
{ LEAF("MaxSampleSize"), 1, "2147483647 B", ABSOFF(max_sample_size), 0, uf_memsize, 0, pf_memsize,
BLURB("<p>This setting controls the maximum (CDR) serialised size of samples that DDSI2E will forward in either direction. Samples larger than this are discarded with a warning.</p>") },
{ LEAF("WriteBatch"), 1, "false", ABSOFF(whc_batch), 0, uf_boolean, 0, pf_boolean,
BLURB("<p>This element enables the batching of write operations. By default each write operation writes through the write cache and out onto the transport. Enabling write batching causes multiple small write operations to be aggregated within the write cache into a single larger write. This gives greater throughput at the expense of latency. Currently there is no mechanism for the write cache to automatically flush itself, so that if write batching is enabled, the application may havee to use the dds_write_flush function to ensure thta all samples are written.</p>") },
BLURB("<p>This element enables the batching of write operations. By default each write operation writes through the write cache and out onto the transport. Enabling write batching causes multiple small write operations to be aggregated within the write cache into a single larger write. This gives greater throughput at the expense of latency. Currently there is no mechanism for the write cache to automatically flush itself, so that if write batching is enabled, the application may have to use the dds_write_flush function to ensure that all samples are written.</p>") },
{ LEAF_W_ATTRS("LivelinessMonitoring", liveliness_monitoring_attrs), 1, "false", ABSOFF(liveliness_monitoring), 0, uf_boolean, 0, pf_boolean,
BLURB("<p>This element controls whether or not implementation should internally monitor its own liveliness. If liveliness monitoring is enabled, stack traces can be dumped automatically when some thread appears to have stopped making progress.</p>") },
{ LEAF("MonitorPort"), 1, "-1", ABSOFF(monitor_port), 0, uf_int, 0, pf_int,
@ -760,7 +760,7 @@ static const struct cfgelem discovery_ports_cfgelems[] = {
{ LEAF("DomainGain"), 1, "250", ABSOFF(ports.dg), 0, uf_uint, 0, pf_uint,
BLURB("<p>This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant DG).</p>") },
{ LEAF("ParticipantGain"), 1, "2", ABSOFF(ports.pg), 0, uf_uint, 0, pf_uint,
BLURB("<p>This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant PG).</p>") },
BLURB("<p>This element specifies the participant gain, relating p0, participant index to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant PG).</p>") },
{ LEAF("MulticastMetaOffset"), 1, "0", ABSOFF(ports.d0), 0, uf_uint, 0, pf_uint,
BLURB("<p>This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d0).</p>") },
{ LEAF("UnicastMetaOffset"), 1, "10", ABSOFF(ports.d1), 0, uf_uint, 0, pf_uint,
@ -906,7 +906,7 @@ static const struct cfgelem tracing_cfgelems[] = {
{ LEAF("AppendToFile"), 1, "false", ABSOFF(tracingAppendToFile), 0, uf_boolean, 0, pf_boolean,
BLURB("<p>This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated.</p>") },
{ LEAF("PacketCaptureFile"), 1, "", ABSOFF(pcap_file), 0, uf_string, ff_free, pf_string,
BLURB("<p>This option specifies the file to which received and sent packets will be logged in the \"pcap\" format suitable for analysis using common networking tools, such as WireShark. IP and UDP headers are ficitious, in particular the destination address of received packets. The TTL may be used to distinguish between sent and received packets: it is 255 for sent packets and 128 for received ones. Currently IPv4 only.</p>") },
BLURB("<p>This option specifies the file to which received and sent packets will be logged in the \"pcap\" format suitable for analysis using common networking tools, such as WireShark. IP and UDP headers are fictitious, in particular the destination address of received packets. The TTL may be used to distinguish between sent and received packets: it is 255 for sent packets and 128 for received ones. Currently IPv4 only.</p>") },
END_MARKER
};

View file

@ -303,9 +303,11 @@ static void nn_rbuf_release (struct nn_rbuf *rbuf);
#define RMSGTRACE(...) TRACE_CFG (rmsg, rmsg->chunk.rbuf->rbufpool->logcfg, __VA_ARGS__)
#define RDATATRACE(rdata, ...) TRACE_CFG ((rdata)->rmsg, (rdata)->rmsg->chunk.rbuf->rbufpool->logcfg, __VA_ARGS__)
static uint32_t align8uint32 (uint32_t x)
static uint32_t align_rmsg (uint32_t x)
{
return (x + 7u) & (uint32_t)-8;
x += (uint32_t) ALIGNOF_RMSG - 1;
x -= x % (uint32_t) ALIGNOF_RMSG;
return x;
}
#ifndef NDEBUG
@ -553,15 +555,15 @@ struct nn_rmsg *nn_rmsg_new (struct nn_rbufpool *rbp)
void nn_rmsg_setsize (struct nn_rmsg *rmsg, uint32_t size)
{
uint32_t size8 = align8uint32 (size);
RMSGTRACE ("rmsg_setsize(%p, %"PRIu32" => %"PRIu32")\n", (void *) rmsg, size, size8);
uint32_t size8P = align_rmsg (size);
RMSGTRACE ("rmsg_setsize(%p, %"PRIu32" => %"PRIu32")\n", (void *) rmsg, size, size8P);
ASSERT_RBUFPOOL_OWNER (rmsg->chunk.rbuf->rbufpool);
ASSERT_RMSG_UNCOMMITTED (rmsg);
assert (ddsrt_atomic_ld32 (&rmsg->refcount) == RMSG_REFCOUNT_UNCOMMITTED_BIAS);
assert (rmsg->chunk.u.size == 0);
assert (size8 <= rmsg->chunk.rbuf->max_rmsg_size);
assert (size8P <= rmsg->chunk.rbuf->max_rmsg_size);
assert (rmsg->lastchunk == &rmsg->chunk);
rmsg->chunk.u.size = size8;
rmsg->chunk.u.size = size8P;
#if USE_VALGRIND
VALGRIND_MEMPOOL_CHANGE (rmsg->chunk.rbuf->rbufpool, rmsg, rmsg, offsetof (struct nn_rmsg, chunk.u.payload) + rmsg->chunk.size);
#endif
@ -620,7 +622,7 @@ void nn_rmsg_commit (struct nn_rmsg *rmsg)
ASSERT_RBUFPOOL_OWNER (chunk->rbuf->rbufpool);
ASSERT_RMSG_UNCOMMITTED (rmsg);
assert (chunk->u.size <= chunk->rbuf->max_rmsg_size);
assert ((chunk->u.size % 8) == 0);
assert ((chunk->u.size % ALIGNOF_RMSG) == 0);
assert (ddsrt_atomic_ld32 (&rmsg->refcount) >= RMSG_REFCOUNT_UNCOMMITTED_BIAS);
assert (ddsrt_atomic_ld32 (&rmsg->chunk.rbuf->n_live_rmsg_chunks) > 0);
assert (ddsrt_atomic_ld32 (&chunk->rbuf->n_live_rmsg_chunks) > 0);
@ -677,15 +679,15 @@ void *nn_rmsg_alloc (struct nn_rmsg *rmsg, uint32_t size)
{
struct nn_rmsg_chunk *chunk = rmsg->lastchunk;
struct nn_rbuf *rbuf = chunk->rbuf;
uint32_t size8 = align8uint32 (size);
uint32_t size8P = align_rmsg (size);
void *ptr;
RMSGTRACE ("rmsg_alloc(%p, %"PRIu32" => %"PRIu32")\n", (void *) rmsg, size, size8);
RMSGTRACE ("rmsg_alloc(%p, %"PRIu32" => %"PRIu32")\n", (void *) rmsg, size, size8P);
ASSERT_RBUFPOOL_OWNER (rbuf->rbufpool);
ASSERT_RMSG_UNCOMMITTED (rmsg);
assert ((chunk->u.size % 8) == 0);
assert (size8 <= rbuf->max_rmsg_size);
assert ((chunk->u.size % ALIGNOF_RMSG) == 0);
assert (size8P <= rbuf->max_rmsg_size);
if (chunk->u.size + size8 > rbuf->max_rmsg_size)
if (chunk->u.size + size8P > rbuf->max_rmsg_size)
{
struct nn_rbufpool *rbp = rbuf->rbufpool;
struct nn_rmsg_chunk *newchunk;
@ -703,7 +705,7 @@ void *nn_rmsg_alloc (struct nn_rmsg *rmsg, uint32_t size)
}
ptr = (unsigned char *) (chunk + 1) + chunk->u.size;
chunk->u.size += size8;
chunk->u.size += size8P;
RMSGTRACE ("rmsg_alloc(%p, %"PRIu32") = %p\n", (void *) rmsg, size, ptr);
#if USE_VALGRIND
if (chunk == &rmsg->chunk) {

View file

@ -62,6 +62,10 @@ if(WITH_FREERTOS)
set(system_name freertos)
elseif(APPLE)
set(system_name darwin)
elseif(ANDROID)
# FIXME: Not correct, but will do for the short-term. A better way would be
# fallback to linux, and then posix.
set(system_name linux)
else()
string(TOLOWER ${CMAKE_SYSTEM_NAME} system_name)
endif()

View file

@ -32,9 +32,9 @@
#include <fcntl.h>
#endif
#ifdef __APPLE__
#if defined(__APPLE__) || defined(__FreeBSD__)
#include <sys/sockio.h>
#endif /* __APPLE__ */
#endif /* __APPLE__ || __FreeBSD__ */
#endif /* LWIP_SOCKET */
dds_return_t
@ -316,13 +316,13 @@ ddsrt_setsockopt(
goto err_setsockopt;
}
#if defined(__APPLE__)
#if defined(__APPLE__) || defined(__FreeBSD__)
if (level == SOL_SOCKET && optname == SO_REUSEADDR &&
setsockopt(sock, level, SO_REUSEPORT, optval, optlen) == -1)
{
goto err_setsockopt;
}
#endif /* __APPLE__ */
#endif /* __APPLE__ || __FreeBSD__ */
return DDS_RETCODE_OK;
err_setsockopt:

View file

@ -12,10 +12,10 @@
# Verify Maven is available
find_package(Maven 3.0 REQUIRED)
file(GLOB_RECURSE IDLC_G_SOURCES LIST_DIRECTORIES true *.g)
file(GLOB_RECURSE IDLC_G4_SOURCES LIST_DIRECTORIES true *.g4)
file(GLOB_RECURSE IDLC_JAVA_SOURCES LIST_DIRECTORIES true *.java)
file(GLOB_RECURSE IDLC_ST_SOURCES LIST_DIRECTORIES true *.st?)
file(GLOB_RECURSE IDLC_G_SOURCES LIST_DIRECTORIES false *.g)
file(GLOB_RECURSE IDLC_G4_SOURCES LIST_DIRECTORIES false *.g4)
file(GLOB_RECURSE IDLC_JAVA_SOURCES LIST_DIRECTORIES false *.java)
file(GLOB_RECURSE IDLC_ST_SOURCES LIST_DIRECTORIES false *.st?)
set(IDLC_JAR "${CMAKE_CURRENT_BINARY_DIR}/target/idlc-jar-with-dependencies.jar")
mark_as_advanced(IDLC_JAR)

View file

@ -36,7 +36,7 @@ public class IdlcCmdOptions extends CmdOptions
io.println (" -nostamp Do not timestamp generated code");
io.println (" -lax Skip over structs containing unsupported datatypes");
io.println (" -quiet Suppress console output other than error messages (default)");
io.println (" -verbose Enable console ouptut other than error messages");
io.println (" -verbose Enable console output other than error messages");
io.println (" -map_wide Map the unsupported wchar and wstring types to char and string");
io.println (" -map_longdouble Map the unsupported long double type to double");
}

View file

@ -385,7 +385,7 @@ static void qp_qos (const dds_qos_t *q, FILE *fp)
qp_group_data (q, fp);
}
static void print_key(FILE *fp, const char *label, const dds_builtintopic_guid_t *key)
static void print_key(FILE *fp, const char *label, const dds_guid_t *key)
{
fprintf(fp, "%s", label);
for(size_t j = 0; j < sizeof (key->v); j++) {

View file

@ -283,7 +283,7 @@ struct ppant {
ddsrt_avl_node_t avlnode; /* embedded AVL node for handle index */
ddsrt_fibheap_node_t fhnode; /* prio queue for timeout handling */
dds_instance_handle_t handle; /* participant instance handle */
dds_builtintopic_guid_t guid; /* participant GUID */
dds_guid_t guid; /* participant GUID */
char *hostname; /* hostname is taken from user_data QoS */
uint32_t pid; /* pid is also taken from user_data QoS */
dds_time_t tdisc; /* time at which it was discovered */
@ -357,7 +357,7 @@ static void error3 (const char *fmt, ...)
verrorx (3, fmt, ap);
}
static char *make_guidstr (struct guidstr *buf, const dds_builtintopic_guid_t *guid)
static char *make_guidstr (struct guidstr *buf, const dds_guid_t *guid)
{
snprintf (buf->str, sizeof (buf->str), "%02x%02x%02x%02x_%02x%02x%02x%02x_%02x%02x%02x%02x_%02x%02x%02x%02x",
guid->v[0], guid->v[1], guid->v[2], guid->v[3],