diff --git a/.azure/templates/build-test.yml b/.azure/templates/build-test.yml
index f8076a12..db55d0fc 100644
--- a/.azure/templates/build-test.yml
+++ b/.azure/templates/build-test.yml
@@ -79,7 +79,7 @@ steps:
pre-commit run --all-files
name: run_pre_commit
- bash: |
- pip install gcovr --user --upgrade
+ pip install gcovr==5.0 --user --upgrade
condition: eq(variables['coverage'], 'on')
name: install_gcovr
- bash: |
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 06648da8..f046b631 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,7 +10,7 @@
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#
cmake_minimum_required(VERSION 3.10)
-project(CycloneDDS VERSION 0.9.0 LANGUAGES C)
+project(CycloneDDS VERSION 0.9.1 LANGUAGES C)
if(CMAKE_VERSION VERSION_LESS 3.12)
# GENERATE_EXPORT_HEADER requires a C++ compiler up to version 3.12
enable_language(CXX)
@@ -346,4 +346,4 @@ if(DEFINED ENV{LIB_FUZZING_ENGINE})
add_subdirectory(fuzz)
endif()
-include(CMakeCPack.cmake)
\ No newline at end of file
+include(CMakeCPack.cmake)
diff --git a/README.md b/README.md
index 9b5ec01a..5da77b67 100644
--- a/README.md
+++ b/README.md
@@ -4,249 +4,30 @@
[](https://choosealicense.com/licenses/epl-2.0/)
[](https://choosealicense.com/licenses/edl-1.0/)
-# Eclipse Cyclone DDS
+# This branch supports CycloneDDS over FreeRTOS-Plus-TCP stack on FreeRTOS.
+CycloneDDS looks have support on FreeRTOS+LWIP Stack,
+however lacking FreeRTOS-Plus-TCP Stack support
+This change managed to add +TCP support
+
+* base CycloneDDS version0.9.1
+* ddsrt socket / thread ...
+
+[Changes]
++TCP socket
+ddsrt header and source
+sockaddr ifaddr
+.init_array section
+log sink
+multicast/unicast peer define in xml
+TLS-Thread_Local_Storage from FreeRTOS SW impl instread of toolchain
+sock_waitset
+sock fdset
+sendmsg/recvmsg for UDP
+dds_align from 0.10.2
+FragmentSize for jumbo and normal
+
+# DDS Readme refer to master readme
+Link:
+https://github.com/polejoe/cycloneDDS_RTOS/blob/master/README.md
-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)) 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://docs.ros.org/en/rolling/).
-* [Getting Started](#getting-started)
-* [Performance](#performance)
-* [Configuration](#configuration)
-
-> Consult the [roadmap](ROADMAP.md) for a high-level overview of upcoming features.
-
-# Getting Started
-
-## Building Eclipse Cyclone DDS
-
-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;
- * [CMake](https://cmake.org/download/), version 3.10 or later;
- * [OpenSSL](https://www.openssl.org/), preferably version 1.1 or later if you want to use TLS over
- TCP. You can explicitly disable it by setting ``ENABLE_SSL=NO``, which is very useful for
- reducing the footprint or when the FindOpenSSL CMake script gives you trouble;
- * Optionally [Bison](https://www.gnu.org/software/bison/) parser generator. A cached source is checked into the repository.
-
-If you want to play around with the parser you will need to install the bison parser generator. On Ubuntu ``apt install bison`` should do the trick for getting it installed.
-On Windows, installing chocolatey and ``choco install winflexbison3`` should get you a long way. On macOS, ``brew install bison`` is easiest.
-
-To obtain Eclipse Cyclone DDS, do
-
- $ git clone https://github.com/eclipse-cyclonedds/cyclonedds.git
- $ cd cyclonedds
- $ mkdir build
-
-Depending on whether you want to develop applications using Cyclone DDS or contribute to it you can
-follow different procedures
-
-### For application developers
-
-To build and install the required libraries needed to develop your own applications using Cyclone
-DDS requires a few simple steps. There are some small differences between Linux and macOS on the one
-hand, and Windows on the other. For Linux or macOS:
-
- $ cd build
- $ cmake -DCMAKE_INSTALL_PREFIX= -DBUILD_EXAMPLES=ON ..
- $ cmake --build .
-
-and for Windows:
-
- $ cd build
- $ cmake -G "" -DCMAKE_INSTALL_PREFIX= -DBUILD_EXAMPLES=ON ..
- $ cmake --build .
-
-where you should replace ```` by the directory under which you would like to
-install Cyclone DDS and ```` by one of the ways
-CMake [generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html) offer for
-generating build files. For example, "Visual Studio 15 2017 Win64" would target a 64-bit build
-using Visual Studio 2017.
-
-To install it after a successful build, do:
-
- $ cmake --build . --target install
-
-which will copy everything to:
-
- * ``/lib``
- * ``/bin``
- * ``/include/ddsc``
- * ``/share/CycloneDDS``
-
-Depending on the installation location you may need administrator privileges.
-
-At this point you are ready to use Eclipse Cyclone DDS in your own projects.
-
-Note that the default build type is a release build with debug information included
-(RelWithDebInfo), which is generally the most convenient type of build to use from applications
-because of a good mix between performance and still being able to debug things. If you'd rather
-have a Debug or pure Release build, set ``CMAKE_BUILD_TYPE`` accordingly.
-
-### Contributing to Eclipse Cyclone DDS
-
-We very much welcome all contributions to the project, whether that is questions, examples, bug
-fixes, enhancements or improvements to the documentation, or anything else really. When considering
-contributing code, it might be good to know that build configurations for Travis CI and AppVeyor are
-present in the repository and that there is a test suite using CTest and CUnit that can be built
-locally if desired. To build it, set the cmake variable ``BUILD_TESTING`` to on when configuring, e.g.:
-
- $ cd build
- $ cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON ..
- $ cmake --build .
- $ ctest
-
-Such a build requires the presence of [CUnit](http://cunit.sourceforge.net/). You can install this
-yourself, or you can choose to instead rely on the [Conan](https://conan.io) packaging system that
-the CI build infrastructure also uses. In that case, install Conan and do:
-
- $ conan install .. --build missing
-
-in the build directory prior to running cmake.
-
-For Windows, depending on the generator, you might also need to add switches to select the architecture
-and build type, e.g., ``conan install -s arch=x86_64 -s build_type=Debug ..`` This will automatically
-download and/or build CUnit (and, at the moment, OpenSSL).
-
-## Documentation
-
-The documentation is still rather limited, and at the moment only available in the sources (in the
-form of restructured text files in ``docs`` and Doxygen comments in the header files), or as
-a
-[PDF](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/pdf/CycloneDDS-0.1.0.pdf). The
-intent is to automate the process of building the documentation and have them available in more
-convenient formats and in the usual locations.
-
-## Building and Running the Roundtrip Example
-
-We will show you how to build and run an example program that measures latency. The examples are
-built automatically when you build Cyclone DDS, so you don't need to follow these steps to be able
-to run the program, it is merely to illustrate the process.
-
- $ mkdir roundtrip
- $ cd roundtrip
- $ cmake /share/CycloneDDS/examples/roundtrip
- $ cmake --build .
-
-On one terminal start the application that will be responding to pings:
-
- $ ./RoundtripPong
-
-On another terminal, start the application that will be sending the pings:
-
- $ ./RoundtripPing 0 0 0
- # payloadSize: 0 | numSamples: 0 | timeOut: 0
- # Waiting for startup jitter to stabilise
- # Warm up complete.
- # Latency measurements (in us)
- # Latency [us] Write-access time [us] Read-access time [us]
- # Seconds Count median min 99% max Count median min Count median min
- 1 28065 17 16 23 87 28065 8 6 28065 1 0
- 2 28115 17 16 23 46 28115 8 6 28115 1 0
- 3 28381 17 16 22 46 28381 8 6 28381 1 0
- 4 27928 17 16 24 127 27928 8 6 27928 1 0
- 5 28427 17 16 20 47 28427 8 6 28427 1 0
- 6 27685 17 16 26 51 27685 8 6 27685 1 0
- 7 28391 17 16 23 47 28391 8 6 28391 1 0
- 8 27938 17 16 24 63 27938 8 6 27938 1 0
- 9 28242 17 16 24 132 28242 8 6 28242 1 0
- 10 28075 17 16 23 46 28075 8 6 28075 1 0
-
-The numbers above were measured on Mac running a 4.2 GHz Intel Core i7 on December 12th 2018. From
-these numbers you can see how the roundtrip is very stable and the minimal latency is now down to 17
-micro-seconds (used to be 25 micro-seconds) on this HW.
-
-# Performance
-
-Reliable message throughput is over 1MS/s for very small samples and is roughly 90% of GbE with 100
-byte samples, and latency is about 30us when measured using [ddsperf](src/tools/ddsperf) between two
-Intel(R) Xeon(R) CPU E3-1270 V2 @ 3.50GHz (that's 2012 hardware ...) running Ubuntu 16.04, with the
-executables built on Ubuntu 18.04 using gcc 7.4.0 for a default (i.e., "RelWithDebInfo") build.
-
-
-
-This is with the subscriber in listener mode, using asynchronous delivery for the throughput
-test. The configuration is a marginally tweaked out-of-the-box configuration: an increased maximum
-message size and fragment size, and an increased high-water mark for the reliability window on the
-writer side. For details, see the [scripts](examples/perfscript) directory,
-the
-[environment details](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/config.txt) and
-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 ([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
-
-The out-of-the-box configuration should usually be fine, but there are a great many options that can
-be tweaked by creating an XML file with the desired settings and defining the ``CYCLONEDDS_URI`` to
-point to it. E.g. (on Linux):
-
- $ cat cyclonedds.xml
-
-
-
-
-
-
-
- default
- 65500B
- 4000B
-
-
-
- 500kB
-
-
-
- config
- stdout
-
-
-
- $ export CYCLONEDDS_URI=file://$PWD/cyclonedds.xml
-
-(on Windows, one would have to use ``set CYCLONEDDS_URI=file://...`` instead.)
-
-This example shows a few things:
-
-* ``Interfaces`` can be used to override the interfaces selected by default. Members are
- * ``NetworkInterface[@autodetermine]`` tells Cyclone DDS to autoselect the interface it deems best.
- * ``NetworkInterface[@name]`` specifies the name of an interface to select (not shown above, alternative for autodetermine).
- * ``NetworkInterface[@ip]`` specifies the ipv4/ipv6 address of an interface to select (not shown above, alternative for autodetermine).
- * ``NetworkInterface[@multicast]`` specifies whether multicast should be used on this interface.
- The default value 'default' means Cyclone DDS will check the OS reported flags of the interface
- and enable multicast if it is supported. Use 'true' to ignore what the OS reports and enable it
- anyway and 'false' to always disable multicast on this interface.
- * ``NetworkInterface[@priority]`` specifies the priority of an interface. The default value (``default``)
- means priority ``0`` for normal interfaces and ``2`` for loopback interfaces.
-* ``AllowMulticast`` configures the circumstances under which multicast will be used. If the
- selected interface doesn't support it, it obviously won't be used (``false``); but if it does
- support it, the type of the network adapter determines the default value. For a wired network, it
- will use multicast for initial discovery as well as for data when there are multiple peers that
- the data needs to go to (``true``); but on a WiFi network it will use it only for initial
- discovery (``spdp``), because multicast on WiFi is very unreliable.
-* ``Verbosity`` allows control over the tracing, "config" dumps the configuration to the trace
- output (which defaults to "cyclonedds.log"). Which interface is used, what multicast settings are
- used, etc., is all in the trace. Setting the verbosity to "finest" gives way more output on the
- inner workings, and there are various other levels as well.
-* ``MaxMessageSize`` and ``FragmentSize`` control the maximum size of the RTPS messages (basically
- the size of the UDP payload), and the size of the fragments into which very large samples get
- split (which needs to be "a bit" less). Large values such as these typically improve performance
- over the (current) default values.
-* ``WhcHigh`` determines when the sender will wait for acknowledgements from the readers because it
- has buffered too much unacknowledged data. There is some auto-tuning, the (current) default value
- is a bit small to get really high throughput.
-
-Background information on configuring Cyclone DDS can be found
-[here](docs/manual/config.rst) and a list of settings is
-[available](docs/manual/options.md).
-
-# Trademarks
-
-* "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.
diff --git a/cmake/CheckHashScript.cmake b/cmake/CheckHashScript.cmake
index 4edc4bb2..f6f90218 100644
--- a/cmake/CheckHashScript.cmake
+++ b/cmake/CheckHashScript.cmake
@@ -3,11 +3,11 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/Modules")
include(HashUtilities)
check_hashes(
- OUTVAR _test
+ _test
HASH_FILES ${HASH_FILES}
APPEND_FILES ${APPEND_FILES}
)
if (NOT ${_test})
message(FATAL_ERROR "Not up to date")
-endif()
\ No newline at end of file
+endif()
diff --git a/cmake/Modules/FindLcov.cmake b/cmake/Modules/FindLcov.cmake
index dc2eebb7..de4aba52 100644
--- a/cmake/Modules/FindLcov.cmake
+++ b/cmake/Modules/FindLcov.cmake
@@ -78,7 +78,7 @@ include(FindPackageHandleStandardArgs)
find_program(LCOV_BIN lcov)
find_program(GENINFO_BIN geninfo)
find_program(GENHTML_BIN genhtml)
-find_package_handle_standard_args(lcov
+find_package_handle_standard_args(Lcov
REQUIRED_VARS LCOV_BIN GENINFO_BIN GENHTML_BIN
)
diff --git a/docs/dev/xtypes_relnotes.md b/docs/dev/xtypes_relnotes.md
new file mode 100644
index 00000000..90415773
--- /dev/null
+++ b/docs/dev/xtypes_relnotes.md
@@ -0,0 +1,44 @@
+# Cyclone XTypes support
+
+## Release 0.9
+
+### Type System
+
+- The following data types are not supported: map, bitset, wide-strings, char16, float128
+- For the C language binding, additionally the following types are not supported as part of a type’s key: union, sequence
+- Union types:
+ - Using bitmask type as discriminator is not supported
+ - Inheritance (7.2.2.4.5) is not supported
+ - Extensibility `mutable` for unions is not supported
+- The Dynamic Language Binding (7.5.2) is not supported (7.6.6, DynamicData and DynamicType API). Note: the Python API supports dynamic types without requiring a separate API.
+- The built-in TypeLookup service (7.6.3.3) has no support for requesting type dependencies (service operation `getTypeDependencies`, section 7.6.3.3.4.1) and replying to a request of this type.
+ - Because of this, handling `PublicationBuiltinTopicData` or `SubscriptionBuiltinTopicData` with an incomplete set of dependent types (i.e. number of entries in `dependent_typeids` is less than `dependent_typeid_count`) may result in a failure to match a reader with a writer.
+- In case a union has a default case, the C (de)serializer requires that the default case comes last because of a limitation of the IDL compiler.
+- Using the `try_construct` annotation (7.2.2.7) with a parameter other than `DISCARD` (the default) is not supported.
+- The C deserializer does not support explicit defaults for members of an aggregated type (`default` annotation)
+- External (7.3.1.2.1.4) collections element types not supported (e.g. `sequence<@external b>`)
+- Using `default_literal` (7.3.1.2.1.10) to set the default for enumerated types is not supported
+- Default extensibility is `final` rather than `appendable` to maintain backwards compatibility with DDS implementations that do not support XTypes (including Cyclone DDS versions prior to 0.9.0). The IDL compiler has command-line option to select a different default.
+
+### Type Representation
+
+- Type Object type representation
+ - Recursive types are not supported (Strongly Connected Components, 7.3.4.9)
+ - User-defined annotations (7.3.1.2.4) and `verbatim` annotations (7.3.2.5.1.1) are not included in complete type objects
+- IDL type representation
+ - Pragma declarations other than `keylist` are not supported
+ - Alternative Annotation Syntax (7.3.1.2.3) is not supported
+ - `verbatim` annotation (7.3.2.5.1.1) is not supported
+ - `ignore_literal_names` annotation (7.3.1.2.1.11) is not supported
+ - `non_serialized` annotation (7.3.1.2.1.14) is not supported
+- XML (7.3.2) and XSD (7.3.3) type representation not supported
+
+### Data Representation
+
+- Default data representation is XCDR1 for `@final` types without optional members to maintain backwards compatibility with DDS implementations that do not support XTypes (including Cyclone DDS versions prior to 0.9.0).
+
+ All other types require XCDR2: following 7.6.3.1.1 there is no need to support XCDR1 for interoperating with DDS implementations (ignoring those that only support XTypes 1.0 or 1.1, but not 1.2 or later).
+
+ The C serializer does not support PL-CDR version 1 nor optional members in PLAIN-CDR version 1.
+
+- XML data representation (7.4.4) is not supported
\ No newline at end of file
diff --git a/package.xml b/package.xml
index 34ea4fbc..8a8b152e 100644
--- a/package.xml
+++ b/package.xml
@@ -2,7 +2,7 @@
cyclonedds
- 0.9.0
+ 0.9.1
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.
Eclipse Foundation, Inc.
Eclipse Public License 2.0
diff --git a/ports/android/README.md b/ports/android/README.md
index 0888e8f5..0173ce12 100644
--- a/ports/android/README.md
+++ b/ports/android/README.md
@@ -16,7 +16,7 @@ document.
[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.
+ * 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*
@@ -38,7 +38,7 @@ document.
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
+> 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.
@@ -48,9 +48,9 @@ document.
[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
+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.
+supported variables, consult the [Toolchain Arguments][4] section.
```
$ cd cyclonedds
@@ -137,7 +137,7 @@ $ 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
+> 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.
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ac30414c..8c0049c7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -27,6 +27,7 @@ option(ENABLE_LIFESPAN "Enable Lifespan QoS support" ON)
option(ENABLE_DEADLINE_MISSED "Enable Deadline Missed QoS support" ON)
option(ENABLE_NETWORK_PARTITIONS "Enable network partition support" ON)
option(ENABLE_SOURCE_SPECIFIC_MULTICAST "Enable support for source-specific multicast" ON)
+option(ENABLE_IPV6 "Enable ipv6 support" ON)
option(ENABLE_TYPE_DISCOVERY "Enable Type Discovery support" OFF)
option(ENABLE_TOPIC_DISCOVERY "Enable Topic Discovery support" OFF)
if(ENABLE_TOPIC_DISCOVERY)
diff --git a/src/core/ddsc/include/dds/ddsc/dds_public_impl.h b/src/core/ddsc/include/dds/ddsc/dds_public_impl.h
index ea0e7055..291e5d9c 100644
--- a/src/core/ddsc/include/dds/ddsc/dds_public_impl.h
+++ b/src/core/ddsc/include/dds/ddsc/dds_public_impl.h
@@ -26,6 +26,9 @@
#include
#include "dds/export.h"
#include "dds/features.h"
+#ifdef DDSRT_WITH_FREERTOSTCP
+#include "dds/ddsrt/align.h"
+#endif
#include "dds/ddsc/dds_public_alloc.h"
#include "dds/ddsc/dds_opcodes.h"
diff --git a/src/core/ddsc/include/dds/export.h b/src/core/ddsc/include/dds/export.h
new file mode 100755
index 00000000..30103d12
--- /dev/null
+++ b/src/core/ddsc/include/dds/export.h
@@ -0,0 +1,50 @@
+
+#ifndef DDS_EXPORT_H
+#define DDS_EXPORT_H
+
+#ifdef DDS_STATIC_DEFINE
+# define DDS_EXPORT
+# define DDS_NO_EXPORT
+#else
+# ifndef DDS_EXPORT
+# ifdef ddsc_EXPORTS
+ /* We are building this library */
+# define DDS_EXPORT
+# else
+ /* We are using this library */
+# define DDS_EXPORT
+# endif
+# endif
+
+# ifndef DDS_NO_EXPORT
+# define DDS_NO_EXPORT
+# endif
+#endif
+
+#ifndef DDS_DEPRECATED
+# define DDS_DEPRECATED
+#endif
+
+#ifndef DDS_DEPRECATED_EXPORT
+# define DDS_DEPRECATED_EXPORT DDS_EXPORT DDS_DEPRECATED
+#endif
+
+#ifndef DDS_DEPRECATED_NO_EXPORT
+# define DDS_DEPRECATED_NO_EXPORT DDS_NO_EXPORT DDS_DEPRECATED
+#endif
+
+#if 0 /* DEFINE_NO_DEPRECATED */
+# ifndef DDS_NO_DEPRECATED
+# define DDS_NO_DEPRECATED
+# endif
+#endif
+
+#ifndef DDS_INLINE_EXPORT
+# if __MINGW32__ && (!defined(__clang__) || !defined(ddsc_EXPORTS))
+# define DDS_INLINE_EXPORT
+# else
+# define DDS_INLINE_EXPORT DDS_EXPORT
+# endif
+#endif
+
+#endif /* DDS_EXPORT_H */
diff --git a/src/core/ddsc/src/dds_builtin.c b/src/core/ddsc/src/dds_builtin.c
index fd2a31da..43f96adb 100644
--- a/src/core/ddsc/src/dds_builtin.c
+++ b/src/core/ddsc/src/dds_builtin.c
@@ -374,6 +374,8 @@ void dds__builtin_init (struct dds_domain *dom)
{
dds_qos_t *qos = dds__create_builtin_qos ();
+ DDS_LOG(DDS_LC_CONFIG, " dds__builtin_init ...");
+
dom->btif.arg = dom;
dom->btif.builtintopic_get_tkmap_entry = dds__builtin_get_tkmap_entry;
dom->btif.builtintopic_is_builtintopic = dds__builtin_is_builtintopic;
@@ -415,6 +417,8 @@ void dds__builtin_init (struct dds_domain *dom)
dom->builtintopic_writer_subscriptions = new_local_orphan_writer (&dom->gv, to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER), DDS_BUILTIN_TOPIC_SUBSCRIPTION_NAME, dom->builtin_reader_type, qos, builtintopic_whc_new (DSBT_READER, gh));
thread_state_asleep (lookup_thread_state ());
+ DDS_LOG(DDS_LC_CONFIG, " builtin_topics writer done");
+
dds_delete_qos (qos);
/* ddsi_sertype_init initializes the refcount to 1 and dds_sertopic_register_locked increments
diff --git a/src/core/ddsc/src/dds_domain.c b/src/core/ddsc/src/dds_domain.c
index dfb6b802..81afea50 100644
--- a/src/core/ddsc/src/dds_domain.c
+++ b/src/core/ddsc/src/dds_domain.c
@@ -120,6 +120,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
break;
}
domain->m_id = domain->gv.config.domainId;
+ DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " domain 0X%08x / 0x%08x config init done \n", domain->m_id, domain_id);
if (rtps_config_prep (&domain->gv, domain->cfgst) != 0)
{
@@ -127,6 +128,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
domh = DDS_RETCODE_ERROR;
goto fail_rtps_config;
}
+ DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " rtps_config_prep done \n");
if (rtps_init (&domain->gv) < 0)
{
@@ -134,6 +136,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
domh = DDS_RETCODE_ERROR;
goto fail_rtps_init;
}
+ DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " rtps_init done! \n");
#ifdef DDS_HAS_SHM
// if DDS_HAS_SHM is enabled the iceoryx runtime was created in rtps_init and is ready
@@ -151,6 +154,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
domain to configured to do so. */
if (domain->gv.config.liveliness_monitoring)
{
+ DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " liveliness monitor thread start ... \n");
if (dds_global.threadmon_count++ == 0)
{
/* FIXME: configure settings */
@@ -169,9 +173,11 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
goto fail_threadmon_start;
}
}
+ DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " liveliness monitor thread start! \n");
}
dds__builtin_init (domain);
+ DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " dds__builtin_init done! \n");
/* Set additional default participant properties */
@@ -187,10 +193,21 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
domh = DDS_RETCODE_ERROR;
goto fail_rtps_start;
}
+ DDS_LOG(DDS_LC_CONFIG, " rtps_start done!");
if (domain->gv.config.liveliness_monitoring)
ddsi_threadmon_register_domain (dds_global.threadmon, &domain->gv);
dds_entity_init_complete (&domain->m_entity);
+
+ #if 0 // def DDSRT_WITH_FREERTOSTCP
+ /* CAUTION: NEVER open this slice unless in UT itself. */
+ sleep(2U); /* wait thread wrapper */
+ DDS_LOG(DDS_LC_CONFIG, " @@@@@@@@@@@@@@@@@@ domain init threads dump");
+ /* dump all threads created in domain_init */
+ //eth_run_cli("ps");
+ sleep(1U);
+ #endif
+
return domh;
fail_rtps_start:
@@ -234,6 +251,8 @@ static dds_entity_t dds_domain_create_internal_xml_or_raw (dds_domain **domain_o
if (dom)
{
+ DDS_LOG (DDS_LC_CONFIG, " find dom %p", dom);
+
if (!implicit)
domh = DDS_RETCODE_PRECONDITION_NOT_MET;
else
@@ -254,18 +273,22 @@ static dds_entity_t dds_domain_create_internal_xml_or_raw (dds_domain **domain_o
}
else
{
+ DDS_LOG (DDS_LC_CONFIG, " create dom ...");
dom = dds_alloc (sizeof (*dom));
if ((domh = dds_domain_init (dom, id, config, implicit)) < 0)
- dds_free (dom);
+ { dds_free (dom); }
else
{
+ DDS_LOG (DDS_LC_CONFIG, " dom created, domh = 0x%x ", domh);
ddsrt_mutex_lock (&dom->m_entity.m_mutex);
ddsrt_avl_insert (&dds_domaintree_def, &dds_global.m_domains, dom);
dds_entity_register_child (&dds_global.m_entity, &dom->m_entity);
+ DDS_LOG (DDS_LC_CONFIG, " register domain to global done ");
if (implicit)
{
dds_entity_add_ref_locked (&dom->m_entity);
dds_handle_repin (&dom->m_entity.m_hdllink);
+ DDS_LOG (DDS_LC_CONFIG, " dom->m_entity.m_hdllink.hdl = 0x%x ", dom->m_entity.m_hdllink.hdl);
}
domh = dom->m_entity.m_hdllink.hdl;
ddsrt_mutex_unlock (&dom->m_entity.m_mutex);
diff --git a/src/core/ddsc/src/dds_init.c b/src/core/ddsc/src/dds_init.c
index e4252e02..4c9154cc 100644
--- a/src/core/ddsc/src/dds_init.c
+++ b/src/core/ddsc/src/dds_init.c
@@ -52,6 +52,10 @@ dds_cyclonedds_entity dds_global;
#define CDDS_STATE_STARTING 1u
#define CDDS_STATE_READY 2u
#define CDDS_STATE_STOPPING 3u
+
+#ifdef DDSRT_WITH_FREERTOSTCP
+#define MAX_THREAD_NUM 32
+#endif
static ddsrt_atomic_uint32_t dds_state = DDSRT_ATOMIC_UINT32_INIT (CDDS_STATE_ZERO);
static void common_cleanup (void)
@@ -112,7 +116,11 @@ dds_return_t dds_init (void)
ddsrt_mutex_init (&dds_global.m_mutex);
ddsrt_cond_init (&dds_global.m_cond);
ddsi_iid_init ();
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ thread_states_init (MAX_THREAD_NUM);
+ #else
thread_states_init (128);
+ #endif
if (dds_handle_server_init () != DDS_RETCODE_OK)
{
diff --git a/src/core/ddsc/src/dds_participant.c b/src/core/ddsc/src/dds_participant.c
index 9cba6a57..c9a977ad 100644
--- a/src/core/ddsc/src/dds_participant.c
+++ b/src/core/ddsc/src/dds_participant.c
@@ -91,6 +91,9 @@ const struct dds_entity_deriver dds_entity_deriver_participant = {
.refresh_statistics = dds_entity_deriver_dummy_refresh_statistics
};
+#ifdef DDSRT_WITH_FREERTOSTCP
+char dds_peer[16] = {0};
+#endif
dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_t *qos, const dds_listener_t *listener)
{
dds_domain *dom;
@@ -99,6 +102,29 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_
dds_participant * pp;
ddsi_plist_t plist;
dds_qos_t *new_qos = NULL;
+
+#ifdef DDSRT_WITH_FREERTOSTCP
+ /* Make sure DDS instance is initialized. */
+ if ((ret = dds_init ()) < 0)
+ goto err_dds_init;
+
+ char xml[1024];
+ memset(xml, 0, sizeof(xml));
+ if (inet_addr(dds_peer) == 0)
+ {
+ strncpy(dds_peer, "192.168.11.2", sizeof(dds_peer));
+ dds_peer[sizeof(dds_peer) - 1] = '\0';
+ }
+
+ snprintf(xml, sizeof(xml) - 1, "\
+\
+ \
+\
+", dds_peer);
+ const char *config = xml;
+ DDS_WARNING(" participant xml [%s] !", xml);
+ //DDS_WARNING(" participant peer using [%s] !", dds_peer);
+#else
const char *config = "";
/* Make sure DDS instance is initialized. */
@@ -106,6 +132,8 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_
goto err_dds_init;
(void) ddsrt_getenv ("CYCLONEDDS_URI", &config);
+#endif
+
if ((ret = dds_domain_create_internal (&dom, domain, true, config)) < 0)
goto err_domain_create;
@@ -143,6 +171,7 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_
ret = DDS_RETCODE_ERROR;
goto err_new_participant;
}
+ DDS_INFO(" built-in participant done !");
pp = dds_alloc (sizeof (*pp));
if ((ret = dds_entity_init (&pp->m_entity, &dom->m_entity, DDS_KIND_PARTICIPANT, false, true, new_qos, listener, DDS_PARTICIPANT_STATUS_MASK)) < 0)
@@ -160,6 +189,7 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_
ddsrt_mutex_unlock (&dom->m_entity.m_mutex);
dds_entity_init_complete (&pp->m_entity);
+
/* drop temporary extra ref to domain, dds_init */
dds_entity_unpin_and_drop_ref (&dom->m_entity);
dds_entity_unpin_and_drop_ref (&dds_global.m_entity);
diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c
index beae4e51..1f76f41d 100644
--- a/src/core/ddsi/defconfig.c
+++ b/src/core/ddsi/defconfig.c
@@ -14,7 +14,11 @@ void ddsi_config_init_default (struct ddsi_config *cfg)
cfg->externalMaskString = "0.0.0.0";
cfg->allowMulticast = UINT32_C (2147483648);
cfg->multicast_ttl = INT32_C (32);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ cfg->transport_selector = INT32_C (DDSI_TRANS_UDP);
+ #else
cfg->transport_selector = INT32_C (1);
+ #endif
cfg->enableMulticastLoopback = INT32_C (1);
cfg->max_msg_size = UINT32_C (14720);
cfg->max_rexmit_msg_size = UINT32_C (1456);
@@ -58,8 +62,13 @@ void ddsi_config_init_default (struct ddsi_config *cfg)
cfg->const_hb_intv_min = INT64_C (5000000);
cfg->const_hb_intv_sched_min = INT64_C (20000000);
cfg->const_hb_intv_sched_max = INT64_C (8000000000);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ cfg->max_queued_rexmit_bytes = UINT32_C (33554432); /* 524288->32M: > 4K framesize */
+ cfg->max_queued_rexmit_msgs = UINT32_C (18000); /* 200->20480: > 4K framesize / fragmen_size */
+ #else
cfg->max_queued_rexmit_bytes = UINT32_C (524288);
cfg->max_queued_rexmit_msgs = UINT32_C (200);
+ #endif
cfg->writer_linger_duration = INT64_C (1000000000);
cfg->socket_rcvbuf_size.min.isdefault = 1;
cfg->socket_rcvbuf_size.max.isdefault = 1;
diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h b/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h
index 5b5b3db8..d1e3e867 100644
--- a/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h
+++ b/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h
@@ -15,6 +15,10 @@
#include "dds/features.h"
+#ifdef DDSRT_WITH_FREERTOSTCP
+#warning " debug rtos tcp stack including "
+#include "dds/ddsrt/sockets/freertos_plus_tcp.h"
+#endif
static struct cfgelem network_interface_attributes[] = {
STRING("autodetermine", NULL, 1, "false",
@@ -156,7 +160,16 @@ static struct cfgelem general_cfgelems[] = {
"translated to an internal address by replacing the network portion of "
"the external address with the corresponding portion of the preferred "
"network interface address. This option is IPv4-only.
")),
- LIST("AllowMulticast", NULL, 1, "default",
+ LIST("AllowMulticast", NULL, 1,
+#ifdef DDSRT_WITH_FREERTOSTCP
+/*
+ * he "spdp" leaves multicast enabled for initial discovery only
+ * https://github.com/ros2/rmw_cyclonedds/issues/251
+ */
+ "spdp",
+#else
+ "default",
+#endif
MEMBER(allowMulticast),
FUNCTIONS(0, uf_allow_multicast, 0, pf_allow_multicast),
DESCRIPTION(
@@ -212,19 +225,34 @@ static struct cfgelem general_cfgelems[] = {
"packets, to bypass the local routing tables. This is generally useful "
"only when the routing tables cannot be trusted, which is highly "
"unusual.")),
- ENUM("UseIPv6", NULL, 1, "default",
+ ENUM("UseIPv6", NULL, 1,
+#ifdef DDSRT_WITH_FREERTOSTCP
+ "false",
+#else
+ "default",
+#endif
MEMBER(compat_use_ipv6),
FUNCTIONS(0, uf_boolean_default, 0, pf_nop),
DESCRIPTION("Deprecated (use Transport instead)
"),
VALUES("false","true","default")),
- ENUM("Transport", NULL, 1, "default",
+ ENUM("Transport", NULL, 1,
+#ifdef DDSRT_WITH_FREERTOSTCP
+ "udp",
+#else
+ "default",
+#endif
MEMBER(transport_selector),
FUNCTIONS(0, uf_transport_selector, 0, pf_transport_selector),
DESCRIPTION(
"This element allows selecting the transport to be used (udp, udp6, "
"tcp, tcp6, raweth)
"),
VALUES("default","udp","udp6","tcp","tcp6","raweth")),
- BOOL("EnableMulticastLoopback", NULL, 1, "true",
+ BOOL("EnableMulticastLoopback", NULL, 1,
+#ifdef DDSRT_WITH_FREERTOSTCP
+ "false",
+#else
+ "true",
+#endif
MEMBER(enableMulticastLoopback),
FUNCTIONS(0, uf_boolean, 0, pf_boolean),
DESCRIPTION(
@@ -234,7 +262,21 @@ static struct cfgelem general_cfgelems[] = {
"communications, but if a node runs only a single Cyclone DDS service "
"and does not host any other DDSI-capable programs, it should be set "
"to \"false\" for improved performance.")),
- STRING("MaxMessageSize", NULL, 1, "14720 B",
+
+ STRING("MaxMessageSize", NULL, 1,
+#ifdef DDSRT_WITH_FREERTOSTCP
+/* ddsi_config.max_msg_size and fragment_size will decide how many fragments in single submsg.
+ * keep this below MTU if STACK not support IP fragments
+ */
+ #ifdef EQOS_TX_JUMBO_ENABLED
+ "8972 B",
+ #else
+ "1456 B",
+ #endif
+
+#else
+ "14720 B",
+#endif
MEMBER(max_msg_size),
FUNCTIONS(0, uf_memsize, 0, pf_memsize),
DESCRIPTION(
@@ -246,7 +288,16 @@ static struct cfgelem general_cfgelems[] = {
"On some networks it may be necessary to set this item to keep the "
"packetsize below the MTU to prevent IP fragmentation.
"),
UNIT("memsize")),
- STRING("MaxRexmitMessageSize", NULL, 1, "1456 B",
+ STRING("MaxRexmitMessageSize", NULL, 1,
+#ifdef DDSRT_WITH_FREERTOSTCP
+ #ifdef EQOS_TX_JUMBO_ENABLED
+ "8972 B",
+ #else
+ "1464 B",
+ #endif
+#else
+ "1456 B",
+#endif
MEMBER(max_rexmit_msg_size),
FUNCTIONS(0, uf_memsize, 0, pf_memsize),
DESCRIPTION(
@@ -258,7 +309,17 @@ static struct cfgelem general_cfgelems[] = {
"On some networks it may be necessary to set this item to keep the "
"packetsize below the MTU to prevent IP fragmentation.
"),
UNIT("memsize")),
- STRING("FragmentSize", NULL, 1, "1344 B",
+ STRING("FragmentSize", NULL, 1,
+#ifdef DDSRT_WITH_FREERTOSTCP
+ #ifdef EQOS_TX_JUMBO_ENABLED
+ /* ipMAX_UDP_PAYLOAD_LENGTH(8972) > $FragSize + 20(RTPS_HDR) + 12(INFO_TS) + 36(DATA_HDR) + 28(HEART_BEAT) */
+ "8864 B",
+ #else
+ "1400 B",
+ #endif
+#else
+ "1344 B",
+#endif
MEMBER(fragment_size),
FUNCTIONS(0, uf_memsize16, 0, pf_memsize16),
DESCRIPTION(
@@ -938,7 +999,15 @@ static struct cfgelem internal_watermarks_cfgelems[] = {
"expressed in bytes. A suspended writer resumes transmitting when its "
"Cyclone DDS WHC shrinks to this size."),
UNIT("memsize")),
- STRING("WhcHigh", NULL, 1, "500 kB",
+ STRING("WhcHigh", NULL, 1,
+#ifdef DDSRT_WITH_FREERTOSTCP
+ /* 512K->24M: > 4K RGB888 framesize
+ * ALSO to be sure seqeunce limitation defined in idl
+ */
+ "24576 kB",
+#else
+ "500 kB",
+#endif
MEMBER(whc_highwater_mark),
FUNCTIONS(0, uf_memsize, 0, pf_memsize),
DESCRIPTION(
@@ -1282,7 +1351,16 @@ static struct cfgelem internal_cfgelems[] = {
"This element allows configuring the base interval for sending "
"writer heartbeats and the bounds within which it can vary.
"),
UNIT("duration_inf")),
- STRING("MaxQueuedRexmitBytes", NULL, 1, "512 kB",
+
+ STRING("MaxQueuedRexmitBytes", NULL, 1,
+#ifdef DDSRT_WITH_FREERTOSTCP
+ /* 512K->24M: > 4K RGB888 framesize
+ * ALSO to be sure seqeunce limitation defined in idl
+ */
+ "24576 kB",
+#else
+ "512 kB",
+#endif
MEMBER(max_queued_rexmit_bytes),
FUNCTIONS(0, uf_memsize, 0, pf_memsize),
DESCRIPTION(
@@ -1292,7 +1370,14 @@ static struct cfgelem internal_cfgelems[] = {
"NackDelay * AuxiliaryBandwidthLimit. It must be large enough to "
"contain the largest sample that may need to be retransmitted."),
UNIT("memsize")),
- INT("MaxQueuedRexmitMessages", NULL, 1, "200",
+
+ INT("MaxQueuedRexmitMessages", NULL, 1,
+#ifdef DDSRT_WITH_FREERTOSTCP
+ /* 200->20480: > 4K framesize / fragmen_size */
+ "20480",
+#else
+ "200",
+#endif
MEMBER(max_queued_rexmit_msgs),
FUNCTIONS(0, uf_uint, 0, pf_uint),
DESCRIPTION(
@@ -1804,7 +1889,11 @@ static struct cfgelem shmem_cfgelems[] = {
#endif
static struct cfgelem discovery_peer_cfgattrs[] = {
+#ifdef DDSRT_WITH_FREERTOSTCP
+ STRING("Address", NULL, 1, "192.168.11.3:7400", // Not working, use XML string
+#else
STRING("Address", NULL, 1, NULL,
+#endif
MEMBEROF(ddsi_config_peer_listelem, peer),
FUNCTIONS(0, uf_ipv4, ff_free, pf_string),
DESCRIPTION(
@@ -1829,6 +1918,16 @@ static struct cfgelem discovery_peers_group_cfgelems[] = {
};
static struct cfgelem discovery_peers_cfgelems[] = {
+#ifdef DDSRT_WITH_FREERTOSTCP
+ GROUP("Peer", NULL, discovery_peer_cfgattrs, INT_MAX, // Not working, use XML string
+ MEMBER(peers),
+ FUNCTIONS(if_peer, 0, 0, 0),
+ DESCRIPTION(
+ "This element specifies the base port number (refer to the DDSI 2.1 "
+ "specification, section 9.6.1, constant PB).
"
+ )),
+
+#else
GROUP("Peer", NULL, discovery_peer_cfgattrs, INT_MAX,
MEMBER(peers),
FUNCTIONS(if_peer, 0, 0, 0),
@@ -1845,6 +1944,7 @@ static struct cfgelem discovery_peers_cfgelems[] = {
),
MAXIMUM(0)), /* Group element can occur more than once, but 1 is required
because of the way its processed (for now) */
+#endif
END_MARKER
};
@@ -1900,7 +2000,12 @@ static struct cfgelem discovery_cfgelems[] = {
"and fixing the participant index has no adverse effects, it is "
"recommended that the second be option be used."
)),
+#ifdef DDSRT_WITH_FREERTOSTCP
+ /* polling port number to dest peer */
+ INT("MaxAutoParticipantIndex", NULL, 1, "2", /* 9 */
+#else
INT("MaxAutoParticipantIndex", NULL, 1, "9",
+#endif
MEMBER(maxAutoParticipantIndex),
FUNCTIONS(0, uf_natint, 0, pf_int),
DESCRIPTION(
diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_config.h b/src/core/ddsi/include/dds/ddsi/ddsi_config.h
index 6862e1cc..4036b50a 100644
--- a/src/core/ddsi/include/dds/ddsi/ddsi_config.h
+++ b/src/core/ddsi/include/dds/ddsi/ddsi_config.h
@@ -310,8 +310,8 @@ struct ddsi_config
unsigned delivery_queue_maxsamples;
- uint16_t fragment_size;
- uint32_t max_msg_size;
+ uint16_t fragment_size; // default: 1344
+ uint32_t max_msg_size; /* default: 14720 how many fragment in single submsg */
uint32_t max_rexmit_msg_size;
uint32_t init_transmit_extra_pct;
uint32_t max_rexmit_burst_size;
diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_locator.h b/src/core/ddsi/include/dds/ddsi/ddsi_locator.h
index 0d6d2631..584a06da 100644
--- a/src/core/ddsi/include/dds/ddsi/ddsi_locator.h
+++ b/src/core/ddsi/include/dds/ddsi/ddsi_locator.h
@@ -23,7 +23,7 @@ struct ddsi_tran_conn;
/* address field in locator maintained in network byte order, the rest in host */
typedef struct {
- int32_t kind;
+ int32_t kind; // NN_LOCATOR_KIND_UDPv4
uint32_t port;
unsigned char address[16];
} ddsi_locator_t;
diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h b/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h
index b12de943..3cf62747 100644
--- a/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h
+++ b/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h
@@ -98,6 +98,24 @@ struct ddsi_serdata_default_unpadded {
#define DDSI_SERDATA_DEFAULT_PAD(n) (n)
#endif
+
+#if 0
+/* un-fold to easy to track in SI */
+struct ddsi_serdata_default {
+ struct ddsi_serdata c;
+ uint32_t pos;
+ uint32_t size;
+ DDSI_SERDATA_DEFAULT_DEBUG_FIELDS
+ struct ddsi_serdata_default_key key;
+ struct serdatapool *serpool;
+ struct ddsi_serdata_default *next; /* in pool->freelist */
+ char pad[DDSI_SERDATA_DEFAULT_PAD (8 - (offsetof (struct ddsi_serdata_default_unpadded, data) % 8))];
+ struct CDRHeader hdr;
+ char data[];
+};
+#endif
+
+
struct ddsi_serdata_default {
DDSI_SERDATA_DEFAULT_PREPAD;
char pad[DDSI_SERDATA_DEFAULT_PAD (8 - (offsetof (struct ddsi_serdata_default_unpadded, data) % 8))];
diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_udp.h b/src/core/ddsi/include/dds/ddsi/ddsi_udp.h
index 2d36180e..14ea1252 100644
--- a/src/core/ddsi/include/dds/ddsi/ddsi_udp.h
+++ b/src/core/ddsi/include/dds/ddsi/ddsi_udp.h
@@ -18,7 +18,11 @@ extern "C" {
typedef struct nn_udpv4mcgen_address {
/* base IPv4 MC address is ipv4, host bits are bits base .. base+count-1, this machine is bit idx */
+#ifdef DDSRT_WITH_FREERTOSTCP
+ in_addr_t ipv4;
+#else
struct in_addr ipv4;
+#endif
uint8_t base;
uint8_t count;
uint8_t idx; /* must be last: then sorting will put them consecutively */
diff --git a/src/core/ddsi/include/dds/ddsi/q_log.h b/src/core/ddsi/include/dds/ddsi/q_log.h
index 64d3c0f8..cbb9fb03 100644
--- a/src/core/ddsi/include/dds/ddsi/q_log.h
+++ b/src/core/ddsi/include/dds/ddsi/q_log.h
@@ -24,6 +24,9 @@ extern "C" {
#define GVTRACE(...) DDS_CTRACE (&gv->logconfig, __VA_ARGS__)
#define GVLOG(cat, ...) DDS_CLOG ((cat), &gv->logconfig, __VA_ARGS__)
+#ifdef DDSRT_WITH_FREERTOSTCP
+#define GVINFO(...) DDS_CLOG (DDS_LC_INFO, &gv->logconfig, __VA_ARGS__)
+#endif
#define GVWARNING(...) DDS_CLOG (DDS_LC_WARNING, &gv->logconfig, __VA_ARGS__)
#define GVERROR(...) DDS_CLOG (DDS_LC_ERROR, &gv->logconfig, __VA_ARGS__)
diff --git a/src/core/ddsi/include/dds/ddsi/q_thread.h b/src/core/ddsi/include/dds/ddsi/q_thread.h
index 5d84c11d..fd382ea9 100644
--- a/src/core/ddsi/include/dds/ddsi/q_thread.h
+++ b/src/core/ddsi/include/dds/ddsi/q_thread.h
@@ -132,7 +132,11 @@ DDS_EXPORT dds_return_t join_thread (struct thread_state1 *ts1);
DDS_EXPORT void log_stack_traces (const struct ddsrt_log_cfg *logcfg, const struct ddsi_domaingv *gv);
DDS_INLINE_EXPORT inline struct thread_state1 *lookup_thread_state (void) {
+#ifdef DDSRT_WITH_FREERTOSTCP
+ struct thread_state1 *ts1 = (struct thread_state1 *)ddsrt_thread_tls_get(DDS_TLS_IDX_STATE, tsd_thread_state);
+#else
struct thread_state1 *ts1 = tsd_thread_state;
+#endif
if (ts1)
return ts1;
else
diff --git a/src/core/ddsi/src/ddsi_cdrstream.c b/src/core/ddsi/src/ddsi_cdrstream.c
index 084a627b..5e485c49 100644
--- a/src/core/ddsi/src/ddsi_cdrstream.c
+++ b/src/core/ddsi/src/ddsi_cdrstream.c
@@ -861,12 +861,12 @@ static char *dds_stream_reuse_string_bound (dds_istream_t * __restrict is, char
so this check is superfluous, but perhaps rejecting such a sample is the
wrong thing to do */
if (!alloc)
- assert (str != NULL);
+ { assert (str != NULL); }
else if (str == NULL)
- str = dds_alloc (size);
+ { str = dds_alloc (size); }
memcpy (str, src, length > size ? size : length);
if (length > size)
- str[size - 1] = '\0';
+ { str[size - 1] = '\0'; }
is->m_index += length;
return str;
}
@@ -3821,7 +3821,11 @@ static bool prtf_simple (char * __restrict *buf, size_t * __restrict bufsize, dd
case DDS_OP_VAL_4BY: {
const union { int32_t s; uint32_t u; float f; } x = { .u = dds_is_get4 (is) };
if (flags & DDS_OP_FLAG_FP)
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ return prtf (buf, bufsize, "%f", x.f);
+ #else
return prtf (buf, bufsize, "%g", x.f);
+ #endif
else if (flags & DDS_OP_FLAG_SGN)
return prtf (buf, bufsize, "%"PRId32, x.s);
else
@@ -3830,7 +3834,11 @@ static bool prtf_simple (char * __restrict *buf, size_t * __restrict bufsize, dd
case DDS_OP_VAL_8BY: {
const union { int64_t s; uint64_t u; double f; } x = { .u = dds_is_get8 (is) };
if (flags & DDS_OP_FLAG_FP)
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ return prtf (buf, bufsize, "%f", x.f);
+ #else
return prtf (buf, bufsize, "%g", x.f);
+ #endif
else if (flags & DDS_OP_FLAG_SGN)
return prtf (buf, bufsize, "%"PRId64, x.s);
else
diff --git a/src/core/ddsi/src/ddsi_ipaddr.c b/src/core/ddsi/src/ddsi_ipaddr.c
index 5d286ff3..eb086360 100644
--- a/src/core/ddsi/src/ddsi_ipaddr.c
+++ b/src/core/ddsi/src/ddsi_ipaddr.c
@@ -251,7 +251,11 @@ void ddsi_ipaddr_to_loc (ddsi_locator_t *dst, const struct sockaddr *src, int32_
{
const struct sockaddr_in *x = (const struct sockaddr_in *) src;
assert (kind == NN_LOCATOR_KIND_UDPv4 || kind == NN_LOCATOR_KIND_TCPv4);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ if (x->sin_addr == htonl (INADDR_ANY))
+ #else
if (x->sin_addr.s_addr == htonl (INADDR_ANY))
+ #endif
{
dst->kind = NN_LOCATOR_KIND_INVALID;
dst->port = NN_LOCATOR_PORT_INVALID;
@@ -261,7 +265,11 @@ void ddsi_ipaddr_to_loc (ddsi_locator_t *dst, const struct sockaddr *src, int32_
{
dst->port = (x->sin_port == 0) ? NN_LOCATOR_PORT_INVALID : ntohs (x->sin_port);
memset (dst->address, 0, 12);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ memcpy (dst->address + 12, &x->sin_addr, 4);
+ #else
memcpy (dst->address + 12, &x->sin_addr.s_addr, 4);
+ #endif
}
break;
}
@@ -310,7 +318,11 @@ void ddsi_ipaddr_from_loc (struct sockaddr_storage *dst, const ddsi_locator_t *s
struct sockaddr_in *x = (struct sockaddr_in *) dst;
x->sin_family = AF_INET;
x->sin_port = (src->port == NN_LOCATOR_PORT_INVALID) ? 0 : htons ((unsigned short) src->port);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ memcpy (&x->sin_addr, src->address + 12, 4);
+ #else
memcpy (&x->sin_addr.s_addr, src->address + 12, 4);
+ #endif
break;
}
#if DDSRT_HAVE_IPV6
diff --git a/src/core/ddsi/src/ddsi_ownip.c b/src/core/ddsi/src/ddsi_ownip.c
index 6e06a8fe..bbf8e97d 100644
--- a/src/core/ddsi/src/ddsi_ownip.c
+++ b/src/core/ddsi/src/ddsi_ownip.c
@@ -273,7 +273,11 @@ static bool gather_interfaces (struct ddsi_domaingv * const gv, size_t *n_interf
ddsrt_freeifaddrs (ifa_root);
assert ((*n_interfaces > 0) == (*maxq_count > 0));
if (*n_interfaces == 0)
+ {
GVERROR ("failed to find interfaces for \"%s\"\n", gv->m_factory->m_typename);
+ ddsrt_free (*maxq_list);
+ ddsrt_free (*interfaces);
+ }
return (*n_interfaces > 0);
}
diff --git a/src/core/ddsi/src/ddsi_plist.c b/src/core/ddsi/src/ddsi_plist.c
index 9cabeafc..8dbff081 100644
--- a/src/core/ddsi/src/ddsi_plist.c
+++ b/src/core/ddsi/src/ddsi_plist.c
@@ -730,7 +730,7 @@ static dds_return_t ser_type_information (struct nn_xmsg *xmsg, nn_parameterid_t
static dds_return_t valid_type_information (const void *src, size_t srcoff)
{
ddsi_typeinfo_t const * const * x = deser_generic_src (src, &srcoff, alignof (ddsi_typeinfo_t *));
- return *x != NULL && ddsi_typeinfo_valid (*x);
+ return (*x != NULL && ddsi_typeinfo_valid (*x)) ? DDS_RETCODE_OK : DDS_RETCODE_BAD_PARAMETER;
}
static bool equal_type_information (const void *srcx, const void *srcy, size_t srcoff)
diff --git a/src/core/ddsi/src/ddsi_security_omg.c b/src/core/ddsi/src/ddsi_security_omg.c
index 717e81e4..48028abd 100644
--- a/src/core/ddsi/src/ddsi_security_omg.c
+++ b/src/core/ddsi/src/ddsi_security_omg.c
@@ -1259,9 +1259,7 @@ static void cleanup_participant_sec_attributes(void *arg)
if (!sc->crypto_context->crypto_key_factory->unregister_participant(sc->crypto_context->crypto_key_factory, attr->crypto_handle, &exception))
EXCEPTION_ERROR(gv, &exception, "Failed to unregister participant");
- ddsrt_avl_cfree(&pp_proxypp_treedef, &attr->proxy_participants, NULL);
- ddsrt_mutex_unlock(&attr->lock);
- ddsrt_free(attr);
+ participant_sec_attributes_free(attr);
ddsrt_free(arg);
}
diff --git a/src/core/ddsi/src/ddsi_tcp.c b/src/core/ddsi/src/ddsi_tcp.c
index eca7e147..cb8328de 100644
--- a/src/core/ddsi/src/ddsi_tcp.c
+++ b/src/core/ddsi/src/ddsi_tcp.c
@@ -188,7 +188,11 @@ static dds_return_t ddsi_tcp_sock_new (struct ddsi_tran_factory_tcp * const fact
{
case NN_LOCATOR_KIND_TCPv4:
socketname.a4.sin_family = AF_INET;
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ socketname.a4.sin_addr = htonl (INADDR_ANY);
+ #else
socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY);
+ #endif
socketname.a4.sin_port = htons (port);
break;
#if DDSRT_HAVE_IPV6
@@ -459,8 +463,13 @@ static bool ddsi_tcp_select (struct ddsi_domaingv const * const gv, ddsrt_socket
static int32_t addrfam_to_locator_kind (int af)
{
+#if DDSRT_HAVE_IPV6
assert (af == AF_INET || af == AF_INET6);
return (af == AF_INET) ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6;
+#else
+ assert (af == AF_INET);
+ return (af == AF_INET) ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_INVALID;
+#endif
}
static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char *buf, size_t len, bool allow_spurious, ddsi_locator_t *srcloc)
@@ -805,6 +814,10 @@ static dds_return_t ddsi_tcp_create_conn (ddsi_tran_conn_t *conn_out, struct dds
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) fact_cmn;
(void) qos;
(void) port;
+ struct ddsi_domaingv const * const gv = fact->fact.gv;
+ struct nn_interface const * const intf = qos->m_interface ? qos->m_interface : &gv->interfaces[0];
+
+ fact->ddsi_tcp_conn_client.m_base.m_interf = intf;
*conn_out = &fact->ddsi_tcp_conn_client.m_base;
return DDS_RETCODE_OK;
}
@@ -1068,8 +1081,13 @@ static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener)
switch (addr.a.sa_family)
{
case AF_INET:
- if (addr.a4.sin_addr.s_addr == htonl (INADDR_ANY))
- addr.a4.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ if (addr.a4.sin_addr == htonl (INADDR_ANY))
+ { addr.a4.sin_addr = htonl (INADDR_LOOPBACK); }
+ #else
+ if (addr.a4.sin_addr.s_addr == htonl (INADDR_ANY))
+ { addr.a4.sin_addr.s_addr = htonl (INADDR_LOOPBACK); }
+ #endif
break;
#if DDSRT_HAVE_IPV6
case AF_INET6:
diff --git a/src/core/ddsi/src/ddsi_tran.c b/src/core/ddsi/src/ddsi_tran.c
index be1ed3d7..6f5411bd 100644
--- a/src/core/ddsi/src/ddsi_tran.c
+++ b/src/core/ddsi/src/ddsi_tran.c
@@ -134,7 +134,9 @@ void ddsi_conn_free (ddsi_tran_conn_t conn)
for (uint32_t i = 0; i < conn->m_base.gv->n_recv_threads; i++)
{
if (!conn->m_base.gv->recv_threads[i].ts)
+ {
assert (!ddsrt_atomic_ld32 (&conn->m_base.gv->rtps_keepgoing));
+ }
else
{
switch (conn->m_base.gv->recv_threads[i].arg.mode)
diff --git a/src/core/ddsi/src/ddsi_typelib.c b/src/core/ddsi/src/ddsi_typelib.c
index ee799c7d..b3c84103 100644
--- a/src/core/ddsi/src/ddsi_typelib.c
+++ b/src/core/ddsi/src/ddsi_typelib.c
@@ -134,7 +134,7 @@ const ddsi_typeid_t *ddsi_typeinfo_complete_typeid (const ddsi_typeinfo_t *typei
return (const ddsi_typeid_t *) &typeinfo->x.complete.typeid_with_size.type_id;
}
-static bool typeinfo_dependent_typeids_valid (const struct DDS_XTypes_TypeIdentifierWithDependencies *t)
+static bool typeinfo_dependent_typeids_valid (const struct DDS_XTypes_TypeIdentifierWithDependencies *t, ddsi_typeid_kind_t kind)
{
if (t->dependent_typeid_count == -1)
{
@@ -149,8 +149,9 @@ static bool typeinfo_dependent_typeids_valid (const struct DDS_XTypes_TypeIdenti
return false;
for (uint32_t n = 0; n < t->dependent_typeids._length; n++)
{
- if (!ddsi_typeid_is_minimal_impl (&t->dependent_typeids._buffer[n].type_id) ||
- t->dependent_typeids._buffer[n].typeobject_serialized_size == 0)
+ if ((kind == DDSI_TYPEID_KIND_MINIMAL && !ddsi_typeid_is_minimal_impl (&t->dependent_typeids._buffer[n].type_id))
+ || (kind == DDSI_TYPEID_KIND_COMPLETE && !ddsi_typeid_is_complete_impl (&t->dependent_typeids._buffer[n].type_id))
+ || t->dependent_typeids._buffer[n].typeobject_serialized_size == 0)
return false;
}
}
@@ -164,8 +165,8 @@ bool ddsi_typeinfo_valid (const ddsi_typeinfo_t *typeinfo)
if (ddsi_typeid_is_none (tid_min) || !ddsi_typeid_is_hash (tid_min) ||
ddsi_typeid_is_none (tid_compl) || !ddsi_typeid_is_hash (tid_compl))
return false;
- if (!typeinfo_dependent_typeids_valid (&typeinfo->x.minimal) ||
- !typeinfo_dependent_typeids_valid (&typeinfo->x.complete))
+ if (!typeinfo_dependent_typeids_valid (&typeinfo->x.minimal, DDSI_TYPEID_KIND_MINIMAL) ||
+ !typeinfo_dependent_typeids_valid (&typeinfo->x.complete, DDSI_TYPEID_KIND_COMPLETE))
return false;
return true;
}
@@ -323,18 +324,6 @@ static struct ddsi_type * ddsi_type_new (struct ddsi_domaingv *gv, const struct
return type;
}
-static bool type_has_dep (const struct ddsi_type *type, const struct DDS_XTypes_TypeIdentifier *dep_type_id)
-{
- struct ddsi_type_dep *dep = type->deps;
- while (dep)
- {
- if (!ddsi_typeid_compare_impl (&dep->type->xt.id.x, dep_type_id))
- return true;
- dep = dep->prev;
- }
- return false;
-}
-
static void type_add_dep (struct ddsi_domaingv *gv, struct ddsi_type *type, const struct DDS_XTypes_TypeIdentifier *dep_type_id, const struct DDS_XTypes_TypeObject *dep_type_obj, uint32_t *n_match_upd, struct generic_proxy_endpoint ***gpe_match_upd)
{
struct ddsi_typeid_str tistr, tistrdep;
@@ -376,11 +365,22 @@ static void type_add_deps (struct ddsi_domaingv *gv, struct ddsi_type *type, con
for (uint32_t n = 0; dep_ids && n < dep_ids->_length; n++)
{
const struct DDS_XTypes_TypeIdentifier *dep_type_id = &dep_ids->_buffer[n].type_id;
- if (ddsi_typeid_compare_impl (&type->xt.id.x, dep_type_id) && !type_has_dep (type, dep_type_id))
+ if (!ddsi_typeid_compare_impl (&type->xt.id.x, dep_type_id))
+ continue;
+ const struct DDS_XTypes_TypeObject *dep_type_obj = type_map ? ddsi_typemap_typeobj (type_map, dep_type_id) : NULL;
+ struct ddsi_type_dep *dep = type->deps;
+ while (dep)
{
- const struct DDS_XTypes_TypeObject *dep_type_obj = type_map ? ddsi_typemap_typeobj (type_map, dep_type_id) : NULL;
- type_add_dep (gv, type, dep_type_id, dep_type_obj, n_match_upd, gpe_match_upd);
+ if (!ddsi_typeid_compare_impl (&dep->type->xt.id.x, dep_type_id) && dep_type_obj != NULL && ddsi_xt_type_add_typeobj (gv, &dep->type->xt, dep_type_obj) == DDS_RETCODE_OK)
+ {
+ dep->type->state = DDSI_TYPE_RESOLVED;
+ (void) ddsi_type_get_gpe_matches (gv, dep->type, gpe_match_upd, n_match_upd);
+ break;
+ }
+ dep = dep->prev;
}
+ if (!dep)
+ type_add_dep (gv, type, dep_type_id, dep_type_obj, n_match_upd, gpe_match_upd);
}
}
}
@@ -648,6 +648,7 @@ uint32_t ddsi_type_get_gpe_matches (struct ddsi_domaingv *gv, const struct ddsi_
return 0;
uint32_t n = 0;
+ thread_state_awake (lookup_thread_state (), gv);
*gpe_match_upd = ddsrt_realloc (*gpe_match_upd, (*n_match_upd + ddsi_type_proxy_guid_list_count (&type->proxy_guids)) * sizeof (**gpe_match_upd));
struct ddsi_type_proxy_guid_list_iter it;
for (ddsi_guid_t guid = ddsi_type_proxy_guid_list_iter_first (&type->proxy_guids, &it); !is_null_guid (&guid); guid = ddsi_type_proxy_guid_list_iter_next (&it))
@@ -664,6 +665,7 @@ uint32_t ddsi_type_get_gpe_matches (struct ddsi_domaingv *gv, const struct ddsi_
}
*n_match_upd += n;
ddsi_type_register_with_proxy_endpoints_locked (gv, type);
+ thread_state_asleep (lookup_thread_state ());
return n;
}
diff --git a/src/core/ddsi/src/ddsi_typelookup.c b/src/core/ddsi/src/ddsi_typelookup.c
index 161d0b94..2210dcc5 100644
--- a/src/core/ddsi/src/ddsi_typelookup.c
+++ b/src/core/ddsi/src/ddsi_typelookup.c
@@ -172,6 +172,13 @@ void ddsi_tl_handle_request (struct ddsi_domaingv *gv, struct ddsi_serdata *d)
DDS_Builtin_TypeLookup_Request req;
memset (&req, 0, sizeof (req));
ddsi_serdata_to_sample (d, &req, NULL, NULL);
+ if (req.data._d != DDS_Builtin_TypeLookup_getTypes_HashId)
+ {
+ GVTRACE (" handle-tl-req wr "PGUIDFMT " unknown req-type %"PRIi32, PGUID (from_guid (&req.header.requestId.writer_guid)), req.data._d);
+ ddsi_sertype_free_sample (d->type, &req, DDS_FREE_CONTENTS);
+ return;
+ }
+
GVTRACE (" handle-tl-req wr "PGUIDFMT " seqnr %"PRIu64" ntypeids %"PRIu32, PGUID (from_guid (&req.header.requestId.writer_guid)), from_seqno (&req.header.requestId.sequence_number), req.data._u.getTypes.type_ids._length);
ddsrt_mutex_lock (&gv->typelib_lock);
@@ -221,6 +228,13 @@ void ddsi_tl_handle_reply (struct ddsi_domaingv *gv, struct ddsi_serdata *d)
DDS_Builtin_TypeLookup_Reply reply;
memset (&reply, 0, sizeof (reply));
ddsi_serdata_to_sample (d, &reply, NULL, NULL);
+ if (reply.return_data._d != DDS_Builtin_TypeLookup_getTypes_HashId)
+ {
+ GVTRACE (" handle-tl-reply wr "PGUIDFMT " unknown reply-type %"PRIi32, PGUID (from_guid (&reply.header.requestId.writer_guid)), reply.return_data._d);
+ ddsi_sertype_free_sample (d->type, &reply, DDS_FREE_CONTENTS);
+ return;
+ }
+
bool resolved = false;
ddsrt_mutex_lock (&gv->typelib_lock);
GVTRACE ("handle-tl-reply wr "PGUIDFMT " seqnr %"PRIu64" ntypeids %"PRIu32"\n", PGUID (from_guid (&reply.header.requestId.writer_guid)), from_seqno (&reply.header.requestId.sequence_number), reply.return_data._u.getType._u.result.types._length);
diff --git a/src/core/ddsi/src/ddsi_typewrap.c b/src/core/ddsi/src/ddsi_typewrap.c
index 3b87bb63..21cc7521 100644
--- a/src/core/ddsi/src/ddsi_typewrap.c
+++ b/src/core/ddsi/src/ddsi_typewrap.c
@@ -420,7 +420,7 @@ static void xt_sbounds_to_lbounds (struct DDS_XTypes_LBoundSeq *lb, const struct
static void xt_lbounds_dup (struct DDS_XTypes_LBoundSeq *dst, const struct DDS_XTypes_LBoundSeq *src)
{
dst->_length = src->_length;
- dst->_buffer = ddsrt_memdup (&src->_buffer, dst->_length * sizeof (*dst->_buffer));
+ dst->_buffer = ddsrt_memdup (src->_buffer, dst->_length * sizeof (*dst->_buffer));
}
static void DDS_XTypes_AppliedBuiltinMemberAnnotations_copy (struct DDS_XTypes_AppliedBuiltinMemberAnnotations *dst, const struct DDS_XTypes_AppliedBuiltinMemberAnnotations *src);
diff --git a/src/core/ddsi/src/ddsi_udp.c b/src/core/ddsi/src/ddsi_udp.c
index 26c59e9e..2964bd5d 100644
--- a/src/core/ddsi/src/ddsi_udp.c
+++ b/src/core/ddsi/src/ddsi_udp.c
@@ -88,6 +88,19 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn_cmn, unsigned char * bu
msghdr.msg_controllen = 0;
#endif
+#ifdef DDSRT_WITH_FREERTOSTCP
+{
+ if (conn->m_base.m_base.m_port == 7410)
+ {
+ GVTRACE(" @@@@@@ waitset UDP RX on port %u ... ", conn->m_base.m_base.m_port);
+ }
+ if (conn->m_base.m_base.m_port == 7411)
+ {
+ GVTRACE(" @@@@@@ uc UDP RX on port %u ... ", conn->m_base.m_base.m_port);
+ }
+}
+#endif
+
do {
rc = ddsrt_recvmsg (conn->m_sock, &msghdr, 0, &ret);
} while (rc == DDS_RETCODE_INTERRUPTED);
@@ -95,7 +108,9 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn_cmn, unsigned char * bu
if (ret > 0)
{
if (srcloc)
- addr_to_loc (conn->m_base.m_factory, srcloc, &src);
+ {
+ addr_to_loc (conn->m_base.m_factory, srcloc, &src);
+ }
if (gv->pcap_fp)
{
@@ -153,6 +168,13 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn_cmn, const ddsi_locato
#if defined(__sun) && !defined(_XPG4_2)
msg.msg_accrights = NULL;
msg.msg_accrightslen = 0;
+#elif defined DDSRT_WITH_FREERTOSTCP /* got whole payload sz for trans */
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0U;
+ for (int ii = 0; ii < niov; ii++)
+ {
+ msg.msg_controllen += iov[ii].iov_len;
+ }
#else
msg.msg_control = NULL;
msg.msg_controllen = 0;
@@ -163,6 +185,7 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn_cmn, const ddsi_locato
DDSRT_UNUSED_ARG (flags);
#endif
#if MSG_NOSIGNAL && !LWIP_SOCKET
+#error
sendflags |= MSG_NOSIGNAL;
#endif
do {
@@ -266,7 +289,13 @@ static dds_return_t set_dont_route (struct ddsi_domaingv const * const gv, ddsrt
return rc;
}
+#ifdef DDSRT_WITH_FREERTOSTCP
+static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv,
+ ddsrt_socket_t sock, int32_t socket_option, const char *socket_option_name,
+ const char *name, const struct ddsi_config_socket_buf_size *config, uint32_t default_min_size)
+#else
static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, int32_t socket_option, const char *socket_option_name, const char *name, const struct ddsi_config_socket_buf_size *config, uint32_t default_min_size)
+#endif
{
// if (min, max)= and initbuf= then request= and result=
// (def, def) < defmin defmin whatever it is
@@ -275,9 +304,14 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd
// (M, N=M) anything N error if < M
// defmin = 1MB for receive buffer, 0B for send buffer
+
+#ifdef DDSRT_WITH_FREERTOSTCP
+ const bool always_set_size = true;
+#else
const bool always_set_size = // whether to call setsockopt unconditionally
((config->min.isdefault && !config->max.isdefault) ||
(!config->min.isdefault && !config->max.isdefault && config->max.value >= config->min.value));
+#endif
const uint32_t socket_min_buf_size = // error if it ends up below this
!config->min.isdefault ? config->min.value : 0;
const uint32_t socket_req_buf_size = // size to request
@@ -289,7 +323,13 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd
socklen_t optlen = (socklen_t) sizeof (actsize);
dds_return_t rc;
+#ifdef DDSRT_WITH_FREERTOSTCP
+#warning " *** FreeRTOS-Plus-TCP FreeRTOS_Plus_TCP runtime wrapper ..."
+ rc = DDS_RETCODE_OK;
+ actsize = socket_req_buf_size + 1U; /* stub getsockopt a different value */
+#else
rc = ddsrt_getsockopt (sock, SOL_SOCKET, socket_option, &actsize, &optlen);
+#endif
if (rc == DDS_RETCODE_BAD_PARAMETER)
{
/* not all stacks support getting/setting RCVBUF */
@@ -304,6 +344,13 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd
if (always_set_size || actsize < socket_req_buf_size)
{
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ rc = ddsrt_setsockopt (sock, SOL_SOCKET, socket_option, &socket_req_buf_size, sizeof (actsize));
+
+ #warning " *** FreeRTOS-Plus-TCP FreeRTOS_Plus_TCP runtime wrapper ..."
+ actsize = socket_req_buf_size;
+
+ #else
(void) ddsrt_setsockopt (sock, SOL_SOCKET, socket_option, &socket_req_buf_size, sizeof (actsize));
/* We don't check the return code from setsockopt, because some O/Ss tend
@@ -316,11 +363,15 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd
}
if (actsize >= socket_req_buf_size)
- GVLOG (DDS_LC_CONFIG, "socket %s buffer size set to %"PRIu32" bytes\n", name, actsize);
+ {
+ GVLOG (DDS_LC_CONFIG, "socket %s buffer size set to %"PRIu32" bytes\n", name, actsize);
+ }
else if (actsize >= socket_min_buf_size)
- GVLOG (DDS_LC_CONFIG,
+ {
+ GVLOG (DDS_LC_CONFIG,
"failed to increase socket %s buffer size to %"PRIu32" bytes, continuing with %"PRIu32" bytes\n",
name, socket_req_buf_size, actsize);
+ }
else
{
/* If the configuration states it must be >= X, then error out if the
@@ -330,9 +381,10 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd
name, socket_min_buf_size, actsize);
rc = DDS_RETCODE_NOT_ENOUGH_SPACE;
}
+ #endif
}
- return (rc < 0) ? rc : (actsize > (uint32_t) INT32_MAX) ? INT32_MAX : (int32_t) actsize;
+ return (rc < 0) ? rc : ((actsize > (uint32_t) INT32_MAX) ? INT32_MAX : (int32_t) actsize);
}
static dds_return_t set_rcvbuf (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, const struct ddsi_config_socket_buf_size *config)
@@ -374,6 +426,7 @@ static dds_return_t set_mc_options_transmit_ipv6 (struct ddsi_domaingv const * c
static dds_return_t set_mc_options_transmit_ipv4_if (struct ddsi_domaingv const * const gv, struct nn_interface const * const intf, ddsrt_socket_t sock)
{
+#ifndef DDSRT_WITH_FREERTOSTCP
#if (defined(__linux) || defined(__APPLE__)) && !LWIP_SOCKET
if (gv->config.use_multicast_if_mreqn)
{
@@ -390,6 +443,7 @@ static dds_return_t set_mc_options_transmit_ipv4_if (struct ddsi_domaingv const
}
#else
(void) gv;
+#endif
#endif
return ddsrt_setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, intf->loc.address + 12, 4);
}
@@ -466,7 +520,11 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_
{
case NN_LOCATOR_KIND_UDPv4:
if (bind_to_any)
- socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ { socketname.a4.sin_addr = htonl (INADDR_ANY); }
+ #else
+ { socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY); }
+ #endif
break;
#if DDSRT_HAVE_IPV6
case NN_LOCATOR_KIND_UDPv6:
@@ -509,11 +567,15 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_
break;
} while (!ddsrt_atomic_cas32 (&fact->receive_buf_size, old, (uint32_t) rc));
}
+ GVLOG (DDS_LC_CONFIG, " set_rcvbuf done\n");
if (set_sndbuf (gv, sock, &gv->config.socket_sndbuf_size) < 0)
goto fail_w_socket;
+ GVLOG (DDS_LC_CONFIG, " set_sndbuf done\n");
+
if (gv->config.dontRoute && set_dont_route (gv, sock, ipv6) != DDS_RETCODE_OK)
goto fail_w_socket;
+ GVLOG (DDS_LC_CONFIG, " set_dont_route done\n");
if ((rc = ddsrt_bind (sock, &socketname.a, ddsrt_sockaddr_get_size (&socketname.a))) != DDS_RETCODE_OK)
{
@@ -531,6 +593,7 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_
(rc == DDS_RETCODE_PRECONDITION_NOT_MET) ? "address in use" : dds_strretcode (rc));
goto fail_w_socket;
}
+ GVLOG (DDS_LC_CONFIG, " ddsrt_bind to port %u done \n", get_socket_port (gv, sock));
if (set_mc_xmit_options)
{
@@ -538,6 +601,7 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_
if (rc != DDS_RETCODE_OK)
goto fail_w_socket;
}
+ GVLOG (DDS_LC_CONFIG, " set_mc_options_transmit %d done\n", set_mc_xmit_options);
#ifdef DDS_HAS_NETWORK_CHANNELS
if (qos->m_diffserv != 0 && fact->m_kind == NN_LOCATOR_KIND_UDPv4)
@@ -571,7 +635,11 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_
conn->m_base.m_disable_multiplexing_fn = ddsi_udp_disable_multiplexing;
conn->m_base.m_locator_fn = ddsi_udp_conn_locator;
+#ifdef DDSRT_WITH_FREERTOSTCP
+ GVLOG (DDS_LC_CONFIG, "ddsi_udp_create_conn %s socket %"PRIdSOCK" port %"PRIu32"\n", purpose_str, conn->m_sock, conn->m_base.m_base.m_port);
+#else
GVTRACE ("ddsi_udp_create_conn %s socket %"PRIdSOCK" port %"PRIu32"\n", purpose_str, conn->m_sock, conn->m_base.m_base.m_port);
+#endif
*conn_out = &conn->m_base;
return DDS_RETCODE_OK;
@@ -605,9 +673,13 @@ static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const ddsi_lo
struct ip_mreq mreq;
mreq.imr_multiaddr = mcip.a4.sin_addr;
if (interf)
- memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface));
+ { memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface)); }
else
- mreq.imr_interface.s_addr = htonl (INADDR_ANY);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ { mreq.imr_interface = htonl (INADDR_ANY); }
+ #else
+ { mreq.imr_interface.s_addr = htonl (INADDR_ANY); }
+ #endif
rc = ddsrt_setsockopt (socket, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreq, sizeof (mreq));
}
return (rc == DDS_RETCODE_OK) ? 0 : -1;
@@ -714,15 +786,25 @@ static int ddsi_udp_is_mcaddr (const struct ddsi_tran_factory *tran, const ddsi_
switch (loc->kind)
{
case NN_LOCATOR_KIND_UDPv4: {
+#ifdef DDSRT_WITH_FREERTOSTCP
+ const in_addr_t *ipv4 = (const in_addr_t *) (loc->address + 12);
+ DDSRT_WARNING_GNUC_OFF(sign-conversion)
+ return IN_MULTICAST (ntohl (*ipv4));
+#else
const struct in_addr *ipv4 = (const struct in_addr *) (loc->address + 12);
DDSRT_WARNING_GNUC_OFF(sign-conversion)
return IN_MULTICAST (ntohl (ipv4->s_addr));
+#endif
DDSRT_WARNING_GNUC_ON(sign-conversion)
}
case NN_LOCATOR_KIND_UDPv4MCGEN: {
const nn_udpv4mcgen_address_t *mcgen = (const nn_udpv4mcgen_address_t *) loc->address;
DDSRT_WARNING_GNUC_OFF(sign-conversion)
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ return IN_MULTICAST (ntohl (mcgen->ipv4));
+ #else
return IN_MULTICAST (ntohl (mcgen->ipv4.s_addr));
+ #endif
DDSRT_WARNING_GNUC_ON(sign-conversion)
}
#if DDSRT_HAVE_IPV6
@@ -832,7 +914,11 @@ static char *ddsi_udp_locator_to_string (char *dst, size_t sizeof_dst, const dds
memcpy (&mcgen, loc->address, sizeof (mcgen));
memset (&src, 0, sizeof (src));
src.sin_family = AF_INET;
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ memcpy (&src.sin_addr, &mcgen.ipv4, 4);
+ #else
memcpy (&src.sin_addr.s_addr, &mcgen.ipv4, 4);
+ #endif
ddsrt_sockaddrtostr ((const struct sockaddr *) &src, dst, sizeof_dst);
pos = strlen (dst);
assert (pos <= sizeof_dst);
@@ -876,9 +962,11 @@ static int ddsi_udp_locator_from_sockaddr (const struct ddsi_tran_factory *tran_
if (tran->m_kind != NN_LOCATOR_KIND_UDPv4)
return -1;
break;
+#if DDSRT_HAVE_IPV6
case AF_INET6:
if (tran->m_kind != NN_LOCATOR_KIND_UDPv6)
return -1;
+#endif
break;
}
ddsi_ipaddr_to_loc (loc, sockaddr, tran->m_kind);
diff --git a/src/core/ddsi/src/ddsi_wraddrset.c b/src/core/ddsi/src/ddsi_wraddrset.c
index d3430d38..dcca2a15 100644
--- a/src/core/ddsi/src/ddsi_wraddrset.c
+++ b/src/core/ddsi/src/ddsi_wraddrset.c
@@ -691,7 +691,11 @@ static void wras_add_locator (const struct ddsi_domaingv *gv, struct addrset *ne
memcpy (&l1, tmploc.c.address, sizeof (l1));
tmploc.c.kind = NN_LOCATOR_KIND_UDPv4;
memset (tmploc.c.address, 0, 12);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ iph = ntohl (l1.ipv4);
+ #else
iph = ntohl (l1.ipv4.s_addr);
+ #endif
for (i = 0; i < nreaders; i++)
{
cover_info_t ci = cover_get (covered, i, locidx);
diff --git a/src/core/ddsi/src/q_addrset.c b/src/core/ddsi/src/q_addrset.c
index 25759c80..5e1095e1 100644
--- a/src/core/ddsi/src/q_addrset.c
+++ b/src/core/ddsi/src/q_addrset.c
@@ -96,6 +96,8 @@ int add_addresses_to_addrset (const struct ddsi_domaingv *gv, struct addrset *as
DDSRT_WARNING_MSVC_OFF(4996);
char *addrs_copy, *cursor, *a;
int retval = -1;
+
+ GVLOG (DDS_LC_CONFIG, " add addrs [%s] @@@@@@@@@@@@", addrs);
addrs_copy = ddsrt_strdup (addrs);
cursor = addrs_copy;
while ((a = ddsrt_strsep (&cursor, ",")) != NULL)
diff --git a/src/core/ddsi/src/q_ddsi_discovery.c b/src/core/ddsi/src/q_ddsi_discovery.c
index 2e60c34b..c293de6c 100644
--- a/src/core/ddsi/src/q_ddsi_discovery.c
+++ b/src/core/ddsi/src/q_ddsi_discovery.c
@@ -223,6 +223,20 @@ static struct addrset *addrset_from_locatorlists (const struct ddsi_domaingv *gv
external IP address, this locator will be translated into one
in the same subnet as our own local ip and selected. */
assert (gv->n_interfaces == 1); // gv->extmask: the hack is only supported if limited to a single interface
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ in_addr_t tmp4 = *((in_addr_t *) (loc.address + 12));
+ const in_addr_t ownip = *((in_addr_t *) (gv->interfaces[0].loc.address + 12));
+ const in_addr_t extip = *((in_addr_t *) (gv->interfaces[0].extloc.address + 12));
+ const in_addr_t extmask = *((in_addr_t *) (gv->extmask.address + 12));
+
+ if ((tmp4 & extmask) == (extip & extmask))
+ {
+ /* translate network part of the IP address from the external
+ one to the internal one */
+ tmp4 = (tmp4 & ~extmask) | (ownip & extmask);
+ memcpy (loc.address + 12, &tmp4, 4);
+ }
+ #else
struct in_addr tmp4 = *((struct in_addr *) (loc.address + 12));
const struct in_addr ownip = *((struct in_addr *) (gv->interfaces[0].loc.address + 12));
const struct in_addr extip = *((struct in_addr *) (gv->interfaces[0].extloc.address + 12));
@@ -235,6 +249,8 @@ static struct addrset *addrset_from_locatorlists (const struct ddsi_domaingv *gv
tmp4.s_addr = (tmp4.s_addr & ~extmask.s_addr) | (ownip.s_addr & extmask.s_addr);
memcpy (loc.address + 12, &tmp4, 4);
}
+ #endif
+
}
addrset_from_locatorlists_add_one (gv, &loc, as, &intfs, &direct);
diff --git a/src/core/ddsi/src/q_entity.c b/src/core/ddsi/src/q_entity.c
index 1ce7f8de..d934f86c 100644
--- a/src/core/ddsi/src/q_entity.c
+++ b/src/core/ddsi/src/q_entity.c
@@ -3329,6 +3329,7 @@ void update_proxy_endpoint_matching (const struct ddsi_domaingv *gv, struct gene
const char *tp = entity_topic_name (&proxy_ep->e);
ddsrt_mtime_t tnow = ddsrt_time_monotonic ();
+ thread_state_awake (lookup_thread_state (), gv);
entidx_enum_init_topic (&it, gv->entity_index, mkind, tp, &max);
while ((em = entidx_enum_next_max (&it, &max)) != NULL)
{
@@ -3336,6 +3337,7 @@ void update_proxy_endpoint_matching (const struct ddsi_domaingv *gv, struct gene
generic_do_match_connect (&proxy_ep->e, em, tnow, false);
}
entidx_enum_fini (&it);
+ thread_state_asleep (lookup_thread_state ());
}
@@ -3998,6 +4000,10 @@ static dds_return_t new_writer_guid (struct writer **wr_out, const struct ddsi_g
}
}
}
+ else
+ {
+ wr->lease = NULL;
+ }
return 0;
}
@@ -4340,7 +4346,11 @@ static void joinleave_mcast_helper (struct ddsi_domaingv *gv, ddsi_tran_conn_t c
memcpy (&l1, l.address, sizeof (l1));
l.kind = NN_LOCATOR_KIND_UDPv4;
memset (l.address, 0, 12);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ iph = ntohl (l1.ipv4);
+ #else
iph = ntohl (l1.ipv4.s_addr);
+ #endif
for (uint32_t i = 1; i < ((uint32_t)1 << l1.count); i++)
{
uint32_t ipn, iph1 = iph;
@@ -5981,9 +5991,9 @@ static int proxy_endpoint_common_init (struct entity_common *e, struct proxy_end
int ret;
if (is_builtin_entityid (guid->entityid, proxypp->vendor))
- assert ((plist->qos.present & QP_TYPE_NAME) == 0);
+ { assert ((plist->qos.present & QP_TYPE_NAME) == 0); }
else
- assert ((plist->qos.present & (QP_TOPIC_NAME | QP_TYPE_NAME)) == (QP_TOPIC_NAME | QP_TYPE_NAME));
+ { assert ((plist->qos.present & (QP_TOPIC_NAME | QP_TYPE_NAME)) == (QP_TOPIC_NAME | QP_TYPE_NAME)); }
name = (plist->present & PP_ENTITY_NAME) ? plist->entity_name : "";
entity_common_init (e, proxypp->e.gv, guid, name, kind, tcreate, proxypp->vendor, false);
diff --git a/src/core/ddsi/src/q_freelist.c b/src/core/ddsi/src/q_freelist.c
index 28ed6ea1..9ce76244 100644
--- a/src/core/ddsi/src/q_freelist.c
+++ b/src/core/ddsi/src/q_freelist.c
@@ -120,6 +120,11 @@ void nn_freelist_init (struct nn_freelist *fl, uint32_t max, size_t linkoff)
fl->count = 0;
fl->max = (max == UINT32_MAX) ? max-1 : max;
fl->linkoff = linkoff;
+
+#ifdef DDSRT_WITH_FREERTOSTCP
+ /* init TLS var */
+ ddsrt_thread_tls_set(freelist_inner_idx, DDS_TLS_IDX_FREE, (void*)(-1));
+#endif
}
static void *get_next (const struct nn_freelist *fl, const void *e)
@@ -160,6 +165,27 @@ void nn_freelist_fini (struct nn_freelist *fl, void (*xfree) (void *))
static ddsrt_atomic_uint32_t freelist_inner_idx_off = DDSRT_ATOMIC_UINT32_INIT(0);
+#ifdef DDSRT_WITH_FREERTOSTCP
+static int get_freelist_inner_idx (void)
+{
+ int inner_idx = -1;
+
+ inner_idx = ddsrt_thread_tls_get(DDS_TLS_IDX_FREE, freelist_inner_idx);
+
+ if(inner_idx == -1)
+ {
+ static const uint64_t unihashconsts[] = {
+ UINT64_C (16292676669999574021),
+ UINT64_C (10242350189706880077),
+ };
+ uintptr_t addr;
+ uint64_t t = (uint64_t) ((uintptr_t) &addr) + ddsrt_atomic_ld32 (&freelist_inner_idx_off);
+ inner_idx = (int) (((((uint32_t) t + unihashconsts[0]) * ((uint32_t) (t >> 32) + unihashconsts[1]))) >> (64 - NN_FREELIST_NPAR_LG2));
+ }
+ ddsrt_thread_tls_set(freelist_inner_idx, DDS_TLS_IDX_FREE, inner_idx);
+ return inner_idx;
+}
+#else
static int get_freelist_inner_idx (void)
{
if (freelist_inner_idx == -1)
@@ -174,6 +200,7 @@ static int get_freelist_inner_idx (void)
}
return freelist_inner_idx;
}
+#endif
static int lock_inner (struct nn_freelist *fl)
{
@@ -185,7 +212,12 @@ static int lock_inner (struct nn_freelist *fl)
{
ddsrt_atomic_st32(&fl->cc, 0);
ddsrt_atomic_inc32(&freelist_inner_idx_off);
+
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ ddsrt_thread_tls_set(freelist_inner_idx, DDS_TLS_IDX_FREE, (void*)(-1));
+ #else
freelist_inner_idx = -1;
+ #endif
}
}
return k;
diff --git a/src/core/ddsi/src/q_gc.c b/src/core/ddsi/src/q_gc.c
index 61819126..7941ceb3 100644
--- a/src/core/ddsi/src/q_gc.c
+++ b/src/core/ddsi/src/q_gc.c
@@ -204,7 +204,11 @@ struct gcreq_queue *gcreq_queue_new (struct ddsi_domaingv *gv)
bool gcreq_queue_start (struct gcreq_queue *q)
{
+#ifdef DDSRT_WITH_FREERTOSTCP
+ if (create_thread (&q->ts, q->gv, "dds_gc", (uint32_t (*) (void *)) gcreq_queue_thread, q) == DDS_RETCODE_OK)
+#else
if (create_thread (&q->ts, q->gv, "gc", (uint32_t (*) (void *)) gcreq_queue_thread, q) == DDS_RETCODE_OK)
+#endif
return true;
else
{
diff --git a/src/core/ddsi/src/q_init.c b/src/core/ddsi/src/q_init.c
index 0338f7e8..f7f4725d 100644
--- a/src/core/ddsi/src/q_init.c
+++ b/src/core/ddsi/src/q_init.c
@@ -130,6 +130,13 @@ static enum make_uc_sockets_ret make_uc_sockets (struct ddsi_domaingv *gv, uint3
}
ddsi_conn_locator (gv->disc_conn_uc, &gv->loc_meta_uc);
ddsi_conn_locator (gv->data_conn_uc, &gv->loc_default_uc);
+
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ /* update portid to up */
+ *pdisc = gv->disc_conn_uc->m_base.m_port;
+ *pdata = gv->data_conn_uc->m_base.m_port;
+ #endif
+
return MUSRET_SUCCESS;
fail_data:
@@ -539,6 +546,7 @@ int rtps_config_prep (struct ddsi_domaingv *gv, struct cfgst *cfgst)
DDS_ILOG (DDS_LC_ERROR, gv->config.domainId, "Invalid port mapping: %s\n", message);
goto err_config_late_error;
}
+ DDS_ILOG (DDS_LC_INFO, gv->config.domainId, " @@@@@@@@@@@ port mapping: <%s> \n", message);
}
/* retry_on_reject_duration default is dependent on late_ack_mode and responsiveness timeout, so fix up */
@@ -1022,20 +1030,23 @@ static int setup_and_start_recv_threads (struct ddsi_domaingv *gv)
it before it does anything with it. */
if ((gv->recv_threads[i].arg.rbpool = nn_rbufpool_new (&gv->logconfig, gv->config.rbuf_size, gv->config.rmsg_chunk_size)) == NULL)
{
- GVERROR ("rtps_init: can't allocate receive buffer pool for thread %s\n", gv->recv_threads[i].name);
+ GVERROR ("rtps_start: can't allocate receive buffer pool for thread %s\n", gv->recv_threads[i].name);
goto fail;
}
+ GVLOG(DDS_LC_CONFIG, "rtps_start: alloc rbpool %p for recv_thread[%d] '%s' done \n",
+ gv->recv_threads[i].arg.rbpool, i, gv->recv_threads[i].name);
if (gv->recv_threads[i].arg.mode == RTM_MANY)
{
if ((gv->recv_threads[i].arg.u.many.ws = os_sockWaitsetNew ()) == NULL)
{
- GVERROR ("rtps_init: can't allocate sock waitset for thread %s\n", gv->recv_threads[i].name);
+ GVERROR ("rtps_start: can't allocate sock waitset for thread %s\n", gv->recv_threads[i].name);
goto fail;
}
+ GVLOG(DDS_LC_CONFIG, "rtps_start: allocate sock waitset for thread %s done \n", gv->recv_threads[i].name);
}
if (create_thread (&gv->recv_threads[i].ts, gv, gv->recv_threads[i].name, recv_thread, &gv->recv_threads[i].arg) != DDS_RETCODE_OK)
{
- GVERROR ("rtps_init: failed to start thread %s\n", gv->recv_threads[i].name);
+ GVERROR ("rtps_start: failed to start thread %s\n", gv->recv_threads[i].name);
goto fail;
}
}
@@ -1339,6 +1350,7 @@ int rtps_init (struct ddsi_domaingv *gv)
gv->listener = NULL;
gv->debmon = NULL;
+#ifndef DDSRT_WITH_FREERTOS
/* Print start time for referencing relative times in the remainder of the DDS_LOG. */
{
int sec = (int) (gv->tstart.v / 1000000000);
@@ -1347,6 +1359,7 @@ int rtps_init (struct ddsi_domaingv *gv)
ddsrt_ctime(gv->tstart.v, str, sizeof(str));
GVLOG (DDS_LC_CONFIG, "started at %d.06%d -- %s\n", sec, usec, str);
}
+#endif
/* Allow configuration to set "deaf_mute" in case we want to start out that way */
gv->deaf = gv->config.initial_deaf;
@@ -1362,6 +1375,7 @@ int rtps_init (struct ddsi_domaingv *gv)
{
case DDSI_TRANS_DEFAULT:
assert(0);
+#ifdef DDSRT_TRANS_UDP
case DDSI_TRANS_UDP:
case DDSI_TRANS_UDP6:
gv->config.publish_uc_locators = 1;
@@ -1370,6 +1384,8 @@ int rtps_init (struct ddsi_domaingv *gv)
goto err_udp_tcp_init;
gv->m_factory = ddsi_factory_find (gv, gv->config.transport_selector == DDSI_TRANS_UDP ? "udp" : "udp6");
break;
+#endif
+#ifdef DDSRT_TRANS_TCP
case DDSI_TRANS_TCP:
case DDSI_TRANS_TCP6:
gv->config.publish_uc_locators = (gv->config.tcp_port != -1);
@@ -1381,6 +1397,8 @@ int rtps_init (struct ddsi_domaingv *gv)
goto err_udp_tcp_init;
gv->m_factory = ddsi_factory_find (gv, gv->config.transport_selector == DDSI_TRANS_TCP ? "tcp" : "tcp6");
break;
+#endif
+#ifdef DDSRT_TRANS_RAWETH
case DDSI_TRANS_RAWETH:
gv->config.publish_uc_locators = 1;
gv->config.enable_uc_locators = 0;
@@ -1390,6 +1408,8 @@ int rtps_init (struct ddsi_domaingv *gv)
goto err_udp_tcp_init;
gv->m_factory = ddsi_factory_find (gv, "raweth");
break;
+#endif
+#ifdef DDSRT_TRANS_NONE
case DDSI_TRANS_NONE:
gv->config.publish_uc_locators = 0;
gv->config.enable_uc_locators = 0;
@@ -1399,6 +1419,7 @@ int rtps_init (struct ddsi_domaingv *gv)
goto err_udp_tcp_init;
gv->m_factory = ddsi_factory_find (gv, "dummy");
break;
+#endif
}
gv->m_factory->m_enable = true;
@@ -1423,12 +1444,12 @@ int rtps_init (struct ddsi_domaingv *gv)
{
if (!gv->interfaces[i].mc_capable)
{
- GVWARNING ("selected interface \"%s\" is not multicast-capable: disabling multicast\n", gv->interfaces[i].name);
gv->config.allowMulticast = DDSI_AMC_FALSE;
/* ensure discovery can work: firstly, that the process will be reachable on a "well-known" port
number, and secondly, that the local interface's IP address gets added to the discovery
address set */
gv->config.participantIndex = DDSI_PARTICIPANT_INDEX_AUTO;
+ GVWARNING ("selected interface \"%s\" is not multicast-capable: disabling multicast\n", gv->interfaces[i].name);
}
else if (gv->config.allowMulticast & DDSI_AMC_DEFAULT)
{
@@ -1438,7 +1459,7 @@ int rtps_init (struct ddsi_domaingv *gv)
if (gv->interfaces[i].mc_flaky)
{
gv->config.allowMulticast = DDSI_AMC_SPDP;
- GVLOG (DDS_LC_CONFIG, "presumed flaky multicast, use for SPDP only\n");
+ GVLOG (DDS_LC_CONFIG, "presumed flaky multicast(0x%08x), use for SPDP only\n", gv->config.allowMulticast);
}
else
{
@@ -1447,6 +1468,12 @@ int rtps_init (struct ddsi_domaingv *gv)
}
}
}
+#ifdef DDSRT_WITH_FREERTOSTCP
+ }
+ else
+ {
+ GVWARNING (" (gv->config.allowMulticast) is false! \n");
+#endif
}
assert ((gv->config.allowMulticast & DDSI_AMC_DEFAULT) == 0);
@@ -1573,8 +1600,12 @@ int rtps_init (struct ddsi_domaingv *gv)
memcpy (&gv->ppguid_base.prefix.s[2], digest, sizeof (gv->ppguid_base.prefix.s) - 2);
gv->ppguid_base.prefix = nn_ntoh_guid_prefix (gv->ppguid_base.prefix);
gv->ppguid_base.entityid.u = NN_ENTITYID_PARTICIPANT;
+ GVLOG(DDS_LC_CONFIG, " GUID prefix: "PGUIDFMT "vs [%08x %08x %08x]",
+ PGUID (gv->ppguid_base),
+ gv->ppguid_base.prefix.u[0], gv->ppguid_base.prefix.u[1], gv->ppguid_base.prefix.u[2]);
}
+
ddsrt_mutex_init (&gv->lock);
ddsrt_mutex_init (&gv->spdp_lock);
gv->spdp_defrag = nn_defrag_new (&gv->logconfig, NN_DEFRAG_DROP_OLDEST, gv->config.defrag_unreliable_maxsamples);
@@ -1582,6 +1613,8 @@ int rtps_init (struct ddsi_domaingv *gv)
gv->m_tkmap = ddsi_tkmap_new (gv);
+ GVLOG (DDS_LC_CONFIG, "participantIndex %d \n", gv->config.participantIndex);
+
if (gv->m_factory->m_connless)
{
if (gv->config.participantIndex >= 0 || gv->config.participantIndex == DDSI_PARTICIPANT_INDEX_NONE)
@@ -1600,6 +1633,8 @@ int rtps_init (struct ddsi_domaingv *gv)
goto err_unicast_sockets;
case MUSRET_ERROR:
/* something bad happened; assume make_uc_sockets logged the error */
+ GVERROR ("rtps_init: other failed to create unicast sockets for domain %"PRId32" participant index %d (ports %"PRIu32", %"PRIu32")\n",
+ gv->config.extDomainId.value, gv->config.participantIndex, port_disc_uc, port_data_uc);
goto err_unicast_sockets;
}
}
@@ -1621,8 +1656,10 @@ int rtps_init (struct ddsi_domaingv *gv)
gv->config.extDomainId.value, ppid, port_disc_uc, port_data_uc);
goto err_unicast_sockets;
case MUSRET_PORTS_IN_USE: /* Try next one */
+ GVERROR ("Failed to create unicast sockets PORTS_IN_USE \n");
break;
case MUSRET_ERROR:
+ GVERROR ("Failed to create unicast sockets ERROR \n");
/* something bad happened; assume make_uc_sockets logged the error */
goto err_unicast_sockets;
}
@@ -1632,6 +1669,7 @@ int rtps_init (struct ddsi_domaingv *gv)
GVERROR ("Failed to find a free participant index for domain %"PRIu32"\n", gv->config.extDomainId.value);
goto err_unicast_sockets;
}
+ GVLOG (DDS_LC_INFO,"find a participant %d index for domain %"PRIu32"\n", ppid, gv->config.extDomainId.value);
gv->config.participantIndex = ppid;
}
else
@@ -1640,11 +1678,12 @@ int rtps_init (struct ddsi_domaingv *gv)
}
GVLOG (DDS_LC_CONFIG, "rtps_init: uc ports: disc %"PRIu32" data %"PRIu32"\n", port_disc_uc, port_data_uc);
}
- GVLOG (DDS_LC_CONFIG, "rtps_init: domainid %"PRIu32" participantid %d\n", gv->config.domainId, gv->config.participantIndex);
+ GVLOG (DDS_LC_INFO, "rtps_init: domainid %"PRIu32" participantid %d\n", gv->config.domainId, gv->config.participantIndex);
if (gv->config.pcap_file && *gv->config.pcap_file)
{
gv->pcap_fp = new_pcap_file (gv, gv->config.pcap_file);
+ GVLOG (DDS_LC_CONFIG, "rtps_init: pcap_file %s done \n", gv->config.pcap_file);
if (gv->pcap_fp)
{
ddsrt_mutex_init (&gv->pcap_lock);
@@ -2032,6 +2071,8 @@ int rtps_start (struct ddsi_domaingv *gv)
return -1;
}
}
+
+#ifdef DDSRT_TRANS_TCP
if (gv->config.monitor_port >= 0)
{
if ((gv->debmon = new_debug_monitor (gv, gv->config.monitor_port)) == NULL)
@@ -2041,6 +2082,7 @@ int rtps_start (struct ddsi_domaingv *gv)
return -1;
}
}
+#endif
return 0;
}
diff --git a/src/core/ddsi/src/q_pcap.c b/src/core/ddsi/src/q_pcap.c
index 3b843f79..bb0115c1 100644
--- a/src/core/ddsi/src/q_pcap.c
+++ b/src/core/ddsi/src/q_pcap.c
@@ -145,8 +145,13 @@ void write_pcap_received (struct ddsi_domaingv *gv, ddsrt_wctime_t tstamp, const
u.ipv4_hdr = ipv4_hdr_template;
u.ipv4_hdr.totallength = ddsrt_toBE2u ((unsigned short) sz_iud);
u.ipv4_hdr.ttl = 128;
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr;
+ u.ipv4_hdr.dstip = ((struct sockaddr_in*) dst)->sin_addr;
+ #else
u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr.s_addr;
u.ipv4_hdr.dstip = ((struct sockaddr_in*) dst)->sin_addr.s_addr;
+ #endif
u.ipv4_hdr.checksum = calc_ipv4_checksum (u.x);
(void) fwrite (&u.ipv4_hdr, sizeof (u.ipv4_hdr), 1, gv->pcap_fp);
udp_hdr.srcport = ((struct sockaddr_in*) src)->sin_port;
@@ -178,8 +183,13 @@ void write_pcap_sent (struct ddsi_domaingv *gv, ddsrt_wctime_t tstamp, const str
u.ipv4_hdr = ipv4_hdr_template;
u.ipv4_hdr.totallength = ddsrt_toBE2u ((unsigned short) sz_iud);
u.ipv4_hdr.ttl = 255;
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr;
+ u.ipv4_hdr.dstip = ((struct sockaddr_in*) hdr->msg_name)->sin_addr;
+ #else
u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr.s_addr;
u.ipv4_hdr.dstip = ((struct sockaddr_in*) hdr->msg_name)->sin_addr.s_addr;
+ #endif
u.ipv4_hdr.checksum = calc_ipv4_checksum (u.x);
(void) fwrite (&u.ipv4_hdr, sizeof (u.ipv4_hdr), 1, gv->pcap_fp);
udp_hdr.srcport = ((struct sockaddr_in*) src)->sin_port;
diff --git a/src/core/ddsi/src/q_receive.c b/src/core/ddsi/src/q_receive.c
index e4898c34..65cd2e8b 100644
--- a/src/core/ddsi/src/q_receive.c
+++ b/src/core/ddsi/src/q_receive.c
@@ -3177,7 +3177,7 @@ static void handle_rtps_message (struct thread_state1 * const ts1, struct ddsi_d
else if (hdr->version.major != RTPS_MAJOR || (hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM))
{
if ((hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM))
- GVTRACE ("HDR(%"PRIx32":%"PRIx32":%"PRIx32" vendor %d.%d) len %lu\n, version mismatch: %d.%d\n",
+ GVWARNING ("HDR(%"PRIx32":%"PRIx32":%"PRIx32" vendor %d.%d) len %lu\n, version mismatch: %d.%d\n",
PGUIDPREFIX (hdr->guid_prefix), hdr->vendorid.id[0], hdr->vendorid.id[1], (unsigned long) sz, hdr->version.major, hdr->version.minor);
if (DDSI_SC_PEDANTIC_P (gv->config))
malformed_packet_received (gv, msg, NULL, (size_t) sz, hdr->vendorid);
@@ -3197,6 +3197,12 @@ static void handle_rtps_message (struct thread_state1 * const ts1, struct ddsi_d
if (res != NN_RTPS_MSG_STATE_ERROR)
{
handle_submsg_sequence (ts1, gv, conn, srcloc, ddsrt_time_wallclock (), ddsrt_time_elapsed (), &hdr->guid_prefix, guidprefix, msg, (size_t) sz, msg + RTPS_MESSAGE_HEADER_SIZE, rmsg, res == NN_RTPS_MSG_STATE_ENCODED);
+#ifdef DDSRT_WITH_FREERTOSTCP
+ }
+ else
+ {
+ GVWARNING(" decode_rtps_messages error! \n");
+#endif
}
}
}
@@ -3229,7 +3235,7 @@ static bool do_packet (struct thread_state1 * const ts1, struct ddsi_domaingv *g
buff = (unsigned char *) NN_RMSG_PAYLOAD (rmsg);
hdr = (Header_t*) buff;
- if (conn->m_stream)
+ if (conn->m_stream) /* ONLY for TCP conn */
{
MsgLen_t * ml = (MsgLen_t*) (hdr + 1);
@@ -3446,13 +3452,16 @@ uint32_t listen_thread (struct ddsi_tran_listener *listener)
static int recv_thread_waitset_add_conn (os_sockWaitset ws, ddsi_tran_conn_t conn)
{
if (conn == NULL)
- return 0;
+ { return 0; }
else
{
struct ddsi_domaingv *gv = conn->m_base.gv;
for (uint32_t i = 0; i < gv->n_recv_threads; i++)
+ {
+ /* SKIP add thread "recvUC" / gv->data_conn_uc to waitset! */
if (gv->recv_threads[i].arg.mode == RTM_SINGLE && gv->recv_threads[i].arg.u.single.conn == conn)
- return 0;
+ { return 0; }
+ }
return os_sockWaitsetAdd (ws, conn);
}
}
@@ -3495,6 +3504,12 @@ uint32_t recv_thread (void *vrecv_thread_arg)
os_sockWaitset waitset = recv_thread_arg->mode == RTM_MANY ? recv_thread_arg->u.many.ws : NULL;
ddsrt_mtime_t next_thread_cputime = { 0 };
+#ifdef DDSRT_WITH_FREERTOS
+ char name[64];
+ ddsrt_thread_getname (name, sizeof (name));
+ DDS_WARNING("recv_thread: called up for thread[%s] \n", name);
+#endif
+
nn_rbufpool_setowner (rbpool, ddsrt_thread_self ());
if (waitset == NULL)
{
@@ -3515,17 +3530,36 @@ uint32_t recv_thread (void *vrecv_thread_arg)
{
int rc;
if ((rc = recv_thread_waitset_add_conn (waitset, gv->disc_conn_uc)) < 0)
- DDS_FATAL("recv_thread: failed to add disc_conn_uc to waitset\n");
+ { DDS_FATAL("recv_thread: failed to add disc_conn_uc to waitset\n"); }
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ if (rc > 0)
+ { DDS_INFO("recv_thread: add disc_conn_uc to waitset ! \n"); }
+ #endif
num_fixed_uc += (unsigned)rc;
+
if ((rc = recv_thread_waitset_add_conn (waitset, gv->data_conn_uc)) < 0)
DDS_FATAL("recv_thread: failed to add data_conn_uc to waitset\n");
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ if (rc > 0)
+ { DDS_INFO("recv_thread: add data_conn_uc to waitset ! \n"); }
+ #endif
num_fixed_uc += (unsigned)rc;
+
num_fixed += num_fixed_uc;
if ((rc = recv_thread_waitset_add_conn (waitset, gv->disc_conn_mc)) < 0)
DDS_FATAL("recv_thread: failed to add disc_conn_mc to waitset\n");
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ if (rc > 0)
+ { DDS_INFO("recv_thread: add disc_conn_mc to waitset ! \n"); }
+ #endif
num_fixed += (unsigned)rc;
+
if ((rc = recv_thread_waitset_add_conn (waitset, gv->data_conn_mc)) < 0)
DDS_FATAL("recv_thread: failed to add data_conn_mc to waitset\n");
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ if (rc > 0)
+ { DDS_INFO("recv_thread: add data_conn_mc to waitset ! \n"); }
+ #endif
num_fixed += (unsigned)rc;
// OpenDDS doesn't respect the locator lists and insists on sending to the
@@ -3535,9 +3569,13 @@ uint32_t recv_thread (void *vrecv_thread_arg)
// Iceoryx gets added as a pseudo-interface but there's no socket to wait
// for input on
if (ddsi_conn_handle (gv->xmit_conns[i]) == DDSRT_INVALID_SOCKET)
- continue;
+ { continue; }
if ((rc = recv_thread_waitset_add_conn (waitset, gv->xmit_conns[i])) < 0)
- DDS_FATAL("recv_thread: failed to add transmit_conn[%d] to waitset\n", i);
+ DDS_FATAL("recv_thread: failed to add xmit_conn[%d] to waitset\n", i);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ if (rc > 0)
+ { DDS_INFO("recv_thread: add xmit_conn[%d] to waitset ! \n", i); }
+ #endif
num_fixed += (unsigned)rc;
}
}
@@ -3564,7 +3602,7 @@ uint32_t recv_thread (void *vrecv_thread_arg)
for (uint32_t i = 0; i < lps.nps; i++)
{
if (lps.ps[i].m_conn)
- os_sockWaitsetAdd (waitset, lps.ps[i].m_conn);
+ { os_sockWaitsetAdd (waitset, lps.ps[i].m_conn); }
}
}
@@ -3575,13 +3613,18 @@ uint32_t recv_thread (void *vrecv_thread_arg)
while ((idx = os_sockWaitsetNextEvent (ctx, &conn)) >= 0)
{
const ddsi_guid_prefix_t *guid_prefix;
- if (((unsigned)idx < num_fixed) || gv->config.many_sockets_mode != DDSI_MSM_MANY_UNICAST)
- guid_prefix = NULL;
+ if (((unsigned)idx < num_fixed)
+ || gv->config.many_sockets_mode != DDSI_MSM_MANY_UNICAST)
+ { guid_prefix = NULL; }
else
- guid_prefix = &lps.ps[(unsigned)idx - num_fixed].guid_prefix;
+ { guid_prefix = &lps.ps[(unsigned)idx - num_fixed].guid_prefix; }
+
/* Process message and clean out connection if failed or closed */
- if (!do_packet (ts1, gv, conn, guid_prefix, rbpool) && !conn->m_connless)
+ if (!do_packet (ts1, gv, conn, guid_prefix, rbpool)
+ && !conn->m_connless)
+ {
ddsi_conn_free (conn);
+ }
}
}
}
diff --git a/src/core/ddsi/src/q_sockwaitset_s.c b/src/core/ddsi/src/q_sockwaitset_s.c
new file mode 100755
index 00000000..df1c8bc9
--- /dev/null
+++ b/src/core/ddsi/src/q_sockwaitset_s.c
@@ -0,0 +1,522 @@
+/*
+ * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
+ * v. 1.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
+#include
+#include
+
+#include "dds/ddsrt/heap.h"
+#include "dds/ddsrt/sockets.h"
+#include "dds/ddsrt/sync.h"
+
+#include "dds/ddsi/q_sockwaitset.h"
+#include "dds/ddsi/ddsi_config_impl.h"
+#include "dds/ddsi/q_log.h"
+#include "dds/ddsi/ddsi_tran.h"
+
+#define WAITSET_DELTA 8
+
+#define MODE_KQUEUE 1
+#define MODE_SELECT 2
+#define MODE_WFMEVS 3
+
+#if defined __APPLE__
+#define MODE_SEL MODE_KQUEUE
+#elif defined WINCE
+#define MODE_SEL MODE_WFMEVS
+#else
+#define MODE_SEL MODE_SELECT /* FreeRTOS always use select */
+#endif
+
+
+#ifdef DDSRT_WITH_FREERTOSTCP
+# warning " *** FreeRTOS-Plus-TCP debug include tree "
+
+#else
+#if !_WIN32 && !LWIP_SOCKET
+
+#if ! __VXWORKS__&& !__QNXNTO__
+#include
+#endif /* __VXWORKS__ __QNXNTO__ */
+
+#ifndef _WRS_KERNEL
+#include
+#endif
+#ifdef __sun
+#include
+#include
+#include
+#endif
+
+#endif /* !_WIN32 && !LWIP_SOCKET */
+#endif
+
+typedef struct os_sockWaitsetSet
+{
+ ddsi_tran_conn_t * conns; /* connections in set */
+ ddsrt_socket_t * fds; /* file descriptors in set */
+ unsigned sz; /* max number of fds in context */
+ unsigned n; /* actual number of fds in context */
+} os_sockWaitsetSet;
+
+struct os_sockWaitsetCtx
+{
+ os_sockWaitsetSet set; /* set of connections and descriptors */
+ unsigned index; /* cursor for enumerating */
+ ddsrt_fd_set_t rdset; /* read file descriptors set */
+};
+
+struct os_sockWaitset
+{
+ ddsrt_socket_t pipe[2]; /* pipe used for triggering */
+ ddsrt_mutex_t mutex; /* concurrency guard */
+ int fdmax_plus_1; /* value for first parameter of select() */
+ os_sockWaitsetSet set; /* set of descriptors handled next */
+ struct os_sockWaitsetCtx ctx; /* set of descriptors being handled */
+};
+
+#if defined (_WIN32)
+static int make_pipe (ddsrt_socket_t fd[2])
+{
+ struct sockaddr_in addr;
+ socklen_t asize = sizeof (addr);
+ ddsrt_socket_t listener = socket (AF_INET, SOCK_STREAM, 0);
+ ddsrt_socket_t s1 = socket (AF_INET, SOCK_STREAM, 0);
+ ddsrt_socket_t s2 = DDSRT_INVALID_SOCKET;
+
+ addr.sin_family = AF_INET;
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ addr.sin_addr = htonl (INADDR_LOOPBACK);
+ #else
+ addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ #endif
+ addr.sin_port = 0;
+ if (bind (listener, (struct sockaddr *)&addr, sizeof (addr)) == -1)
+ goto fail;
+ if (getsockname (listener, (struct sockaddr *)&addr, &asize) == -1)
+ goto fail;
+ if (listen (listener, 1) == -1)
+ goto fail;
+ if (connect (s1, (struct sockaddr *)&addr, sizeof (addr)) == -1)
+ goto fail;
+ if ((s2 = accept (listener, 0, 0)) == INVALID_SOCKET)
+ goto fail;
+ closesocket (listener);
+ /* Equivalent to FD_CLOEXEC */
+ SetHandleInformation ((HANDLE) s1, HANDLE_FLAG_INHERIT, 0);
+ SetHandleInformation ((HANDLE) s2, HANDLE_FLAG_INHERIT, 0);
+ fd[0] = s1;
+ fd[1] = s2;
+ return 0;
+
+fail:
+ closesocket (listener);
+ closesocket (s1);
+ closesocket (s2);
+ return -1;
+}
+#elif defined(__VXWORKS__)
+static int make_pipe (int pfd[2])
+{
+ char pipename[OSPL_PIPENAMESIZE];
+ int pipecount = 0;
+ do {
+ snprintf ((char*)&pipename, sizeof (pipename), "/pipe/ospl%d", pipecount++);
+ } while ((result = pipeDevCreate ((char*)&pipename, 1, 1)) == -1 && os_getErrno() == EINVAL);
+ if (result == -1)
+ goto fail_pipedev;
+ if ((pfd[0] = open ((char*)&pipename, O_RDWR, 0644)) == -1)
+ goto fail_open0;
+ if ((pfd[1] = open ((char*)&pipename, O_RDWR, 0644)) == -1)
+ goto fail_open1;
+ return 0;
+
+fail_open1:
+ close (pfd[0]);
+fail_open0:
+ pipeDevDelete (pipename, 0);
+fail_pipedev:
+ return -1;
+}
+#elif !defined(LWIP_SOCKET)
+static int make_pipe (int pfd[2])
+{
+ return pipe (pfd);
+}
+#endif
+
+static void os_sockWaitsetNewSet (os_sockWaitsetSet * set)
+{
+ set->fds = ddsrt_malloc (WAITSET_DELTA * sizeof (*set->fds));
+ set->conns = ddsrt_malloc (WAITSET_DELTA * sizeof (*set->conns));
+ set->sz = WAITSET_DELTA;
+ set->n = 1;
+}
+
+static void os_sockWaitsetFreeSet (os_sockWaitsetSet * set)
+{
+ ddsrt_free (set->fds);
+ ddsrt_free (set->conns);
+}
+
+static void os_sockWaitsetNewCtx (os_sockWaitsetCtx ctx)
+{
+ os_sockWaitsetNewSet (&ctx->set);
+
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ ctx->rdset = DDSRT_FD_SET_CRATE();
+ DDSRT_FD_ZERO (ctx->rdset);
+ DDS_WARNING("os_sockWaitsetNewCtx: rdset created! rdset %p \n", ctx->rdset);
+ #else
+ FD_ZERO (ctx->rdset);
+ #endif
+}
+
+static void os_sockWaitsetFreeCtx (os_sockWaitsetCtx ctx)
+{
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ DDSRT_FD_SET_DELETE(ctx->rdset);
+ #endif
+ os_sockWaitsetFreeSet (&ctx->set);
+}
+
+os_sockWaitset os_sockWaitsetNew (void)
+{
+ int result;
+ os_sockWaitset ws = ddsrt_malloc (sizeof (*ws));
+
+ os_sockWaitsetNewSet (&ws->set);
+ os_sockWaitsetNewCtx (&ws->ctx);
+
+#if ! defined (_WIN32)
+ ws->fdmax_plus_1 = 0;
+#else
+ ws->fdmax_plus_1 = FD_SETSIZE;
+#endif
+
+#if defined(LWIP_SOCKET)
+ ws->pipe[0] = -1;
+ ws->pipe[1] = -1;
+ result = 0;
+#elif defined(DDSRT_WITH_FREERTOSTCP)
+ # warning " *** FreeRTOS-Plus-TCP FreeRTOS_Plus_TCP runtime wrapper ..."
+ ws->pipe[0] = -1;
+ ws->pipe[1] = -1;
+ result = 0;
+#else
+ # error " *** NO makepipe for FreeRTOS "
+
+ result = make_pipe (ws->pipe);
+#endif
+ if (result == -1)
+ {
+ os_sockWaitsetFreeCtx (&ws->ctx);
+ os_sockWaitsetFreeSet (&ws->set);
+ ddsrt_free (ws);
+ return NULL;
+ }
+
+#if !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP)
+ ws->set.fds[0] = ws->pipe[0];
+#else
+#warning " *** FreeRTOS-Plus-TCP FreeRTOS_Plus_TCP runtime wrapper ..."
+ ws->set.fds[0] = 0;
+#endif
+ ws->set.conns[0] = NULL;
+
+#if !defined(__VXWORKS__) && !defined(_WIN32) && !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) && !defined(__QNXNTO__)
+ (void) fcntl (ws->pipe[0], F_SETFD, fcntl (ws->pipe[0], F_GETFD) | FD_CLOEXEC);
+ (void) fcntl (ws->pipe[1], F_SETFD, fcntl (ws->pipe[1], F_GETFD) | FD_CLOEXEC);
+#endif
+
+#if !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP)
+ FD_SET (ws->set.fds[0], ws->ctx.rdset);
+#endif
+
+#if !defined(_WIN32) && !defined(DDSRT_WITH_FREERTOSTCP)
+ ws->fdmax_plus_1 = ws->set.fds[0] + 1;
+#endif
+
+ ddsrt_mutex_init (&ws->mutex);
+
+ return ws;
+}
+
+static void os_sockWaitsetGrow (os_sockWaitsetSet * set)
+{
+ set->sz += WAITSET_DELTA;
+ set->conns = ddsrt_realloc (set->conns, set->sz * sizeof (*set->conns));
+ set->fds = ddsrt_realloc (set->fds, set->sz * sizeof (*set->fds));
+}
+
+void os_sockWaitsetFree (os_sockWaitset ws)
+{
+#if defined(__VXWORKS__) && defined(__RTP__)
+ char nameBuf[OSPL_PIPENAMESIZE];
+ ioctl (ws->pipe[0], FIOGETNAME, &nameBuf);
+#endif
+
+#if defined(DDSRT_WITH_FREERTOSTCP)
+# warning " *** FreeRTOS-Plus-TCP runtime tree "
+ (void) ddsrt_close (ws->pipe[0]);
+ (void) ddsrt_close (ws->pipe[1]);
+#else
+
+#if defined(_WIN32)
+ closesocket (ws->pipe[0]);
+ closesocket (ws->pipe[1]);
+#elif !defined(LWIP_SOCKET)
+ (void) close (ws->pipe[0]);
+ (void) close (ws->pipe[1]);
+#endif
+#endif
+
+#if defined(__VXWORKS__) && defined(__RTP__)
+ pipeDevDelete ((char*) &nameBuf, 0);
+#endif
+ os_sockWaitsetFreeSet (&ws->set);
+ os_sockWaitsetFreeCtx (&ws->ctx);
+ ddsrt_mutex_destroy (&ws->mutex);
+ ddsrt_free (ws);
+}
+
+void os_sockWaitsetTrigger (os_sockWaitset ws)
+{
+#if defined(LWIP_SOCKET)
+ (void)ws;
+#elif defined (DDSRT_WITH_FREERTOSTCP)
+#warning " *** FreeRTOS-Plus-TCP FreeRTOS_Plus_TCP runtime wrapper ..."
+ (void)ws;
+#else
+ char buf = 0;
+ int n;
+
+#if defined (_WIN32)
+ n = send (ws->pipe[1], &buf, 1, 0);
+#else
+ n = (int) write (ws->pipe[1], &buf, 1);
+#endif
+ if (n != 1)
+ {
+ DDS_WARNING("os_sockWaitsetTrigger: write failed on trigger pipe\n");
+ }
+#endif
+}
+
+int os_sockWaitsetAdd (os_sockWaitset ws, ddsi_tran_conn_t conn)
+{
+ ddsrt_socket_t handle = ddsi_conn_handle (conn);
+ os_sockWaitsetSet * set = &ws->set;
+ unsigned idx;
+ int ret;
+
+#if ! defined (_WIN32) && ! defined(DDSRT_WITH_FREERTOSTCP)
+ assert (handle >= 0);
+ assert (handle < FD_SETSIZE);
+#endif
+
+ ddsrt_mutex_lock (&ws->mutex);
+ for (idx = 0; idx < set->n; idx++)
+ {
+ if (set->conns[idx] == conn)
+ break;
+ }
+ if (idx < set->n)
+ { ret = 0; }
+ else
+ {
+ if (set->n == set->sz)
+ { os_sockWaitsetGrow (set); }
+#if ! defined (_WIN32) && ! defined(DDSRT_WITH_FREERTOSTCP)
+ if ((int) handle >= ws->fdmax_plus_1)
+ ws->fdmax_plus_1 = handle + 1;
+#endif
+ set->conns[set->n] = conn;
+ set->fds[set->n] = handle;
+ set->n++;
+ ret = 1;
+ }
+ ddsrt_mutex_unlock (&ws->mutex);
+ return ret;
+}
+
+void os_sockWaitsetPurge (os_sockWaitset ws, unsigned index)
+{
+ os_sockWaitsetSet * set = &ws->set;
+
+ ddsrt_mutex_lock (&ws->mutex);
+ if (index + 1 <= set->n)
+ {
+ for (unsigned i = index + 1; i < set->n; i++)
+ {
+ set->conns[i] = NULL;
+ set->fds[i] = 0;
+ }
+ set->n = index + 1;
+ }
+ ddsrt_mutex_unlock (&ws->mutex);
+}
+
+void os_sockWaitsetRemove (os_sockWaitset ws, ddsi_tran_conn_t conn)
+{
+ os_sockWaitsetSet * set = &ws->set;
+
+ ddsrt_mutex_lock (&ws->mutex);
+ for (unsigned i = 0; i < set->n; i++)
+ {
+ if (conn == set->conns[i])
+ {
+ set->n--;
+ if (i != set->n)
+ {
+ set->fds[i] = set->fds[set->n];
+ set->conns[i] = set->conns[set->n];
+ }
+ break;
+ }
+ }
+ ddsrt_mutex_unlock (&ws->mutex);
+}
+
+os_sockWaitsetCtx os_sockWaitsetWait (os_sockWaitset ws)
+{
+ unsigned u;
+#if !_WIN32
+ int fdmax;
+#endif
+ ddsrt_fd_set_t rdset = NULL;
+ os_sockWaitsetCtx ctx = &ws->ctx;
+ os_sockWaitsetSet * dst = &ctx->set;
+ os_sockWaitsetSet * src = &ws->set;
+
+ ddsrt_mutex_lock (&ws->mutex);
+
+#ifdef DDSRT_WITH_FREERTOSTCP
+ fdmax = 0; /* For FreeRTOS_TCP stack, fdmax is stub for api compatible */
+#else
+ #if !_WIN32
+ fdmax = ws->fdmax_plus_1;
+ #endif
+#endif
+
+ /* Copy context to working context */
+
+ while (dst->sz < src->sz)
+ {
+ os_sockWaitsetGrow (dst);
+ }
+ dst->n = src->n;
+
+ for (u = 0; u < src->n; u++)
+ {
+ dst->conns[u] = src->conns[u];
+ dst->fds[u] = src->fds[u];
+ }
+
+ ddsrt_mutex_unlock (&ws->mutex);
+
+
+ /* Copy file descriptors into select read set */
+ rdset = ctx->rdset;
+#ifdef DDSRT_WITH_FREERTOSTCP
+ if (rdset == NULL)
+ {
+ assert(0);
+ }
+
+#endif
+
+ DDSRT_FD_ZERO (rdset);
+#if !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP)
+ for (u = 0; u < dst->n; u++)
+ {
+ FD_SET (dst->fds[u], rdset);
+ }
+#else
+ /* fds[0]/conns[0] not using for RTOS */
+ for (u = 1; u < dst->n; u++)
+ {
+ DDSRT_WARNING_GNUC_OFF(sign-conversion)
+ DDSRT_FD_SET (dst->fds[u], rdset);
+ DDSRT_WARNING_GNUC_ON(sign-conversion)
+ }
+#endif /* LWIP_SOCKET */
+
+ dds_return_t rc;
+ do
+ {
+ rc = ddsrt_select (fdmax, rdset, NULL, NULL, SELECT_TIMEOUT_MS);
+ if (rc < 0 && rc != DDS_RETCODE_INTERRUPTED && rc != DDS_RETCODE_TRY_AGAIN)
+ {
+ DDS_WARNING("os_sockWaitsetWait: select failed, retcode = %"PRId32, rc);
+ break;
+ }
+ } while (rc < 0);
+
+ if (rc > 0)
+ {
+ /* set start VALID conn index
+ * this simply skips the trigger fd, index0 is INV.
+ */
+ ctx->index = 1;
+
+ /* to confirm for DDSRT_WITH_FREERTOSTCP
+ TODO
+ TODO
+ TODO
+ TODO
+ TODO
+ TODO
+ */
+#if ! defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP)
+ if (FD_ISSET (dst->fds[0], rdset))
+ {
+ char buf;
+ int n1;
+ #if defined (_WIN32)
+ n1 = recv (dst->fds[0], &buf, 1, 0);
+ #else
+ n1 = (int) read (dst->fds[0], &buf, 1);
+ #endif
+ if (n1 != 1)
+ {
+ DDS_WARNING("os_sockWaitsetWait: read failed on trigger pipe\n");
+ assert (0);
+ }
+ }
+#endif /* LWIP_SOCKET */
+ return ctx;
+ }
+
+ return NULL;
+}
+
+int os_sockWaitsetNextEvent (os_sockWaitsetCtx ctx, ddsi_tran_conn_t * conn)
+{
+ while (ctx->index < ctx->set.n)
+ {
+ unsigned idx = ctx->index++;
+ ddsrt_socket_t fd = ctx->set.fds[idx];
+#if ! defined (LWIP_SOCKET) && ! defined(DDSRT_WITH_FREERTOSTCP)
+ assert(idx > 0);
+#endif
+
+ if (DDSRT_FD_ISSET (fd, ctx->rdset))
+ {
+ *conn = ctx->set.conns[idx];
+
+ return (int) (idx - 1);
+ }
+ }
+ return -1;
+}
+
+
diff --git a/src/core/ddsi/src/q_thread.c b/src/core/ddsi/src/q_thread.c
index 6de01fa1..3205bc74 100644
--- a/src/core/ddsi/src/q_thread.c
+++ b/src/core/ddsi/src/q_thread.c
@@ -109,7 +109,12 @@ void thread_states_init (unsigned maxthreads)
(not strictly required, but it'll get one eventually anyway, and this makes
it rather more clear). */
#ifndef NDEBUG
+#ifdef DDSRT_WITH_FREERTOSTCP
+ struct thread_state1 * const ts0 = (struct thread_state1 * const)ddsrt_thread_tls_get(DDS_TLS_IDX_STATE, tsd_thread_state);
+#else
struct thread_state1 * const ts0 = tsd_thread_state;
+#endif
+
#endif
struct thread_state1 * const ts1 = lookup_thread_state_real ();
assert (ts0 == NULL || ts0 == ts1);
@@ -124,7 +129,12 @@ bool thread_states_fini (void)
struct thread_state1 *ts1 = lookup_thread_state ();
assert (vtime_asleep_p (ddsrt_atomic_ld32 (&ts1->vtime)));
reap_thread_state (ts1, true);
+
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, NULL);
+ #else
tsd_thread_state = NULL;
+ #endif
/* Some applications threads that, at some point, required a thread state, may still be around.
Of those, the cleanup routine is invoked when the thread terminates. This should be rewritten
@@ -215,13 +225,22 @@ static struct thread_state1 *lazy_create_thread_state (ddsrt_thread_t self)
struct thread_state1 *lookup_thread_state_real (void)
{
+#ifdef DDSRT_WITH_FREERTOSTCP
+ struct thread_state1 *ts1 = (struct thread_state1 *)ddsrt_thread_tls_get(DDS_TLS_IDX_STATE, tsd_thread_state);
+#else
struct thread_state1 *ts1 = tsd_thread_state;
+#endif
+
if (ts1 == NULL)
{
ddsrt_thread_t self = ddsrt_thread_self ();
if ((ts1 = find_thread_state (self)) == NULL)
ts1 = lazy_create_thread_state (self);
+#ifdef DDSRT_WITH_FREERTOSTCP
+ ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, ts1);
+#else
tsd_thread_state = ts1;
+#endif
}
assert (ts1 != NULL);
return ts1;
@@ -232,9 +251,19 @@ static uint32_t create_thread_wrapper (void *ptr)
struct thread_state1 * const ts1 = ptr;
struct ddsi_domaingv const * const gv = ddsrt_atomic_ldvoidp (&ts1->gv);
if (gv)
- GVTRACE ("started new thread %"PRIdTID": %s\n", ddsrt_gettid (), ts1->name);
+ {
+ #ifndef DDSRT_WITH_FREERTOSTCP
+ GVTRACE ("started new thread %"PRIdTID": %s \n", ddsrt_gettid (), ts1->name);
+ #else
+ GVTRACE ("started new thread %"PRIdTID": %s, thread_t 0x%lx \n", ddsrt_gettid (), ts1->name, ts1->tid.task);
+ #endif
+ }
assert (ts1->state == THREAD_STATE_INIT);
+#ifdef DDSRT_WITH_FREERTOSTCP
+ ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, ts1);
+#else
tsd_thread_state = ts1;
+#endif
ddsrt_mutex_lock (&thread_states.lock);
ts1->state = THREAD_STATE_ALIVE;
ddsrt_mutex_unlock (&thread_states.lock);
@@ -242,7 +271,12 @@ static uint32_t create_thread_wrapper (void *ptr)
ddsrt_mutex_lock (&thread_states.lock);
ts1->state = THREAD_STATE_STOPPED;
ddsrt_mutex_unlock (&thread_states.lock);
+#ifdef DDSRT_WITH_FREERTOSTCP
+ ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, NULL);
+#else
tsd_thread_state = NULL;
+#endif
+
return ret;
}
diff --git a/src/core/ddsi/src/q_transmit.c b/src/core/ddsi/src/q_transmit.c
index 3e07fb55..b1bbd0d3 100644
--- a/src/core/ddsi/src/q_transmit.c
+++ b/src/core/ddsi/src/q_transmit.c
@@ -323,18 +323,32 @@ struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, const struct whc_
{
if (ddsrt_avl_is_empty (&wr->readers))
{
+#ifdef DDSRT_WITH_FREERTOSTCP
+ ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %u usec (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n",
+ PGUID (wr->e.guid),
+ *hbansreq ? "" : " final",
+ (hbc->tsched.v == DDS_NEVER) ? DDS_NEVER : ((hbc->tsched.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec
+#else
ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %g s (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n",
PGUID (wr->e.guid),
*hbansreq ? "" : " final",
(hbc->tsched.v == DDS_NEVER) ? INFINITY : (double) (hbc->tsched.v - tnow.v) / 1e9,
+#endif
whcst->max_seq, writer_read_seq_xmit(wr));
}
else
{
+#ifdef DDSRT_WITH_FREERTOSTCP
+ ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %u usec (min-ack %"PRIu64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n",
+ PGUID (wr->e.guid),
+ *hbansreq ? "" : " final",
+ (hbc->tsched.v == DDS_NEVER) ? DDS_NEVER : ((hbc->tsched.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec
+#else
ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %g s (min-ack %"PRIu64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n",
PGUID (wr->e.guid),
*hbansreq ? "" : " final",
(hbc->tsched.v == DDS_NEVER) ? INFINITY : (double) (hbc->tsched.v - tnow.v) / 1e9,
+#endif
root_rdmatch (wr)->min_seq,
root_rdmatch (wr)->all_have_replied_to_hb ? "" : "!",
whcst->max_seq, writer_read_seq_xmit(wr));
diff --git a/src/core/ddsi/src/q_xevent.c b/src/core/ddsi/src/q_xevent.c
index 62af2967..0b285405 100644
--- a/src/core/ddsi/src/q_xevent.c
+++ b/src/core/ddsi/src/q_xevent.c
@@ -531,14 +531,22 @@ struct xeventq * xeventq_new (struct ddsi_domaingv *gv, size_t max_queued_rexmit
dds_return_t xeventq_start (struct xeventq *evq, const char *name)
{
dds_return_t rc;
+#ifdef DDSRT_WITH_FREERTOSTCP
+ char * evqname = "dds_tev";
+#else
char * evqname = "tev";
+#endif
assert (evq->ts == NULL);
if (name)
{
size_t slen = strlen (name) + 5;
evqname = ddsrt_malloc (slen);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ (void) snprintf (evqname, slen, "dds_tev.%s", name);
+ #else
(void) snprintf (evqname, slen, "tev.%s", name);
+ #endif
}
evq->terminate = 0;
@@ -764,20 +772,36 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, ddsrt
if (ddsrt_avl_is_empty (&wr->readers))
{
- GVTRACE ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n",
+#ifdef DDSRT_WITH_FREERTOSTCP
+ GVINFO ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %u usec (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n",
+ PGUID (wr->e.guid),
+ hbansreq ? "" : " final",
+ msg ? "sent" : "suppressed",
+ (t_next.v == DDS_NEVER) ? DDS_NEVER : ((t_next.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec
+#else
+ GVINFO ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n",
PGUID (wr->e.guid),
hbansreq ? "" : " final",
msg ? "sent" : "suppressed",
(t_next.v == DDS_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9,
+#endif
whcst.max_seq, writer_read_seq_xmit (wr));
}
else
{
- GVTRACE ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n",
+#ifdef DDSRT_WITH_FREERTOSTCP
+ GVINFO("heartbeat(wr "PGUIDFMT"%s) %s, resched in %u usec (min-ack %"PRId64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n",
PGUID (wr->e.guid),
hbansreq ? "" : " final",
msg ? "sent" : "suppressed",
- (t_next.v == DDS_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9,
+ (t_next.v == DDS_NEVER) ? DDS_NEVER : ((t_next.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec
+#else
+ GVINFO("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n",
+ PGUID (wr->e.guid),
+ hbansreq ? "" : " final",
+ msg ? "sent" : "suppressed",
+ (t_next.v == DDS_NEVER) ? DDS_NEVER : (double)(t_next.v - tnow.v) / 1e9,
+#endif
((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->min_seq,
((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->all_have_replied_to_hb ? "" : "!",
whcst.max_seq, writer_read_seq_xmit (wr));
@@ -1028,10 +1052,18 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
else
{
ddsrt_mtime_t tnext = ddsrt_mtime_add_duration (tnow, DDS_SECS (1));
- GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n",
+#ifdef DDSRT_WITH_FREERTOSTCP
+ GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %u usec)\n",
+ PGUID (pp->e.guid),
+ PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER,
+ (tnext.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND) // usec
+ );
+#else
+ GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %g s)\n",
PGUID (pp->e.guid),
PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER,
(double)(tnext.v - tnow.v) / 1e9);
+#endif
(void) resched_xevent_if_earlier (ev, tnext);
}
}
@@ -1055,10 +1087,18 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e
intv = gv->config.spdp_interval;
tnext = ddsrt_mtime_add_duration (tnow, intv);
- GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n",
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %u usec)\n",
+ PGUID (pp->e.guid),
+ PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER,
+ (tnext.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND) // usec
+ );
+ #else
+ GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %g s)\n",
PGUID (pp->e.guid),
PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER,
(double)(tnext.v - tnow.v) / 1e9);
+ #endif
(void) resched_xevent_if_earlier (ev, tnext);
}
}
@@ -1091,7 +1131,13 @@ static void handle_xevk_pmd_update (struct thread_state1 * const ts1, struct nn_
tnext.v = tnow.v + intv - DDS_SECS (2);
else
tnext.v = tnow.v + 4 * intv / 5;
- GVTRACE ("resched pmd("PGUIDFMT"): %gs\n", PGUID (pp->e.guid), (double)(tnext.v - tnow.v) / 1e9);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ GVTRACE ("resched pmd("PGUIDFMT"): %u usec\n", PGUID (pp->e.guid),
+ (tnext.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND) // usec
+ );
+ #else
+ GVTRACE ("resched pmd("PGUIDFMT"): %g s\n", PGUID (pp->e.guid), (double)(tnext.v - tnow.v) / 1e9);
+ #endif
}
(void) resched_xevent_if_earlier (ev, tnext);
@@ -1127,6 +1173,12 @@ static void handle_individual_xevent (struct thread_state1 * const ts1, struct x
switch (xev->kind)
{
case XEVK_HEARTBEAT:
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ {
+ static uint32_t hb_cnt = 0U;
+ DDS_WARNING(" handle_xevk_heartbeat %u ... ", hb_cnt++);
+ }
+ #endif
handle_xevk_heartbeat (xp, xev, tnow);
break;
case XEVK_ACKNACK:
diff --git a/src/core/ddsi/src/q_xmsg.c b/src/core/ddsi/src/q_xmsg.c
index aa5bbc75..1cb12543 100644
--- a/src/core/ddsi/src/q_xmsg.c
+++ b/src/core/ddsi/src/q_xmsg.c
@@ -121,6 +121,7 @@ struct nn_xmsg {
#ifdef IOV_MAX
#if IOV_MAX > 0 && IOV_MAX < 256
+#error " you should not be here for DDSRT_WITH_FREERTOSTCP"
#define NN_XMSG_MAX_MESSAGE_IOVECS IOV_MAX
#endif
#endif /* defined IOV_MAX */
@@ -1248,7 +1249,15 @@ static ssize_t nn_xpack_send1 (const ddsi_xlocator_t *loc, void * varg)
}
/* Possible number of bytes written can be larger
* due to security. */
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ if (nbytes < len)
+ {
+ GVERROR (" sent len is NOT right! len %u v %u", len, nbytes);
+ assert (nbytes == -1 || (size_t) nbytes >= len);
+ }
+ #else
assert (nbytes == -1 || (size_t) nbytes >= len);
+ #endif
}
#endif
}
@@ -1718,7 +1727,7 @@ int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const uint32_t flag
const uint32_t max_msg_size = rexmit ? xp->gv->config.max_rexmit_msg_size : xp->gv->config.max_msg_size;
if (xpo_niov > 0 && sz > max_msg_size)
{
- GVTRACE (" => now niov %d sz %"PRIuSIZE" > max_msg_size %"PRIu32", nn_xpack_send niov %d sz %"PRIu32" now\n",
+ GVINFO (" => now niov %d sz %"PRIuSIZE" > max_msg_size %"PRIu32", nn_xpack_send niov %d sz %"PRIu32" now\n",
(int) niov, sz, max_msg_size, (int) xpo_niov, xpo_sz);
xp->msg_len.length = xpo_sz;
xp->niov = xpo_niov;
diff --git a/src/ddsrt/CMakeLists.txt b/src/ddsrt/CMakeLists.txt
index 01fdec45..2e357365 100644
--- a/src/ddsrt/CMakeLists.txt
+++ b/src/ddsrt/CMakeLists.txt
@@ -160,8 +160,10 @@ if(DDSRT_HAVE_GETADDRINFO OR DDSRT_HAVE_GETHOSTBYNAME_R)
set(DDSRT_HAVE_DNS TRUE)
endif()
check_type_size("struct sockaddr_in6" SIZEOF_SOCKADDR_IN6)
-if(SIZEOF_SOCKADDR_IN6)
- set(DDSRT_HAVE_IPV6 TRUE)
+if(ENABLE_IPV6)
+ if(SIZEOF_SOCKADDR_IN6)
+ set(DDSRT_HAVE_IPV6 TRUE)
+ endif()
endif()
if(WITH_FREERTOS)
diff --git a/src/ddsrt/include/dds/config.h.in b/src/ddsrt/include/dds/config.h.in
index 87493ab3..f33ed369 100644
--- a/src/ddsrt/include/dds/config.h.in
+++ b/src/ddsrt/include/dds/config.h.in
@@ -15,6 +15,17 @@
#cmakedefine DDSRT_WITH_LWIP 1
#cmakedefine DDSRT_WITH_FREERTOS 1
+/* begin: FreeRTOS_Plus_TCP IP stack */
+#cmakedefine DDSRT_WITH_FREERTOSTCP 1
+
+#cmakedefine DDSRT_TRANS_UDP 1
+#cmakedefine DDSRT_TRANS_TCP 1
+#cmakedefine DDSRT_TRANS_RAWETH 1
+#cmakedefine DDSRT_TRANS_NONE 1
+
+/* end: FreeRTOS_Plus_TCP IP stack */
+
+
#cmakedefine DDSRT_HAVE_DYNLIB 1
#cmakedefine DDSRT_HAVE_FILESYSTEM 1
#cmakedefine DDSRT_HAVE_NETSTAT 1
diff --git a/src/ddsrt/include/dds/ddsrt/iovec.h b/src/ddsrt/include/dds/ddsrt/iovec.h
index cbfa3514..3e9fe845 100644
--- a/src/ddsrt/include/dds/ddsrt/iovec.h
+++ b/src/ddsrt/include/dds/ddsrt/iovec.h
@@ -26,6 +26,15 @@ typedef unsigned long ddsrt_msg_iovlen_t;
#if DDSRT_WITH_LWIP
#include
+
+#elif defined DDSRT_WITH_FREERTOSTCP
+#warning "debug rtos tcp stack including "
+/* will implement struct io_vec in freertos_plus_tcp.h wrapper header. */
+
+struct iovec {
+ void *iov_base;
+ size_t iov_len;
+};
#else
#include
#include
@@ -36,6 +45,8 @@ typedef size_t ddsrt_iov_len_t;
#if defined(__linux) && !LWIP_SOCKET
typedef size_t ddsrt_msg_iovlen_t;
+#elif defined DDSRT_WITH_FREERTOSTCP
+typedef size_t ddsrt_msg_iovlen_t;
#else /* POSIX says int (which macOS, FreeBSD, Solaris do) */
typedef int ddsrt_msg_iovlen_t;
#endif
diff --git a/src/ddsrt/include/dds/ddsrt/log.h b/src/ddsrt/include/dds/ddsrt/log.h
index dabdacb8..cbe31492 100644
--- a/src/ddsrt/include/dds/ddsrt/log.h
+++ b/src/ddsrt/include/dds/ddsrt/log.h
@@ -24,6 +24,9 @@
#include
#include
+#include "dds/config.h"
+#include "dds/features.h"
+
#include "dds/export.h"
#include "dds/ddsrt/attributes.h"
@@ -87,8 +90,12 @@ extern "C" {
DDS_LC_CONTENT | DDS_LC_SHM)
/** @}*/
+#ifdef DDSRT_WITH_FREERTOSTCP
+#define DDS_LOG_MASK DDS_LC_ALL
+#else
#define DDS_LOG_MASK \
(DDS_LC_FATAL | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_INFO)
+#endif
#define DDS_TRACE_MASK \
(~DDS_LOG_MASK)
@@ -382,9 +389,15 @@ dds_log(
* passed just as easily, they are rejected so that tracing is kept entirely
* separate from logging, if only cosmetic.
*/
+#ifndef DDSRT_WITH_FREERTOSTCP
#define DDS_LOG(cat, ...) \
((dds_get_log_mask() & (cat)) ? \
dds_log((cat), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0)
+#else
+#define DDS_LOG(cat, fmt, ...) \
+ ((dds_get_log_mask() & (cat)) ? \
+ dds_log((cat), __FILE__, __LINE__, DDS_FUNCTION, fmt, ##__VA_ARGS__) : 0)
+#endif
/**
* @brief Write a log message with a domain id override.
@@ -398,10 +411,15 @@ dds_log(
* passed just as easily, they are rejected so that tracing is kept entirely
* separate from logging, if only cosmetic.
*/
+#ifndef DDSRT_WITH_FREERTOSTCP
#define DDS_ILOG(cat, domid, ...) \
((dds_get_log_mask() & (cat)) ? \
dds_log_id((cat), (domid), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0)
-
+#else
+#define DDS_ILOG(cat, domid, fmt, ...) \
+ ((dds_get_log_mask() & (cat)) ? \
+ dds_log_id((cat), (domid), __FILE__, __LINE__, DDS_FUNCTION, fmt " \n", ##__VA_ARGS__) : 0)
+#endif
/**
* @brief Write a log message using a specific config.
*
@@ -414,9 +432,15 @@ dds_log(
* passed just as easily, they are rejected so that tracing is kept entirely
* separate from logging, if only cosmetic.
*/
+#ifndef DDSRT_WITH_FREERTOSTCP
#define DDS_CLOG(cat, cfg, ...) \
(((cfg)->c.mask & (cat)) ? \
dds_log_cfg((cfg), (cat), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0)
+#else
+#define DDS_CLOG(cat, cfg, fmt, ...) \
+ (((cfg)->c.mask & (cat)) ? \
+ dds_log_cfg((cfg), (cat), __FILE__, __LINE__, DDS_FUNCTION, fmt "\n", ##__VA_ARGS__) : 0)
+#endif
/** Write a log message of type #DDS_LC_INFO into global log. */
#define DDS_INFO(...) \
@@ -428,8 +452,13 @@ dds_log(
#define DDS_ERROR(...) \
DDS_LOG(DDS_LC_ERROR, __VA_ARGS__)
/** Write a log message of type #DDS_LC_ERROR into global log and abort. */
+#ifndef DDSRT_WITH_FREERTOSTCP
#define DDS_FATAL(...) \
dds_log(DDS_LC_FATAL, __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__)
+#else
+#define DDS_FATAL(fmt, ...) \
+ dds_log(DDS_LC_FATAL, __FILE__, __LINE__, DDS_FUNCTION, fmt "\n", ##__VA_ARGS__)
+#endif
/* MSVC mishandles __VA_ARGS__ while claiming to be conforming -- and even
if they have a defensible implement, they still differ from every other
diff --git a/src/ddsrt/include/dds/ddsrt/process.h b/src/ddsrt/include/dds/ddsrt/process.h
index c074d084..84e75197 100644
--- a/src/ddsrt/include/dds/ddsrt/process.h
+++ b/src/ddsrt/include/dds/ddsrt/process.h
@@ -55,6 +55,18 @@ extern "C" {
DDS_EXPORT ddsrt_pid_t
ddsrt_getpid(void);
+/**
+ * @brief Return process name of the calling process.
+ *
+ * On linux maps to /proc/self/cmdline's first entry (argv[0]),
+ * on mac/windows maps to relevant API calls. Falls back to process-{pid}
+ * on failure.
+ *
+ * @returns The process name of the calling process.
+ */
+DDS_EXPORT char *
+ddsrt_getprocessname(void);
+
#if defined (__cplusplus)
}
#endif
diff --git a/src/ddsrt/include/dds/ddsrt/sockets.h b/src/ddsrt/include/dds/ddsrt/sockets.h
index 65b40ed5..4a911c67 100644
--- a/src/ddsrt/include/dds/ddsrt/sockets.h
+++ b/src/ddsrt/include/dds/ddsrt/sockets.h
@@ -10,10 +10,16 @@
#include "dds/ddsrt/retcode.h"
#include "dds/ddsrt/time.h"
#include "dds/ddsrt/misc.h"
-#if _WIN32
-#include "dds/ddsrt/sockets/windows.h"
+
+#if defined DDSRT_WITH_FREERTOSTCP
+ #warning " debug rtos tcp stack including "
+ #include "dds/ddsrt/sockets/freertos_plus_tcp.h"
#else
-#include "dds/ddsrt/sockets/posix.h"
+ #if _WIN32
+ #include "dds/ddsrt/sockets/windows.h"
+ #else
+ #include "dds/ddsrt/sockets/posix.h"
+ #endif
#endif
#if defined (__cplusplus)
@@ -187,9 +193,15 @@ ddsrt_setsockreuse(
DDS_EXPORT dds_return_t
ddsrt_select(
int32_t nfds,
+#ifdef DDSRT_WITH_FREERTOSTCP
+ ddsrt_fd_set_t readfds,
+ ddsrt_fd_set_t writefds,
+ ddsrt_fd_set_t errorfds,
+#else
fd_set *readfds,
fd_set *writefds,
fd_set *errorfds,
+#endif
dds_duration_t reltime);
#if _WIN32
diff --git a/src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h b/src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h
new file mode 100755
index 00000000..c2c01e22
--- /dev/null
+++ b/src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h
@@ -0,0 +1,245 @@
+/*
+ * INTEL CONFIDENTIAL
+ *
+ * Copyright (C) 2022 Intel Corporation
+ *
+ * This software and the related documents are Intel copyrighted materials,
+ * and your use of them is governed by the express license under which they
+ * were provided to you ("License"). Unless the License provides otherwise,
+ * you may not use, modify, copy, publish, distribute, disclose or transmit
+ * this software or the related documents without Intel's prior written permission.
+ * This software and the related documents are provided as is, with no express
+ * or implied warranties, other than those that are expressly
+ * stated in the License.
+ */
+
+#ifndef DDSRT_SOCKETS_FREERTOS_PLUS_TCP_H
+#define DDSRT_SOCKETS_FREERTOS_PLUS_TCP_H
+
+#define __need_size_t
+#include
+
+/* This operating system-specific header file defines the SOCK_*, PF_*,
+ AF_*, MSG_*, SOL_*, and SO_* constants, and the `struct sockaddr',
+ `struct msghdr', and `struct linger' types. */
+
+#include
+
+#include
+#include
+#include
+#include
+
+#include "dds/ddsrt/iovec.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#ifndef ntohl
+#define ntohl FreeRTOS_ntohl
+#define htol FreeRTOS_htonl
+
+#define htos FreeRTOS_htons
+#define ntohs FreeRTOS_ntohs
+#endif
+
+#define inet_addr FreeRTOS_inet_addr
+#define IN_MULTICAST(ip) (xIsIPv4Multicast(ntohl(ip)))
+
+
+/* posix data for FreeRTOS+TCP stack */
+#define DDSRT_HAVE_SSM 0
+#define IFF_UP 0x1
+#define IFF_BROADCAST 0x2
+#define IFF_LOOPBACK 0x8
+#define IFF_POINTOPOINT 0x10
+#define IFF_MULTICAST 0x1000
+
+struct msghdr
+{
+ void *msg_name;
+ socklen_t msg_namelen;
+ struct iovec *msg_iov;
+ int msg_iovlen;
+ void *msg_control;
+ socklen_t msg_controllen;
+ int msg_flags;
+};
+
+struct timeval
+{
+ long tv_sec; /* seconds */
+ long tv_usec; /* and microseconds */
+};
+
+typedef struct msghdr ddsrt_msghdr_t;
+#define DDSRT_MSGHDR_FLAGS 0
+
+
+/* adaption to ddsrt socket interface */
+typedef Socket_t ddsrt_socket_t; /* Socket_t ==> FreeRTOS_Socket_t* */
+// typedef SocketSelect_t fd_set; /* SocketSelect_t => struct xSOCKET_SET */
+typedef SocketSet_t ddsrt_fd_set_t;
+
+#define SELECT_TIMEOUT_MS 1000U /* 200U experienced value from XRCE-client */
+
+/*
+FD_ZERO() clears a set.
+FD_SET() and FD_CLR() respectively add and remove a given file descriptor from a set.
+FD_ISSET() tests to see if a file descriptor is part of the set; this is useful after select() returns.
+*/
+static inline void DDSRT_FD_ZERO(ddsrt_fd_set_t set)
+{
+ (void)set;
+}
+
+static ddsrt_fd_set_t DDSRT_FD_SET_CRATE(void)
+{
+ SocketSet_t set = FreeRTOS_CreateSocketSet();
+ assert(set);
+ return set;
+}
+
+static void DDSRT_FD_SET_DELETE(ddsrt_fd_set_t set)
+{
+ assert(set);
+ FreeRTOS_DeleteSocketSet(set);
+}
+
+/*
+#define DDSRT_FD_ISSET(fd, set) FreeRTOS_FD_ISSET(fd, set)
+#define DDSRT_FD_SET(fd, set) FreeRTOS_FD_SET(fd, set, eSELECT_READ | eSELECT_EXCEPT)
+#define DDSRT_FD_CLR(fd, set) FreeRTOS_FD_CLR(fd, set, eSELECT_ALL)
+*/
+
+static inline int32_t DDSRT_FD_ISSET(ddsrt_socket_t fd, ddsrt_fd_set_t set)
+{
+ return (int32_t)FreeRTOS_FD_ISSET(fd, set);
+}
+
+/* for FD_SET only be used in CDDS for rdset */
+static inline void DDSRT_FD_SET(ddsrt_socket_t fd, ddsrt_fd_set_t set)
+{
+ FreeRTOS_FD_SET(fd, set, eSELECT_READ | eSELECT_EXCEPT);
+}
+
+static inline void DDSRT_FD_CLR(ddsrt_socket_t fd, ddsrt_fd_set_t set)
+{
+ FreeRTOS_FD_CLR(fd, set, eSELECT_ALL);
+}
+
+#ifndef sa_family_t
+ typedef uint8_t sa_family_t;
+#endif
+
+ struct sockaddr_storage
+ {
+ uint8_t s2_len;
+ sa_family_t ss_family;
+ char s2_data1[2];
+ uint32_t s2_data2[3];
+ };
+
+#if 1
+ /* for posix compatible sa_family reference inside DDS
+ * we declare sockaddr a new struct but same W/ freertos_sockaddr
+ */
+ struct sockaddr
+ {
+ uint8_t sa_len;
+ sa_family_t sa_family;
+ uint16_t sin_port;
+ uint32_t sin_addr;
+ };
+#else
+#define sockaddr freertos_sockaddr
+#endif
+
+#define sockaddr_in freertos_sockaddr
+typedef uint32_t in_addr_t; /* base type for internet address */
+
+/*
+ * Options and types related to multicast membership
+ */
+#define IP_ADD_MEMBERSHIP 3
+#define IP_DROP_MEMBERSHIP 4
+ typedef struct ip_mreq
+ {
+ in_addr_t imr_multiaddr; /* IP multicast address of group */
+ in_addr_t imr_interface; /* local IP address of interface */
+ } ip_mreq;
+ // end multicast
+
+#define IP_MULTICAST_TTL 5
+#define IP_MULTICAST_IF 6
+#define IP_MULTICAST_LOOP 7
+
+/** 255.255.255.255 */
+#define INADDR_NONE ((uint32_t)0xffffffffUL)
+/** 127.0.0.1 */
+#define INADDR_LOOPBACK ((uint32_t)0x7f000000UL)
+/** 0.0.0.0 */
+#define INADDR_ANY ((uint32_t)0x00000000UL)
+/** 255.255.255.255 */
+#define INADDR_BROADCAST ((uint32_t)0xffffffffUL)
+
+#define AF_INET FREERTOS_AF_INET
+#define AF_INET6 FREERTOS_AF_INET6
+
+#define IPPROTO_IP 0
+#define IPPROTO_ICMP ipPROTOCOL_ICMP
+
+#define SOCK_DGRAM FREERTOS_SOCK_DGRAM
+#define IPPROTO_UDP FREERTOS_IPPROTO_UDP
+
+#define SOCK_STREAM FREERTOS_SOCK_STREAM
+#define IPPROTO_TCP FREERTOS_IPPROTO_TCP
+
+#define SOL_SOCKET IPPROTO_IP /* set socket level, always 0 for RTOS */
+
+#define SO_REUSEADDR FREERTOS_SO_REUSE_LISTEN_SOCKET
+#define SO_RCVTIMEO FREERTOS_SO_RCVTIMEO
+#define SO_SNDTIMEO FREERTOS_SO_SNDTIMEO
+#define SO_SNDBUF FREERTOS_SO_SNDBUF
+#define SO_RCVBUF FREERTOS_SO_RCVBUF
+
+#define SO_OOB FREERTOS_MSG_OOB
+#define SO_PEEK FREERTOS_MSG_PEEK
+#define SO_DONTROUTE FREERTOS_MSG_DONTROUTE
+#define SO_DONTWAIT FREERTOS_MSG_DONTWAIT
+
+/*
+ FreeRTOS_accept() has an optional timeout. The timeout defaults
+ to ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME, and is modified
+ using the FREERTOS_SO_RCVTIMEO parameter in a call to FreeRTOS_setsockopt()
+
+ If a timeout occurs before a connection from a remote socket
+ is accepted then NULL is returned.
+*/
+#define ACCEPT_TIMEOUT (NULL) // accpet timeout
+#define INVALID_SOCKET (FREERTOS_INVALID_SOCKET)
+
+/* The following constants should be used for the second parameter of
+ `shutdown'. */
+#define SHUT_RD FREERTOS_SHUT_RD
+#define SHUT_WR FREERTOS_SHUT_WR
+#define SHUT_RDWR FREERTOS_SHUT_RDWR
+
+
+#define DDSRT_INVALID_SOCKET (INVALID_SOCKET)
+#define PRIdSOCK PRIxPTR
+
+// #define errno FreeRTOS_errno
+#define DDSRT_RET_OK (0)
+
+#ifndef FD_SETSIZE
+#define FD_SETSIZE 8
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/src/ddsrt/include/dds/ddsrt/sockets/posix.h b/src/ddsrt/include/dds/ddsrt/sockets/posix.h
index e48cc0c2..2c232415 100644
--- a/src/ddsrt/include/dds/ddsrt/sockets/posix.h
+++ b/src/ddsrt/include/dds/ddsrt/sockets/posix.h
@@ -31,6 +31,13 @@ extern "C" {
#endif
typedef int ddsrt_socket_t;
+
+#ifdef DDSRT_WITH_FREERTOSTCP
+typedef fd_set* ddsrt_fd_set_t; /* compatible with FreeRTOS +TCP */
+#define SELECT_TIMEOUT_MS DDS_INFINITY
+#endif
+
+
#define DDSRT_INVALID_SOCKET (-1)
#define PRIdSOCK "d"
diff --git a/src/ddsrt/include/dds/ddsrt/threads.h b/src/ddsrt/include/dds/ddsrt/threads.h
index 6341bf7a..46ac58fb 100644
--- a/src/ddsrt/include/dds/ddsrt/threads.h
+++ b/src/ddsrt/include/dds/ddsrt/threads.h
@@ -49,7 +49,13 @@ extern "C" {
supports Thread-local storage since version 2.0. */
/* VxWorks 7 supports __thread for both GCC and DIAB, older versions may
support it as well, but that is not verified. */
+
+#ifdef DDSRT_WITH_FREERTOSTCP
+#define ddsrt_thread_local
+#else
#define ddsrt_thread_local __thread
+#endif
+
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
#define ddsrt_thread_local __thread
#else
@@ -73,6 +79,32 @@ typedef struct {
uint32_t stackSize;
} ddsrt_threadattr_t;
+
+#ifdef DDSRT_WITH_FREERTOS
+#if configNUM_THREAD_LOCAL_STORAGE_POINTERS <= 0
+#error " Error, FreeRTOS THREAD_LOCAL_STORAGE support NOT enabled!"
+#endif
+
+/*
+add configNUM_THREAD_LOCAL_STORAGE_POINTERS for DDS usage
+ 22 taskguard and FATfs reserved 0~3
+*/
+#define DDS_TLS_IDX_LOGBUFF 4
+#define DDS_TLS_IDX_FREE 5
+#define DDS_TLS_IDX_STATE 6
+#define DDS_TLS_IDX_CTX 7
+
+#define ddsrt_thread_tls_set(d, idx, s) \
+ vTaskSetThreadLocalStoragePointer(NULL, idx, (void*)s)
+
+#define ddsrt_thread_tls_get(idx, s) \
+ pvTaskGetThreadLocalStoragePointer(NULL, idx)
+#else
+#error
+#define ddsrt_thread_tls_set(d, idx, s) (d) = (s)
+#define ddsrt_thread_tls_get(idx, s) (s)
+#endif
+
/**
* @brief Initialize thread attributes to platform defaults.
*/
diff --git a/src/ddsrt/src/cdtors.c b/src/ddsrt/src/cdtors.c
index 5ceca0a8..ad49ab2e 100644
--- a/src/ddsrt/src/cdtors.c
+++ b/src/ddsrt/src/cdtors.c
@@ -165,6 +165,19 @@ DDSRT_WARNING_CLANG_ON(missing-prototypes)
#pragma data_seg()
#endif
#else /* _WIN32 */
+
+#ifdef DDSRT_WITH_FREERTOSTCP
+void ddsrt_ctor(void)
+{
+ ddsrt_init();
+}
+
+void ddsrt_dtor(void)
+{
+ ddsrt_fini();
+}
+
+#else
void __attribute__((constructor)) ddsrt_ctor(void);
void __attribute__((destructor)) ddsrt_dtor(void);
@@ -177,5 +190,8 @@ void __attribute__((destructor)) ddsrt_dtor(void)
{
ddsrt_fini();
}
+
+#endif
+
#endif /* _WIN32 */
diff --git a/src/ddsrt/src/heap/freertos/heap.c b/src/ddsrt/src/heap/freertos/heap.c
index ffb3d0fb..89d448bc 100644
--- a/src/ddsrt/src/heap/freertos/heap.c
+++ b/src/ddsrt/src/heap/freertos/heap.c
@@ -10,6 +10,7 @@
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include
+#include
#if defined(configSUPPORT_DYNAMIC_ALLOCATION) && \
(configSUPPORT_DYNAMIC_ALLOCATION == 0)
diff --git a/src/ddsrt/src/ifaddrs.c b/src/ddsrt/src/ifaddrs.c
index d50a2e40..8114780d 100644
--- a/src/ddsrt/src/ifaddrs.c
+++ b/src/ddsrt/src/ifaddrs.c
@@ -19,7 +19,9 @@ ddsrt_freeifaddrs(ddsrt_ifaddrs_t *ifa)
while (ifa != NULL) {
next = ifa->next;
+ #ifndef DDSRT_WITH_FREERTOSTCP
ddsrt_free(ifa->name);
+ #endif
ddsrt_free(ifa->addr);
ddsrt_free(ifa->netmask);
ddsrt_free(ifa->broadaddr);
diff --git a/src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c b/src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c
new file mode 100755
index 00000000..52c17792
--- /dev/null
+++ b/src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c
@@ -0,0 +1,110 @@
+
+#include
+#include
+
+#include "dds/ddsrt/log.h"
+#include "dds/ddsrt/misc.h"
+#include "sockets_priv.h"
+
+#include "dds/ddsrt/heap.h"
+#include "dds/ddsrt/io.h"
+#include "dds/ddsrt/ifaddrs.h"
+#include "dds/ddsrt/retcode.h"
+#include "dds/ddsrt/string.h"
+
+extern const int *const os_supp_afs;
+
+
+static dds_return_t copyaddr(ddsrt_ifaddrs_t **ifap)
+{
+ dds_return_t rc = DDS_RETCODE_OK;
+ ddsrt_ifaddrs_t *ifa;
+ struct sockaddr sa = {0U};
+
+ assert(ifap != NULL);
+
+ /* note: local IP shoule be got after STACK up! */
+ u32 lip, netmask, bcip;
+ bcip = ipBROADCAST_IP_ADDRESS;
+ FreeRTOS_GetAddressConfiguration(&lip, &netmask, NULL, NULL);
+
+ ifa = ddsrt_calloc(1, sizeof(*ifa));
+ if(ifa == NULL)
+ {
+ rc = DDS_RETCODE_OUT_OF_RESOURCES;
+ goto __exit;
+ }
+
+ ifa->addr = ddsrt_calloc(1, sizeof(struct sockaddr));
+ ifa->netmask = ddsrt_calloc(1, sizeof(struct sockaddr));
+ ifa->broadaddr = ddsrt_calloc(1, sizeof(struct sockaddr));
+ if ((ifa->addr == NULL)
+ || (ifa->netmask == NULL)
+ || (ifa->broadaddr == NULL))
+ {
+ rc = DDS_RETCODE_OUT_OF_RESOURCES;
+ goto __exit;
+ }
+
+ sa.sa_len = sizeof(struct sockaddr);
+ sa.sa_family = AF_INET;
+ sa.sin_addr = (lip); /* storage IP, no need. FreeRTOS_htonl */
+ memcpy((void*)ifa->addr, &sa, sizeof(struct sockaddr));
+
+ sa.sin_addr = (netmask);
+ memcpy((void*)ifa->netmask, &sa, sizeof(struct sockaddr));
+
+ sa.sin_addr = (bcip);
+ memcpy((void*)ifa->broadaddr, &sa, sizeof(struct sockaddr));
+
+ ifa->next = NULL;
+ ifa->type = DDSRT_IFTYPE_WIRED;
+ ifa->name = "eqos0";
+ ifa->index = 0;
+ ifa->flags = IFF_UP | IFF_BROADCAST; // | IFF_MULTICAST;
+
+__exit:
+ if (rc == DDS_RETCODE_OK)
+ {
+ *ifap = ifa;
+ }
+ else
+ {
+ ddsrt_freeifaddrs(ifa);
+ *ifap = NULL;
+ }
+
+ return rc;
+}
+
+dds_return_t ddsrt_getifaddrs(ddsrt_ifaddrs_t **ifap, const int *afs)
+{
+ dds_return_t rc = DDS_RETCODE_OK;
+ int use_ip4 = 0;
+ int use_ip6 = 0;
+
+ assert(ifap != NULL);
+
+ if (afs == NULL)
+ {
+ afs = os_supp_afs;
+ }
+
+ for (int i = 0; afs[i] != DDSRT_AF_TERM; i++)
+ {
+ if (afs[i] == AF_INET)
+ {
+ use_ip4 = 1;
+ }
+#ifdef DDSRT_HAVE_IPV6
+ else if (afs[i] == AF_INET6)
+ {
+ use_ip6 = 1;
+ }
+#endif
+ }
+
+ rc = copyaddr(ifap);
+
+ return rc;
+}
diff --git a/src/ddsrt/src/log.c b/src/ddsrt/src/log.c
index a291c0ca..33d3f29e 100644
--- a/src/ddsrt/src/log.c
+++ b/src/ddsrt/src/log.c
@@ -38,7 +38,9 @@ typedef struct {
FILE *out;
} log_sink_t;
+#ifndef DDSRT_WITH_FREERTOS
static ddsrt_thread_local log_buffer_t log_buffer;
+#endif
static ddsrt_once_t lock_inited = DDSRT_ONCE_INIT;
static ddsrt_rwlock_t lock;
@@ -50,13 +52,82 @@ struct ddsrt_log_cfg_impl {
DDSRT_STATIC_ASSERT (sizeof (struct ddsrt_log_cfg_impl) <= sizeof (struct ddsrt_log_cfg));
+static const uint8_t * ddslstr[] = {
+ "DDS_LC_FATAL",
+ "DDS_LC_ERROR",
+ "DDS_LC_WARNING",
+ "DDS_LC_INFO",
+ "DDS_LC_CONFIG",
+ "DDS_LC_DISCOVERY",
+ "DDS_LC_DATA",
+ "DDS_LC_TRACE",
+ "DDS_LC_RADMIN",
+ "DDS_LC_TIMING",
+ "DDS_LC_TRAFFIC",
+ "DDS_LC_TOPIC",
+ "DDS_LC_TCP",
+ "DDS_LC_PLIST",
+ "DDS_LC_WHC",
+ "DDS_LC_THROTTLE",
+ "DDS_LC_RHC",
+ "DDS_LC_CONTENT",
+ "DDS_LC_SHM",
+ };
+
static void default_sink (void *ptr, const dds_log_data_t *data)
{
+ #ifdef DDSRT_WITH_FREERTOSTCP
+
+ (void)ptr;
+ uint32_t lv;
+
+ uint32_t i;
+ for (i = 0U; i < sizeof(int) * 8U; i++)
+ {
+ if (data->priority <= (1U << i))
+ { break; }
+ }
+
+ switch (data->priority)
+ {
+ case DDS_LC_FATAL:
+ case DDS_LC_ERROR:
+ lv = IPLOG_LEVEL_ERROR;
+ pr_error("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line);
+ break;
+ case DDS_LC_WARNING:
+ lv = IPLOG_LEVEL_WARN;
+ pr_warn("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line);
+ break;
+ case DDS_LC_CONFIG:
+ case DDS_LC_INFO:
+ lv = IPLOG_LEVEL_INFO;
+ pr_info("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line);
+ break;
+ case DDS_LC_TRACE:
+ lv = IPLOG_LEVEL_DEBUG;
+ pr_debug("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line);
+ break;
+
+ case DDS_LC_DISCOVERY:
+ lv = IPLOG_LEVEL_DEBUG;
+ pr_debug("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line);
+ break;
+
+ default:
+ lv = IPLOG_LEVEL_DEBUG;
+ pr_debug("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line);
+ break;
+ }
+ //net_log_print(lv, "[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line);
+
+ #else
if (ptr)
{
(void) fwrite (data->message - data->hdrsize, 1, data->hdrsize + data->size + 1, (FILE *) ptr);
fflush ((FILE *) ptr);
}
+ #endif
}
#define LOG (0)
@@ -64,7 +135,14 @@ static void default_sink (void *ptr, const dds_log_data_t *data)
static struct ddsrt_log_cfg_impl logconfig = {
.c = {
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ .mask = DDS_LC_ALL
+ | DDS_LC_DISCOVERY | DDS_LC_TOPIC
+ | DDS_LC_CONFIG | DDS_LC_INFO | DDS_LC_WARNING
+ | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_FATAL,
+ #else
.mask = DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_FATAL,
+ #endif
.tracemask = 0,
.domid = UINT32_MAX
},
@@ -172,8 +250,19 @@ static size_t print_header (char *str, uint32_t id)
{
int cnt, off;
char *tid, buf[MAX_TID_LEN+1] = { 0 };
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ /*
+ * for RTOS, printf might not support all format output,
+ * so add explict len other that this STDIO tricks
+ * printf("%.*s", 10, str) - output str with cutoff or prefix padding to 10 chars.
+ */
+ static const char fmt_no_id[] = "%06u.%06d [] %.10s:";
+ static const char fmt_with_id[] = "%06u.%06d [%"PRIu32"] %.10s:";
+ // snprintf (str + off, HDR_LEN - off, fmt_no_id, sec, usec, tid);
+ #else
static const char fmt_no_id[] = "%10u.%06d [] %*.*s:";
static const char fmt_with_id[] = "%10u.%06d [%"PRIu32"] %*.*s:";
+ #endif
dds_time_t time;
unsigned sec;
int usec;
@@ -187,18 +276,44 @@ static size_t print_header (char *str, uint32_t id)
if (id == UINT32_MAX)
{
off = MAX_ID_LEN;
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ /* fix bug, HDR might overwrite log buffer set before.
+ HDR_LEN - off
+ //snprintf (str + off, HDR_LEN, "%10u.%06d [] %*.*s:", sec, usec, MAX_TID_LEN, MAX_TID_LEN, tid)
+ */
+ cnt = snprintf (str + off, HDR_LEN - off, fmt_no_id, sec, usec,
+ tid);
+ #else
cnt = snprintf (str + off, HDR_LEN, fmt_no_id, sec, usec, MAX_TID_LEN, MAX_TID_LEN, tid);
+ #endif
}
else
{
/* low domain ids tend to be most used from what I have seen */
off = 9;
if (id >= 10)
- for (uint32_t thres = 10; off > 0 && id >= thres; off--, thres *= 10);
+ { for (uint32_t thres = 10; off > 0 && id >= thres; off--, thres *= 10); }
+
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ cnt = snprintf (str + off, HDR_LEN - off, fmt_with_id, sec, usec, id, tid);
+ #else
cnt = snprintf (str + off, HDR_LEN, fmt_with_id, sec, usec, id, MAX_TID_LEN, MAX_TID_LEN, tid);
+ #endif
}
+#ifdef DDSRT_WITH_FREERTOSTCP
+ /* fix CycloneDDS bug
+ * for RTOS printf might not support all STDIO format. "%.*s"
+ */
+ assert (off + cnt < HDR_LEN);
+ for (int i = off + cnt; i < HDR_LEN; i++)
+ {
+ str[i] = ' '; /* Replace snprintf null byte by space. */
+ }
+#else
assert (off + cnt == (HDR_LEN - 1));
str[off + cnt] = ' '; /* Replace snprintf null byte by space. */
+#endif
+
return (size_t) (cnt + 1);
}
@@ -209,6 +324,10 @@ static void vlog1 (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t
log_buffer_t *lb;
dds_log_data_t data;
+ #ifdef DDSRT_WITH_FREERTOS
+ log_buffer_t log_buffer = {0};
+ #endif
+
/* id can be used to override the id in logconfig, so that the global
logging configuration can be used for reporting errors while inlcuding
a domain id. This simply verifies that the id override is only ever
diff --git a/src/ddsrt/src/process/freertos/process.c b/src/ddsrt/src/process/freertos/process.c
index b2998885..360d499d 100644
--- a/src/ddsrt/src/process/freertos/process.c
+++ b/src/ddsrt/src/process/freertos/process.c
@@ -20,3 +20,8 @@ ddsrt_getpid(void)
return xTaskGetCurrentTaskHandle();
}
+char *
+ddsrt_getprocessname(void)
+{
+ return pcTaskGetName(xTaskGetCurrentTaskHandle());
+}
diff --git a/src/ddsrt/src/sockets.c b/src/ddsrt/src/sockets.c
index 364be9a8..08bfd800 100644
--- a/src/ddsrt/src/sockets.c
+++ b/src/ddsrt/src/sockets.c
@@ -19,6 +19,9 @@
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/log.h"
+#ifdef DDSRT_WITH_FREERTOSTCP
+# warning " *** FreeRTOS-Plus-TCP debug include tree "
+#else
#if !LWIP_SOCKET
# if !defined(_WIN32)
# include
@@ -29,6 +32,7 @@
# endif /* __linux */
# endif /* _WIN32 */
#endif /* LWIP_SOCKET */
+#endif /* FreeRTOSTCP */
#if defined __APPLE__
#include
@@ -119,7 +123,11 @@ ddsrt_sockaddr_isunspecified(const struct sockaddr *__restrict sa)
return IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6*)sa)->sin6_addr);
#endif
case AF_INET:
- return (((struct sockaddr_in *)sa)->sin_addr.s_addr == 0);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ return (((struct sockaddr_in *)sa)->sin_addr == 0);
+ #else
+ return (((struct sockaddr_in *)sa)->sin_addr.s_addr == 0);
+ #endif
}
return false;
@@ -137,8 +145,12 @@ ddsrt_sockaddr_isloopback(const struct sockaddr *__restrict sa)
&((const struct sockaddr_in6 *)sa)->sin6_addr);
#endif /* DDSRT_HAVE_IPV6 */
case AF_INET:
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ return (((const struct sockaddr_in *)sa)->sin_addr == htonl(INADDR_LOOPBACK));
+ #else
return (((const struct sockaddr_in *)sa)->sin_addr.s_addr
== htonl(INADDR_LOOPBACK));
+ #endif
}
return false;
@@ -160,11 +172,19 @@ ddsrt_sockaddr_insamesubnet(
switch (sa1->sa_family) {
case AF_INET: {
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ eq = ((((struct sockaddr_in *)sa1)->sin_addr &
+ ((struct sockaddr_in *)mask)->sin_addr)
+ ==
+ (((struct sockaddr_in *)sa2)->sin_addr &
+ ((struct sockaddr_in *)mask)->sin_addr));
+ #else
eq = ((((struct sockaddr_in *)sa1)->sin_addr.s_addr &
((struct sockaddr_in *)mask)->sin_addr.s_addr)
==
(((struct sockaddr_in *)sa2)->sin_addr.s_addr &
((struct sockaddr_in *)mask)->sin_addr.s_addr));
+ #endif
} break;
#if DDSRT_HAVE_IPV6
case AF_INET6: {
@@ -196,14 +216,24 @@ ddsrt_sockaddrfromstr(int af, const char *str, void *sa)
switch (af) {
case AF_INET: {
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ in_addr_t buf;
+ #else
struct in_addr buf;
+ #endif
#if DDSRT_HAVE_INET_PTON
if (inet_pton(af, str, &buf) != 1) {
return DDS_RETCODE_BAD_PARAMETER;
}
#else
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ buf = inet_addr (str);
+ if (buf == (in_addr_t)(-1))
+ #else
buf.s_addr = inet_addr (str);
- if (buf.s_addr == (in_addr_t)-1) {
+ if (buf.s_addr == (in_addr_t)(-1))
+ #endif
+ {
return DDS_RETCODE_BAD_PARAMETER;
}
#endif
@@ -247,7 +277,11 @@ DDSRT_WARNING_GNUC_OFF(sign-conversion)
AF_INET, &((struct sockaddr_in *)sa)->sin_addr, buf, (uint32_t)size);
#else
{
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ in_addr_t x = ntohl(((struct sockaddr_in *)sa)->sin_addr);
+ #else
in_addr_t x = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
+ #endif
snprintf(buf,size,"%u.%u.%u.%u",(x>>24),(x>>16)&0xff,(x>>8)&0xff,x&0xff);
ptr = buf;
}
diff --git a/src/ddsrt/src/threads/freertos/threads.c b/src/ddsrt/src/threads/freertos/threads.c
index 206d7d62..9f3be999 100644
--- a/src/ddsrt/src/threads/freertos/threads.c
+++ b/src/ddsrt/src/threads/freertos/threads.c
@@ -183,7 +183,11 @@ static dds_return_t
thread_context_acquire(thread_context_t **ctxptr)
{
dds_return_t rc = DDS_RETCODE_OK;
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ thread_context_t *ctx = (thread_context_t *)ddsrt_thread_tls_get(DDS_TLS_IDX_CTX, thread_context);
+ #else
thread_context_t *ctx = thread_context;
+ #endif
if (ctx == NULL) {
/* Dynamically initialize global thread registry (exactly once). */
@@ -199,7 +203,11 @@ thread_context_acquire(thread_context_t **ctxptr)
ctx->task = xTaskGetCurrentTaskHandle();
}
ddsrt_mutex_unlock(&thread_registry.mutex);
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ ddsrt_thread_tls_set(thread_context, DDS_TLS_IDX_CTX, ctx);
+ #else
thread_context = ctx;
+ #endif
} else {
assert(ctx->func != NULL);
assert(ctx->stat == THREAD_RUNNING);
@@ -326,7 +334,11 @@ thread_start_routine(void *arg)
thread because a reference to the thread's context is stored and
synchronization is considerably easier if it's handled there. */
+#ifdef DDSRT_WITH_FREERTOSTCP
+ ddsrt_thread_tls_set(thread_context, DDS_TLS_IDX_CTX, ctx);
+#else
thread_context = ctx;
+#endif
ret = ctx->func(ctx->arg);
thread_fini(ctx, ret); /* DO NOT DEREFERENCE THREAD CONTEXT ANYMORE! */
@@ -427,6 +439,10 @@ void
ddsrt_thread_init(uint32_t reason)
{
(void)reason;
+#ifdef DDSRT_WITH_FREERTOSTCP
+ /* init TLS var */
+ ddsrt_thread_tls_set(thread_context, DDS_TLS_IDX_CTX, NULL);
+#endif
if (thread_context_require() != DDS_RETCODE_OK) {
assert(0);
}
@@ -440,7 +456,12 @@ ddsrt_thread_fini(uint32_t reason)
(void)reason;
/* NO-OP if no context exists since thread-local storage and cleanup
handler references are both stored in the thread context. */
+ #ifdef DDSRT_WITH_FREERTOSTCP
+ ctx = (thread_context_t *)ddsrt_thread_tls_get(DDS_TLS_IDX_CTX, thread_context);
+ if ( ctx != NULL) {
+ #else
if ((ctx = thread_context) != NULL) {
+ #endif
assert(ctx->func != &non_local_thread);
thread_fini(ctx, 0);
}
diff --git a/src/ddsrt/src/time.c b/src/ddsrt/src/time.c
index 9551f0dd..64945fcc 100644
--- a/src/ddsrt/src/time.c
+++ b/src/ddsrt/src/time.c
@@ -38,6 +38,8 @@ void dds_sleepfor(dds_duration_t n)
}
#endif
+#ifndef DDSRT_WITH_FREERTOS
+#warning " ctime in glib, ignore it for FreeRTOS "
size_t
ddsrt_ctime(dds_time_t n, char *str, size_t size)
{
@@ -73,6 +75,7 @@ ddsrt_ctime(dds_time_t n, char *str, size_t size)
return ddsrt_strlcpy(str, buf, size);
}
+#endif
static void time_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, int64_t t)
{
diff --git a/src/ddsrt/src/time/freertos/time.c b/src/ddsrt/src/time/freertos/time.c
index 01c367bb..e1e5d5a9 100644
--- a/src/ddsrt/src/time/freertos/time.c
+++ b/src/ddsrt/src/time/freertos/time.c
@@ -20,6 +20,9 @@ DDS_EXPORT extern inline TickType_t ddsrt_duration_to_ticks_ceil(dds_duration_t
dds_time_t dds_time(void)
{
+#ifdef DDSRT_WITH_FREERTOSTCP
+ return get_timer_us(0U) * 1000U;
+#else
struct timespec ts;
#if __STDC_VERSION__ >= 201112L
@@ -29,6 +32,7 @@ dds_time_t dds_time(void)
#endif
return (ts.tv_sec * DDS_NSECS_IN_SEC) + ts.tv_nsec;
+#endif
}
#define NSECS_PER_TICK (DDS_NSECS_IN_SEC / configTICK_RATE_HZ)
diff --git a/src/idl/include/idl/processor.h b/src/idl/include/idl/processor.h
index 4e23085a..b27a21eb 100644
--- a/src/idl/include/idl/processor.h
+++ b/src/idl/include/idl/processor.h
@@ -78,6 +78,7 @@ struct idl_pstate {
struct {
uint32_t flags; /**< processor options */
int default_extensibility; /**< default extensibility for aggregated types */
+ bool default_nested; /**< default nestedness for aggregated types */
const idl_warning_t *disable_warnings; /**< list of warning that will be suppressed */
size_t n_disable_warnings; /**< number of items in disable_warnings */
} config;
diff --git a/src/idl/src/processor.c b/src/idl/src/processor.c
index 216decd3..2d5e83d0 100644
--- a/src/idl/src/processor.c
+++ b/src/idl/src/processor.c
@@ -156,6 +156,7 @@ idl_create_pstate(
pstate->config.flags = flags;
pstate->config.default_extensibility = IDL_DEFAULT_EXTENSIBILITY_UNDEFINED;
+ pstate->config.default_nested = false;
pstate->global_scope = pstate->scope = scope;
if (pstate->config.flags & IDL_FLAG_ANNOTATIONS) {
@@ -476,6 +477,31 @@ static idl_retcode_t validate_bitbound(idl_pstate_t *pstate)
return idl_visit(pstate, pstate->root, &visitor, NULL);
}
+static void
+set_nestedness(
+ const idl_pstate_t* pstate,
+ void* node,
+ bool current_fallback)
+{
+ IDL_FOREACH(node, node) {
+ if (idl_is_module(node)) {
+ idl_module_t *mod = node;
+ if (!mod->default_nested.annotation)
+ mod->default_nested.value = current_fallback;
+ else
+ current_fallback = mod->default_nested.value;
+
+ IDL_FOREACH(node, mod->definitions) {
+ set_nestedness(pstate, node, current_fallback);
+ }
+ } else if (idl_is_union(node) && !((idl_union_t*)node)->nested.annotation) {
+ ((idl_union_t*)node)->nested.value = current_fallback;
+ } else if (idl_is_struct(node) && !((idl_struct_t*)node)->nested.annotation) {
+ ((idl_struct_t*)node)->nested.value = current_fallback;
+ }
+ }
+}
+
static idl_retcode_t set_type_extensibility(idl_pstate_t *pstate)
{
if (pstate->config.default_extensibility == IDL_DEFAULT_EXTENSIBILITY_UNDEFINED && idl_has_unset_extensibility_r(pstate->root)) {
@@ -563,6 +589,8 @@ idl_retcode_t idl_parse(idl_pstate_t *pstate)
if ((ret = idl_set_xcdr2_required(pstate->root) != IDL_RETCODE_OK))
goto err;
+ set_nestedness(pstate, pstate->root, pstate->config.default_nested);
+
if (pstate->keylists) {
if ((ret = idl_validate_keylists(pstate)) != IDL_RETCODE_OK)
goto err;
diff --git a/src/idl/tests/annotation.c b/src/idl/tests/annotation.c
index 6a9d26a7..1c6505e7 100644
--- a/src/idl/tests/annotation.c
+++ b/src/idl/tests/annotation.c
@@ -432,12 +432,18 @@ CU_Test(idl_annotation, default_nested)
const char *str;
struct { bool a; bool v; } dn[3];
struct { bool a; bool v; } n[2];
+ bool pstate_default_nested;
} tests[] = {
- { M("m1", M("m2", S("s1")) M("m3", S("s2"))), {{0,0},{0,0},{0,0}}, {{0,0},{0,0}} },
- { DN() M("m1", M("m2", S("s1")) M("m3", S("s2"))), {{1,1},{0,1},{0,1}}, {{0,1},{0,1}} },
- { DN() M("m1", DN(NO) M("m2", S("s1")) M("m3", S("s2"))), {{1,1},{1,0},{0,1}}, {{0,0},{0,1}} },
- { DN(NO) M("m1", DN(YES) M("m2", S("s1")) M("m3", S("s2"))), {{1,0},{1,1},{0,0}}, {{0,1},{0,0}} },
- { DN(YES) M("m1", M("m2", N(NO) S("s1")) M("m3", S("s2"))), {{1,1},{0,1},{0,1}}, {{1,0},{0,1}} }
+ { M("m1", M("m2", S("s1")) M("m3", S("s2"))), {{0,0},{0,0},{0,0}}, {{0,0},{0,0}}, false },
+ { DN() M("m1", M("m2", S("s1")) M("m3", S("s2"))), {{1,1},{0,1},{0,1}}, {{0,1},{0,1}}, false },
+ { DN() M("m1", DN(NO) M("m2", S("s1")) M("m3", S("s2"))), {{1,1},{1,0},{0,1}}, {{0,0},{0,1}}, false },
+ { DN(NO) M("m1", DN(YES) M("m2", S("s1")) M("m3", S("s2"))), {{1,0},{1,1},{0,0}}, {{0,1},{0,0}}, false },
+ { DN(YES) M("m1", M("m2", N(NO) S("s1")) M("m3", S("s2"))), {{1,1},{0,1},{0,1}}, {{1,0},{0,1}}, false },
+ { M("m1", M("m2", S("s1")) M("m3", S("s2"))), {{0,1},{0,1},{0,1}}, {{0,1},{0,1}}, true },
+ { DN() M("m1", M("m2", S("s1")) M("m3", S("s2"))), {{1,1},{0,1},{0,1}}, {{0,1},{0,1}}, true },
+ { DN() M("m1", DN(NO) M("m2", S("s1")) M("m3", S("s2"))), {{1,1},{1,0},{0,1}}, {{0,0},{0,1}}, true },
+ { DN(NO) M("m1", DN(YES) M("m2", S("s1")) M("m3", S("s2"))), {{1,0},{1,1},{0,0}}, {{0,1},{0,0}}, true },
+ { DN(YES) M("m1", M("m2", N(NO) S("s1")) M("m3", S("s2"))), {{1,1},{0,1},{0,1}}, {{1,0},{0,1}}, true },
};
static const size_t n = sizeof(tests)/sizeof(tests[0]);
@@ -449,7 +455,13 @@ CU_Test(idl_annotation, default_nested)
for (size_t i=0; i < n; i++) {
pstate = NULL;
- ret = parse_string(IDL_FLAG_ANNOTATIONS, tests[i].str, &pstate);
+ ret = idl_create_pstate(IDL_FLAG_ANNOTATIONS, NULL, &pstate);
+ if (IDL_RETCODE_OK == ret) {
+ pstate->config.default_extensibility = IDL_FINAL;
+ pstate->config.default_nested = tests[i].pstate_default_nested;
+ ret = idl_parse_string(pstate, tests[i].str);
+ }
+
CU_ASSERT_EQUAL(ret, IDL_RETCODE_OK);
if (ret == IDL_RETCODE_OK) {
m = (idl_module_t *)pstate->root;
@@ -473,7 +485,8 @@ CU_Test(idl_annotation, default_nested)
CU_ASSERT(!tests[i].n[1].a == !s->nested.annotation);
CU_ASSERT(s->nested.value == tests[i].n[1].v);
}
- idl_delete_pstate(pstate);
+ if (pstate)
+ idl_delete_pstate(pstate);
}
}
#undef M
diff --git a/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c b/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c
index bb900f16..1f556556 100644
--- a/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c
+++ b/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c
@@ -464,7 +464,7 @@ crypto_decrypt_data(
{
bool result = true;
EVP_CIPHER_CTX *ctx;
- crypto_session_key_t session_key;
+ crypto_session_key_t session_key = {.data = {0} };
uint32_t key_size = crypto_get_key_size(CRYPTO_TRANSFORM_KIND(transformation_kind));
int len = 0;
diff --git a/src/tools/_confgen/CMakeLists.txt b/src/tools/_confgen/CMakeLists.txt
index 9df1b82a..d5ca793d 100644
--- a/src/tools/_confgen/CMakeLists.txt
+++ b/src/tools/_confgen/CMakeLists.txt
@@ -60,33 +60,33 @@ if (NOT ${_confgen_hash_correct})
add_custom_target(
_confgen
- COMMAND _confgen-exe ARGS -f defconfig -o "${generated_defconfig_src}"
- COMMAND _confgen-exe ARGS -f rnc -o "${generated_cyclonedds_rnc}"
- COMMAND _confgen-exe ARGS -f xsd -o "${generated_cyclonedds_xsd}"
- COMMAND _confgen-exe ARGS -f md -o "${generated_options_md}"
+ COMMAND _confgen-exe -f defconfig -o "${generated_defconfig_src}"
+ COMMAND _confgen-exe -f rnc -o "${generated_cyclonedds_rnc}"
+ COMMAND _confgen-exe -f xsd -o "${generated_cyclonedds_xsd}"
+ COMMAND _confgen-exe -f md -o "${generated_options_md}"
# Append hashes to defconfig.c
- COMMAND ${CMAKE_COMMAND} ARGS
+ COMMAND ${CMAKE_COMMAND}
"-DPREFIX=/*"
"-DPOSTFIX=*/"
-DHASH_FILES=${out_confgen_hash_files}
-DAPPEND_FILES=${generated_defconfig_src}
-P ${CMAKE_SOURCE_DIR}/cmake/AppendHashScript.cmake
# Append hashes to rnc
- COMMAND ${CMAKE_COMMAND} ARGS
+ COMMAND ${CMAKE_COMMAND}
"-DPREFIX=#"
"-DPOSTFIX="
-DHASH_FILES=${out_confgen_hash_files}
-DAPPEND_FILES=${generated_cyclonedds_rnc}
-P ${CMAKE_SOURCE_DIR}/cmake/AppendHashScript.cmake
# Append hashes to xsd
- COMMAND ${CMAKE_COMMAND} ARGS
+ COMMAND ${CMAKE_COMMAND}
"-DPREFIX="
-DHASH_FILES=${out_confgen_hash_files}
-DAPPEND_FILES=${generated_cyclonedds_xsd}
-P ${CMAKE_SOURCE_DIR}/cmake/AppendHashScript.cmake
# Append hashes to md
- COMMAND ${CMAKE_COMMAND} ARGS
+ COMMAND ${CMAKE_COMMAND}
"-DPREFIX="
-DHASH_FILES=${out_confgen_hash_files}
diff --git a/src/tools/ddsperf/ddsperf.c b/src/tools/ddsperf/ddsperf.c
index f5645d5f..de24ab0f 100644
--- a/src/tools/ddsperf/ddsperf.c
+++ b/src/tools/ddsperf/ddsperf.c
@@ -2125,7 +2125,7 @@ int main (int argc, char *argv[])
sigset_t sigset, osigset;
ddsrt_thread_t sigtid;
#endif
- char netload_if[256];
+ char netload_if[256] = {0};
double netload_bw = -1;
double rss_init = 0.0, rss_final = 0.0;
ddsrt_threadattr_init (&attr);
diff --git a/src/tools/idlc/src/descriptor_type_meta.c b/src/tools/idlc/src/descriptor_type_meta.c
index 338051bf..4f54ed9e 100644
--- a/src/tools/idlc/src/descriptor_type_meta.c
+++ b/src/tools/idlc/src/descriptor_type_meta.c
@@ -198,6 +198,12 @@ has_fully_descriptive_typeid (const idl_type_spec_t *type_spec)
static idl_retcode_t
get_typeid(const idl_pstate_t *pstate, struct descriptor_type_meta *dtm, const idl_type_spec_t *type_spec, bool alias_related_type, DDS_XTypes_TypeIdentifier *ti, DDS_XTypes_TypeKind kind, bool array_element);
+static DDS_XTypes_CollectionElementFlag
+get_sequence_element_flags(const idl_sequence_t *seq);
+
+static DDS_XTypes_CollectionElementFlag
+get_array_element_flags(const idl_node_t *node);
+
static idl_retcode_t
get_plain_typeid (const idl_pstate_t *pstate, struct descriptor_type_meta *dtm, const idl_type_spec_t *type_spec, bool alias_related_type, DDS_XTypes_TypeIdentifier *ti, DDS_XTypes_TypeKind kind)
{
@@ -220,6 +226,7 @@ get_plain_typeid (const idl_pstate_t *pstate, struct descriptor_type_meta *dtm,
ti->_u.array_sdefn.element_identifier = calloc (1, sizeof (*ti->_u.array_sdefn.element_identifier));
if ((ret = get_typeid (pstate, dtm, type_spec, false, ti->_u.array_sdefn.element_identifier, kind, true)) < 0)
return ret;
+ ti->_u.array_sdefn.header.element_flags = get_array_element_flags (type_spec);
if (has_fully_descriptive_typeid_impl (type_spec, true, alias_related_type))
ti->_u.array_sdefn.header.equiv_kind = DDS_XTypes_EK_BOTH;
else
@@ -227,6 +234,7 @@ get_plain_typeid (const idl_pstate_t *pstate, struct descriptor_type_meta *dtm,
} else {
ti->_d = DDS_XTypes_TI_PLAIN_ARRAY_LARGE;
ti->_u.array_ldefn.element_identifier = calloc (1, sizeof (*ti->_u.array_ldefn.element_identifier));
+ ti->_u.array_ldefn.header.element_flags = get_array_element_flags (type_spec);
for (; literal; literal = idl_next (literal)) {
assert (literal->value.uint64 < UINT32_MAX);
uint32_t val = literal->value.uint32;
@@ -275,6 +283,7 @@ get_plain_typeid (const idl_pstate_t *pstate, struct descriptor_type_meta *dtm,
if (!idl_is_bounded (seq) || seq->maximum <= UINT8_MAX) {
ti->_d = DDS_XTypes_TI_PLAIN_SEQUENCE_SMALL;
ti->_u.seq_sdefn.bound = (uint8_t) seq->maximum;
+ ti->_u.seq_sdefn.header.element_flags = get_sequence_element_flags (seq);
ti->_u.seq_sdefn.element_identifier = calloc (1, sizeof (*ti->_u.seq_sdefn.element_identifier));
if ((ret = get_typeid (pstate, dtm, idl_type_spec (type_spec), false, ti->_u.seq_sdefn.element_identifier, kind, false)) < 0)
return ret;
@@ -285,6 +294,7 @@ get_plain_typeid (const idl_pstate_t *pstate, struct descriptor_type_meta *dtm,
} else {
ti->_d = DDS_XTypes_TI_PLAIN_SEQUENCE_LARGE;
ti->_u.seq_ldefn.bound = seq->maximum;
+ ti->_u.seq_ldefn.header.element_flags = get_sequence_element_flags (seq);
ti->_u.seq_ldefn.element_identifier = calloc (1, sizeof (*ti->_u.seq_ldefn.element_identifier));
if ((ret = get_typeid (pstate, dtm, idl_type_spec (type_spec), false, ti->_u.seq_ldefn.element_identifier, kind, false)) < 0)
return ret;
@@ -386,19 +396,18 @@ static DDS_XTypes_StructMemberFlag
get_struct_member_flags(const idl_member_t *member)
{
DDS_XTypes_StructMemberFlag flags = 0u;
- if (member->try_construct.annotation) {
- switch (member->try_construct.value) {
- case IDL_DISCARD:
- flags |= DDS_XTypes_TRY_CONSTRUCT_DISCARD;
- break;
- case IDL_USE_DEFAULT:
- flags |= DDS_XTypes_TRY_CONSTRUCT_USE_DEFAULT;
- break;
- case IDL_TRIM:
- flags |= DDS_XTypes_TRY_CONSTRUCT_TRIM;
- break;
- }
+ switch (member->try_construct.value) {
+ case IDL_DISCARD:
+ flags |= DDS_XTypes_TRY_CONSTRUCT_DISCARD;
+ break;
+ case IDL_USE_DEFAULT:
+ flags |= DDS_XTypes_TRY_CONSTRUCT_USE_DEFAULT;
+ break;
+ case IDL_TRIM:
+ flags |= DDS_XTypes_TRY_CONSTRUCT_TRIM;
+ break;
}
+
if (member->external.value)
flags |= DDS_XTypes_IS_EXTERNAL;
if (member->key.value)
@@ -434,6 +443,10 @@ static DDS_XTypes_UnionDiscriminatorFlag
get_union_discriminator_flags(const idl_switch_type_spec_t *switch_type_spec)
{
DDS_XTypes_UnionDiscriminatorFlag flags = 0u;
+
+ // FIXME: support non-default try-construct
+ flags |= DDS_XTypes_TRY_CONSTRUCT_DISCARD;
+
// XTypes spec 7.2.2.4.4.4.6: In a union type, the discriminator member shall always have the 'must understand' attribute set to true
flags |= DDS_XTypes_IS_MUST_UNDERSTAND;
if (switch_type_spec->key.value)
@@ -446,18 +459,16 @@ static DDS_XTypes_UnionMemberFlag
get_union_case_flags(const idl_case_t *_case)
{
DDS_XTypes_UnionMemberFlag flags = 0u;
- if (_case->try_construct.annotation) {
- switch (_case->try_construct.value) {
- case IDL_DISCARD:
- flags |= DDS_XTypes_TRY_CONSTRUCT_DISCARD;
- break;
- case IDL_USE_DEFAULT:
- flags |= DDS_XTypes_TRY_CONSTRUCT_USE_DEFAULT;
- break;
- case IDL_TRIM:
- flags |= DDS_XTypes_TRY_CONSTRUCT_TRIM;
- break;
- }
+ switch (_case->try_construct.value) {
+ case IDL_DISCARD:
+ flags |= DDS_XTypes_TRY_CONSTRUCT_DISCARD;
+ break;
+ case IDL_USE_DEFAULT:
+ flags |= DDS_XTypes_TRY_CONSTRUCT_USE_DEFAULT;
+ break;
+ case IDL_TRIM:
+ flags |= DDS_XTypes_TRY_CONSTRUCT_TRIM;
+ break;
}
if (_case->external.value)
flags |= DDS_XTypes_IS_EXTERNAL;
@@ -468,10 +479,13 @@ get_union_case_flags(const idl_case_t *_case)
}
static DDS_XTypes_CollectionElementFlag
-get_collection_element_flags(const idl_sequence_t *seq)
+get_sequence_element_flags(const idl_sequence_t *seq)
{
DDS_XTypes_CollectionElementFlag flags = 0u;
+ // FIXME: support non-default try-construct
+ flags |= DDS_XTypes_TRY_CONSTRUCT_DISCARD;
+
(void) seq;
// FIXME: support @external for sequence element type
// if (seq->external)
@@ -479,6 +493,21 @@ get_collection_element_flags(const idl_sequence_t *seq)
return flags;
}
+static DDS_XTypes_CollectionElementFlag
+get_array_element_flags(const idl_node_t *node)
+{
+ DDS_XTypes_CollectionElementFlag flags = 0u;
+
+ // FIXME: support non-default try-construct
+ flags |= DDS_XTypes_TRY_CONSTRUCT_DISCARD;
+
+ (void) node;
+ // FIXME: support @external for array element type
+ // if (arr->external)
+ // flags |= DDS_XTypes_IS_EXTERNAL;
+ return flags;
+}
+
static DDS_XTypes_BitmaskTypeFlag
get_bitmask_flags(const idl_bitmask_t *_bitmask)
{
@@ -988,7 +1017,7 @@ add_array (
if (!revisit) {
dtm->stack->to_minimal->_u.minimal._u.array_type.element.common.element_flags =
- dtm->stack->to_complete->_u.complete._u.array_type.element.common.element_flags = get_collection_element_flags (node);
+ dtm->stack->to_complete->_u.complete._u.array_type.element.common.element_flags = get_sequence_element_flags (node);
if ((ret = get_complete_type_detail (type_spec, &dtm->stack->to_complete->_u.complete._u.array_type.header.detail)) < 0)
return ret;
@@ -1428,7 +1457,7 @@ emit_sequence(
No need to include sequence_type.header.detail here, because sequences are anonymous
types and there is no type name to store */
dtm->stack->to_minimal->_u.minimal._u.sequence_type.element.common.element_flags =
- dtm->stack->to_complete->_u.complete._u.sequence_type.element.common.element_flags = get_collection_element_flags (node);
+ dtm->stack->to_complete->_u.complete._u.sequence_type.element.common.element_flags = get_sequence_element_flags (node);
dtm->stack->to_minimal->_u.minimal._u.sequence_type.header.common.bound =
dtm->stack->to_complete->_u.complete._u.sequence_type.header.common.bound = seq->maximum;
return IDL_VISIT_REVISIT | IDL_VISIT_TYPE_SPEC;
diff --git a/src/tools/idlc/src/idlc.c b/src/tools/idlc/src/idlc.c
index bc25c228..3ea2edb7 100644
--- a/src/tools/idlc/src/idlc.c
+++ b/src/tools/idlc/src/idlc.c
@@ -59,6 +59,7 @@ static struct {
int keylist;
int case_sensitive;
int default_extensibility;
+ bool default_nested;
struct idlc_disable_warning_list disable_warnings;
int help;
int version;
@@ -314,6 +315,7 @@ static idl_retcode_t idlc_parse(void)
pstate->scanner.position.column = 1;
pstate->config.flags |= IDL_WRITE;
pstate->config.default_extensibility = config.default_extensibility;
+ pstate->config.default_nested = config.default_nested;
pstate->config.disable_warnings = config.disable_warnings.list;
pstate->config.n_disable_warnings = config.disable_warnings.count;
}
@@ -442,6 +444,18 @@ static int config_default_extensibility(const idlc_option_t *opt, const char *ar
return 0;
}
+static int config_default_nested(const idlc_option_t *opt, const char *arg)
+{
+ (void)opt;
+ if (strcmp(arg, "true") == 0)
+ config.default_nested = true;
+ else if (strcmp(arg, "false") == 0)
+ config.default_nested = false;
+ else
+ return IDLC_BAD_ARGUMENT;
+ return 0;
+}
+
static int add_disable_warning(idl_warning_t warning)
{
if (config.disable_warnings.count == config.disable_warnings.size) {
@@ -539,6 +553,12 @@ static const idlc_option_t *compopts[] = {
"Set the default extensibility that is used in case no extensibility"
"is set on a type. Possible values are final, appendable and mutable. "
"(default: final)" },
+ &(idlc_option_t){
+ IDLC_FUNCTION, { .function = &config_default_nested }, 'n', "", "",
+ "Set the default nestedness that is used in the absence of nestedness specifiers on a type "
+ "(@topic/nested), or other specifiers in its hierarchy (@default_nestedness on modules), "
+ "with an unset nestedness implicitly being false. Possible values for this option are: true, "
+ "false (default: true). " },
&(idlc_option_t){
IDLC_FUNCTION, { .function = &config_warning }, 'W', "", "",
"Enable or disable warnings. Possible values are: no-implicit-extensibility, "
@@ -602,6 +622,7 @@ int main(int argc, char *argv[])
config.compile = 1;
config.preprocess = 1;
config.default_extensibility = IDL_DEFAULT_EXTENSIBILITY_UNDEFINED;
+ config.default_nested = false;
config.disable_warnings.list = NULL;
config.disable_warnings.size = 0;
config.disable_warnings.count = 0;
diff --git a/src/tools/idlc/tests/type_meta.c b/src/tools/idlc/tests/type_meta.c
index 48fffc55..b5df38a8 100644
--- a/src/tools/idlc/tests/type_meta.c
+++ b/src/tools/idlc/tests/type_meta.c
@@ -202,7 +202,7 @@ static DDS_XTypes_TypeObject *get_typeobj_union(const char *name, uint16_t flags
._d = DDS_XTypes_TK_UNION,
._u.union_type = (DDS_XTypes_CompleteUnionType) {
.union_flags = flags,
- .discriminator = { .common = { .member_flags = DDS_XTypes_IS_MUST_UNDERSTAND, .type_id = disc_type } },
+ .discriminator = { .common = { .member_flags = DDS_XTypes_IS_MUST_UNDERSTAND | DDS_XTypes_TRY_CONSTRUCT_DISCARD, .type_id = disc_type } },
.member_seq = {
._maximum = member_cnt,
._length = member_cnt,
@@ -224,9 +224,9 @@ static DDS_XTypes_TypeObject *get_typeobj1 (void)
DDS_XTypes_IS_APPENDABLE,
(DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE },
3, (smember_t[]) {
- { 0, DDS_XTypes_IS_KEY | DDS_XTypes_IS_MUST_UNDERSTAND, { ._d = DDS_XTypes_TK_INT64 }, "f1" },
- { 1, DDS_XTypes_IS_OPTIONAL, { ._d = DDS_XTypes_TI_STRING8_SMALL, ._u.string_sdefn.bound = 0 }, "f2" },
- { 4, DDS_XTypes_IS_EXTERNAL, { ._d = DDS_XTypes_TK_CHAR8 }, "f3" }
+ { 0, DDS_XTypes_IS_KEY | DDS_XTypes_IS_MUST_UNDERSTAND | DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_INT64 }, "f1" },
+ { 1, DDS_XTypes_IS_OPTIONAL | DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TI_STRING8_SMALL, ._u.string_sdefn.bound = 0 }, "f2" },
+ { 4, DDS_XTypes_IS_EXTERNAL | DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_CHAR8 }, "f3" }
});
}
@@ -237,8 +237,8 @@ static DDS_XTypes_TypeObject *get_typeobj2 (void)
DDS_XTypes_IS_MUTABLE,
(DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE },
2, (smember_t[]) {
- { 0, DDS_XTypes_IS_OPTIONAL | DDS_XTypes_IS_EXTERNAL, { ._d = DDS_XTypes_TK_UINT32 }, "f1" },
- { 1, DDS_XTypes_IS_OPTIONAL | DDS_XTypes_IS_EXTERNAL, { ._d = DDS_XTypes_TK_UINT32 }, "f2" }
+ { 0, DDS_XTypes_IS_OPTIONAL | DDS_XTypes_IS_EXTERNAL | DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_UINT32 }, "f1" },
+ { 1, DDS_XTypes_IS_OPTIONAL | DDS_XTypes_IS_EXTERNAL | DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_UINT32 }, "f2" }
});
}
@@ -249,8 +249,8 @@ static DDS_XTypes_TypeObject *get_typeobj3 (void)
DDS_XTypes_IS_FINAL,
(DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_INT16 },
2, (umember_t[]) {
- { 0, 0, { ._d = DDS_XTypes_TK_INT32 }, "f1", 1, (int32_t[]) { 1 } },
- { 1, DDS_XTypes_IS_EXTERNAL | DDS_XTypes_IS_DEFAULT, { ._d = DDS_XTypes_TI_STRING8_SMALL, ._u.string_sdefn.bound = 0 }, "f2", 2, (int32_t[]) { 2, 3 } }
+ { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_INT32 }, "f1", 1, (int32_t[]) { 1 } },
+ { 1, DDS_XTypes_IS_EXTERNAL | DDS_XTypes_IS_DEFAULT | DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TI_STRING8_SMALL, ._u.string_sdefn.bound = 0 }, "f2", 2, (int32_t[]) { 2, 3 } }
});
}
@@ -273,14 +273,14 @@ static DDS_XTypes_TypeObject *get_typeobj4 (void)
DDS_XTypes_IS_MUTABLE | DDS_XTypes_IS_NESTED,
(DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE },
1, (smember_t[]) {
- { 5, 0, { ._d = DDS_XTypes_TK_INT32 }, "a1" }
+ { 5, DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_INT32 }, "a1" }
}));
return get_typeobj_struct (
"t4::test_struct",
DDS_XTypes_IS_MUTABLE,
ti_base,
1, (smember_t[]) {
- { 10, 0, { ._d = DDS_XTypes_TK_INT32 }, "f1" }
+ { 10, DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_INT32 }, "f1" }
});
}
@@ -301,7 +301,7 @@ static DDS_XTypes_TypeObject *get_typeobj5 (void)
.body = { .common = { .related_flags = 0, .related_type = (DDS_XTypes_TypeIdentifier) {
._d = DDS_XTypes_TI_PLAIN_SEQUENCE_SMALL,
._u.seq_sdefn = {
- .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = 0 },
+ .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD },
.bound = 0,
.element_identifier = ti_long
}
@@ -314,7 +314,7 @@ static DDS_XTypes_TypeObject *get_typeobj5 (void)
DDS_XTypes_TypeIdentifier ti_seq = {
._d = DDS_XTypes_TI_PLAIN_SEQUENCE_SMALL,
._u.seq_sdefn = {
- .header = { .equiv_kind = DDS_XTypes_EK_COMPLETE, .element_flags = 0 },
+ .header = { .equiv_kind = DDS_XTypes_EK_COMPLETE, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD },
.bound = 0
}
};
@@ -326,8 +326,8 @@ static DDS_XTypes_TypeObject *get_typeobj5 (void)
DDS_XTypes_IS_FINAL,
(DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE },
2, (smember_t[]) {
- { 0, 0, ti_seq, "f1" },
- { 1, 0, ti_alias, "f2" }
+ { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_seq, "f1" },
+ { 1, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_alias, "f2" }
});
}
@@ -345,7 +345,7 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void)
ti_f1 = (DDS_XTypes_TypeIdentifier) {
._d = DDS_XTypes_TI_PLAIN_ARRAY_SMALL,
._u.array_sdefn = {
- .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = 0 },
+ .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD },
.array_bound_seq = { ._maximum = 1, ._length = 1, ._buffer = f1bound_seq, ._release = true },
.element_identifier = ti_f1_el
}
@@ -356,6 +356,7 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void)
// the other 2 fields.
ti_f1._u.array_sdefn.array_bound_seq._buffer = f1bound_seq;
ti_f1._u.array_sdefn.element_identifier = ti_f1_el;
+ ti_f1._u.array_sdefn.header.element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD;
}
/* f2 type identifier: string<555> f2[999][3] */
@@ -370,7 +371,7 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void)
ti_f2 = (DDS_XTypes_TypeIdentifier) {
._d = DDS_XTypes_TI_PLAIN_ARRAY_LARGE,
._u.array_ldefn = {
- .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = 0 },
+ .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD },
.array_bound_seq = { ._maximum = 2, ._length = 2, ._buffer = f2bound_seq, ._release = true },
.element_identifier = ti_f2_el
}
@@ -378,6 +379,7 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void)
// Clang's static analyzer ...
ti_f2._u.array_ldefn.array_bound_seq._buffer = f2bound_seq;
ti_f2._u.array_ldefn.element_identifier = ti_f2_el;
+ ti_f2._u.array_ldefn.header.element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD;
}
/* f3 type identifier: a[3] f3 */
@@ -389,7 +391,7 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void)
DDS_XTypes_IS_FINAL | DDS_XTypes_IS_NESTED,
(DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE },
1, (smember_t[]) {
- { 0, 0, { ._d = DDS_XTypes_TK_INT32 }, "a1" }
+ { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_INT32 }, "a1" }
}));
uint8_t *f3bound_seq = calloc (1, sizeof (*f3bound_seq));
@@ -397,7 +399,7 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void)
ti_f3 = (DDS_XTypes_TypeIdentifier) {
._d = DDS_XTypes_TI_PLAIN_ARRAY_SMALL,
._u.array_sdefn = {
- .header = { .equiv_kind = DDS_XTypes_EK_COMPLETE, .element_flags = 0 },
+ .header = { .equiv_kind = DDS_XTypes_EK_COMPLETE, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD },
.array_bound_seq = { ._maximum = 1, ._length = 1, ._buffer = f3bound_seq, ._release = true },
.element_identifier = ti_a
}
@@ -405,6 +407,7 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void)
// Clang's static analyzer ...
ti_f3._u.array_sdefn.array_bound_seq._buffer = f3bound_seq;
ti_f3._u.array_sdefn.element_identifier = ti_a;
+ ti_f3._u.array_sdefn.header.element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD;
}
return get_typeobj_struct (
@@ -412,9 +415,9 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void)
DDS_XTypes_IS_FINAL,
(DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE },
3, (smember_t[]) {
- { 0, 0, ti_f1, "f1" },
- { 1, 0, ti_f2, "f2" },
- { 2, 0, ti_f3, "f3" }
+ { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f1, "f1" },
+ { 1, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f2, "f2" },
+ { 2, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f3, "f3" }
});
}
@@ -465,8 +468,8 @@ static DDS_XTypes_TypeObject *get_typeobj7 (void)
DDS_XTypes_IS_FINAL,
(DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE },
2, (smember_t[]) {
- { 0, 0, ti_f1, "f1" },
- { 1, 0, ti_f2, "f2" }
+ { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f1, "f1" },
+ { 1, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f2, "f2" }
});
}
@@ -485,7 +488,7 @@ static DDS_XTypes_TypeObject *get_typeobj8 (void)
ti_f1 = (DDS_XTypes_TypeIdentifier) {
._d = DDS_XTypes_TI_PLAIN_ARRAY_SMALL,
._u.array_sdefn = {
- .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = 0 },
+ .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD },
.array_bound_seq = { ._maximum = 2, ._length = 2, ._buffer = f1bound_seq, ._release = true },
.element_identifier = ti_f1_el
}
@@ -497,7 +500,7 @@ static DDS_XTypes_TypeObject *get_typeobj8 (void)
DDS_XTypes_IS_FINAL,
(DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE },
1, (smember_t[]) {
- { 0, 0, ti_f1, "f1" }
+ { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f1, "f1" }
});
}
@@ -529,8 +532,8 @@ static DDS_XTypes_TypeObject *get_typeobj9 (void)
DDS_XTypes_IS_FINAL,
(DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE },
2, (smember_t[]) {
- { 0, 0, ti_f, "f1" },
- { 1, 0, ti_f, "f2" }
+ { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f, "f1" },
+ { 1, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f, "f2" }
});
}
@@ -562,8 +565,8 @@ static DDS_XTypes_TypeObject *get_typeobj10 (void)
DDS_XTypes_IS_FINAL,
(DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE },
2, (smember_t[]) {
- { 0, 0, ti_f, "f1" },
- { 1, 0, ti_f, "f2" }
+ { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f, "f1" },
+ { 1, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f, "f2" }
});
}
@@ -574,8 +577,8 @@ static DDS_XTypes_TypeObject *get_typeobj11 (void)
DDS_XTypes_IS_FINAL,
(DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_CHAR8 },
2, (umember_t[]) {
- { 99, 0, { ._d = DDS_XTypes_TK_INT32 }, "f1", 1, (int32_t[]) { 'a' } },
- { 5, DDS_XTypes_IS_DEFAULT, { ._d = DDS_XTypes_TK_UINT16 }, "f2", 0, (int32_t[]) { 0 } }
+ { 99, DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_INT32 }, "f1", 1, (int32_t[]) { 'a' } },
+ { 5, DDS_XTypes_IS_DEFAULT | DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_UINT16 }, "f2", 0, (int32_t[]) { 0 } }
});
}
@@ -602,7 +605,7 @@ static DDS_XTypes_TypeObject *get_typeobj12 (void)
.body = { .common = { .related_flags = 0, .related_type = (DDS_XTypes_TypeIdentifier) {
._d = DDS_XTypes_TI_PLAIN_SEQUENCE_SMALL,
._u.seq_sdefn = {
- .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = 0 },
+ .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD },
.bound = 0,
.element_identifier = ti_long
}
@@ -624,7 +627,7 @@ static DDS_XTypes_TypeObject *get_typeobj12 (void)
.body = { .common = { .related_flags = 0, .related_type = (DDS_XTypes_TypeIdentifier) {
._d = DDS_XTypes_TI_PLAIN_ARRAY_SMALL,
._u.array_sdefn = {
- .header = { .equiv_kind = DDS_XTypes_EK_COMPLETE, .element_flags = 0 },
+ .header = { .equiv_kind = DDS_XTypes_EK_COMPLETE, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD },
.array_bound_seq = { ._maximum = 1, ._length = 1, ._buffer = bound_seq, ._release = true },
.element_identifier = ti_alias_seq
}
@@ -639,7 +642,7 @@ static DDS_XTypes_TypeObject *get_typeobj12 (void)
DDS_XTypes_IS_FINAL,
(DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE },
1, (smember_t[]) {
- { 0, 0, ti_f1, "f1" },
+ { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f1, "f1" },
});
}
@@ -665,7 +668,7 @@ static DDS_XTypes_TypeObject *get_typeobj13 (void)
.body = { .common = { .related_flags = 0, .related_type = (DDS_XTypes_TypeIdentifier) {
._d = DDS_XTypes_TI_PLAIN_ARRAY_SMALL,
._u.array_sdefn = {
- .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = 0 },
+ .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD },
.array_bound_seq = { ._maximum = 1, ._length = 1, ._buffer = bound_seq, ._release = true },
.element_identifier = ti_long
}
@@ -694,7 +697,7 @@ static DDS_XTypes_TypeObject *get_typeobj13 (void)
DDS_XTypes_IS_FINAL,
(DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE },
1, (smember_t[]) {
- { 0, 0, ti_f1, "f1" },
+ { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f1, "f1" },
});
}