Introduction to OpenDDS¶
What is OpenDDS?¶
OpenDDS is an open-source C++ framework for exchanging data in distributed systems. It is an implementation of a group of related OMG specifications. OpenDDS is implemented in C++ and contains support for Java. Users in the OpenDDS community have contributed and maintain bindings for other languages that include C#, Node.js, and Python. OpenDDS is sponsored by the OpenDDS Foundation and is available via https://opendds.org and https://github.com/OpenDDS/OpenDDS.
Licensing Terms¶
OpenDDS is open source software.
The source code may be freely downloaded and is open for inspection, review, comment, and improvement.
Copies may be freely installed across all your systems and those of your customers.
There is no charge for development or run-time licenses.
The source code is designed to be compiled, and used, across a wide variety of hardware and operating systems architectures.
You may modify it for your own needs, within the terms of the license agreements.
You must not copyright OpenDDS software.
For details of the licensing terms, see the file named LICENSE
that is included in the OpenDDS source code distribution or visit https://opendds.org/about/license.html.
OpenDDS also utilizes other open source software products including MPC and ACE/TAO.
OpenDDS is open source and the development team welcomes contributions of code, tests, documentation, and ideas. Active participation by users ensures a robust implementation. Contact the OpenDDS Foundation if you are interested in contributing to the development of OpenDDS. Please note that any code or documentation that is contributed to and becomes part of the OpenDDS open source code base is subject to the same licensing terms as the rest of the OpenDDS code base.
Specifications¶
OpenDDS is an open source implementation of a group of related OMG specifications.
Data Distribution Service (DDS) for Real-Time Systems¶
This specification defines a service for efficiently distributing application data between participants in a distributed application. This is the core functionality implemented by OpenDDS for real-time publish and subscribe applications and is described throughout this document.
The version OpenDDS uses is DDS v1.4. Compliance with the specification is documented in DDS Compliance. More information about the DDS itself can be found on the DDS Foundation website.
Real-time Publish-Subscribe (RTPS)¶
The full name of this specification is the Real-time Publish-Subscribe Protocol DDS Interoperability Wire Protocol (DDSI-RTPS), but can also be just called RTPS. This specification describes the requirements for interoperability between DDS implementations. See RTPS Discovery and RTPS/UDP Transport for more information.
The version OpenDDS uses is RTPS v2.3. Although the document number is v2.3, it specifies protocol version 2.4. Compliance with the specification is documented in DDSI-RTPS Compliance.
DDS Security¶
This specification extends DDS with capabilities for authentication and encryption. OpenDDS’s support for the DDS Security specification is described in DDS Security.
The version OpenDDS uses is DDS Security v1.1. Compliance with the specification is documented in DDS Security Implementation Status.
Extensible and Dynamic Topic Types for DDS (XTypes)¶
This specification defines details of the type system used for the data exchanged on DDS Topics, including how schema and data are encoded for network transmission. OpenDDS’s support for XTypes is described in XTypes.
The version OpenDDS uses is DDS XTypes v1.3. Compliance with the specification is documented in Unimplemented Features and Differences From the Specification.
IDL¶
IDL is a language that can be used to define data structures and interfaces that can be mapped to multiple programming languages. The parser is implemented as part of tao_idl.
The version OpenDDS uses is IDL v4.2. Compliance with the specification is documented in IDL Compliance.
IDL to C++03 Language Mapping¶
This specification defines an IDL to C++ mapping. It’s generated by tao_idl, not opendds_idl.
The version OpenDDS uses is IDL to C++03 v1.3.
IDL to C++11 Language Mapping¶
This specification defines an IDL to C++ mapping that takes advantage of C++11 language features and standard library types. OpenDDS’s support for IDL to C++11 is described in Using the IDL-to-C++11 Mapping.
The version OpenDDS uses is IDL to C++11 v1.5.
IDL to Java Language Mapping¶
This specification defines an IDL to Java mapping and is used for the Java Bindings.
The version OpenDDS uses is IDL to Java v1.3.
Compliance¶
OpenDDS complies with the OMG DDS and the OMG DDSI-RTPS specifications. Details of that compliance follows here. OpenDDS also implements the OMG DDS Security specification. See Specifications for how OpenDDS complies with other specifications it implements.
DDS Compliance¶
Section 2 of the DDS specification defines five compliance points for a DDS implementation:
Minimum Profile
Content-Subscription Profile
Persistence Profile
Ownership Profile
Object Model Profile
OpenDDS complies with the entire DDS specification (including all optional profiles). This includes the implementation of all Quality of Service policies with the following notes:
Reliability QoS
RELIABLE_RELIABILITY_QOS
is supported by the RTPS/UDP Transport, the TCP Transport, and the Multicast Transport (when configured as reliable).Transport Priority QoS is not implemented as changeable.
Although version 1.5 of the DDS specification is not yet published, OpenDDS incorporates some changes planned for that version that are required for a robust implementation:
OMG Issue DDS15-5 (Member Link): The IDL type
BuiltinTopicKey_t
is a struct containing an array of 16 octetsThe actual child issue isn’t public viewable for some reason, but the member link is https://issues.omg.org/browse/DDS15-257
DDSI-RTPS Compliance¶
The OpenDDS implementation complies with the requirements of the OMG DDSI-RTPS specification.
OpenDDS RTPS Implementation Notes¶
The OMG DDSI-RTPS specification supplies statements for implementation, but not required for compliance. The following items should be taken into consideration when utilizing the OpenDDS RTPS functionality for transport and/or discovery. Section numbers of the DDSI-RTPS specification are supplied with each item for further reference.
Items not implemented in OpenDDS:
Writer-side content filtering (RTPS v2.3 8.7.3 Content-filtered Topics)
OpenDDS may still drop samples that aren’t needed (due to content filtering) by any associated readers – this is done above the transport layer
RTPS v2.3 8.7.7 Directed Write
OpenDDS will use the Directed Write parameter if it’s present on incoming messages (for example, messages generated by a different DDS implementation)
RTPS v2.3 8.7.9 Original Writer Info for Durability QoS
This would only be used for transient and persistent durability, which are not supported by the RTPS specification
Key Hashes are not generated, but the specification makes them optional
nackSuppressionDuration
(Table 8.47 in RTPS v2.3 8.4.7.1 RTPS Writer) andheartbeatSuppressionDuration
(Table 8.62 in RTPS v2.3 8.4.10.1 RTPS Reader).
Note
Items 3 and 4 above are described in the DDSI-RTPS specification. However, they do not have a corresponding concept in the DDS specification.
IDL Compliance¶
OMG IDL is used in a few different ways in the OpenDDS code base and downstream applications that use it:
Files that come with OpenDDS such as
dds/DdsDcpsTopic.idl
define parts of the API between the middleware libraries and the application. This is known as the OMG IDL Platform Specific Model (PSM).Users of OpenDDS author IDL files in addition to source code files in C++ or Java.
This section only describes the latter use.
The IDL specification (version 4.2) uses the term “building block” to define subsets of the overall IDL grammar that may be supported by certain tools. OpenDDS supports the following building blocks, with notes/caveats listed below each:
Core Data Types
Support for the “fixed” data type (fixed point decimal) is incomplete.
Anonymous Types
There is limited support for anonymous types when they appear as sequence/array instantiations directly as struct field types. Using an explicitly-named type is recommended.
Annotations
See Defining Data Types with IDL and IDL Annotations for details on which built-in annotations are supported.
User-defined annotation types are also supported.
Extended Data Types
The integer types
int8
,uint8
,int16
,uin16
,int32
uint32
,int64
, anduint64
are supported.The rest of the building block is not supported.
Extensions to the DDS Specification¶
Data types, interfaces, and constants in the DDS
IDL module (C++ namespace, Java package) correspond directly to the DDS specification with very few exceptions:
DDS::SampleInfo
contains an extra field starting withopendds_reserved
.Type-specific DataReaders (including those for Built-in Topics) have additional operations
read_instance_w_condition()
andtake_instance_w_condition()
.
Additional extended behavior is provided by various classes and interfaces in the OpenDDS
module/namespace/package.
Those include features like Recorder and Replayer (Alternate Interfaces to Data) and also:
OpenDDS::DCPS::TypeSupport
adds theunregister_type()
operation not found in the DDS spec.OpenDDS::DCPS::ALL_STATUS_MASK
,NO_STATUS_MASK
, andDEFAULT_STATUS_MASK
are useful constants for theDDS::StatusMask
type used byDDS::Entity
,DDS::StatusCondition
, and the variouscreate_*()
operations.
OpenDDS Implementation and Architecture¶
This section gives a brief overview of the OpenDDS implementation, its features, and some of its components.
Source Code Organization¶
Relative to DDS_ROOT
:
the
dds/
directory contains the source code for OpenDDS.the
tests/
directory contains tests.the
tools/
directory contains tools and libraries like the DCPSInfoRepo, RtpsRelay, and the Modeling SDK.the
DevGuideExamples/
directory contains examples used in this guide.the
examples/
directory contains examples not used in this guide.the
docs/
directory contains documentation for users and developers of OpenDDS.
Design Philosophy¶
The OpenDDS implementation and API is based on a fairly strict interpretation of the OMG IDL PSM. In almost all cases the OMG’s IDL-to-C++ Language Mapping is used to define how the IDL in the DDS specification is mapped into the C++ APIs that OpenDDS exposes to the client.
The main deviation from the OMG IDL PSM is that local interfaces are used for the entities and various other interfaces. These are defined as unconstrained (non-local) interfaces in the DDS specification. Defining them as local interfaces improves performance, reduces memory usage, simplifies the client’s interaction with these interfaces, and makes it easier for clients to build their own implementations.
Plugins¶
OpenDDS puts many implementation details into libraries that are outside the core OpenDDS_Dcps
library.
Making these features modular allows users to build and distribute their applications without building or distributing code their applications won’t use.
It also makes it easier to replace these libraries with custom ones.
How to enable and use a particular plugin will differ based on the kind of plugin and the plugin itself, but generally they are enabled by some form of configuration setting, for example using [transport] transport_type
or DCPSSecurity
in a configuration file.
The plugin will also have to be linked and initialized at runtime.
For dynamic libraries (.dll
, .dynlib
or, .so
files) this is done automatically as the OpenDDS will load the dynamic library and then run any initialization the plugin requires.
When the plugins are statically linked, then it requires explicit linking and including an initialization header in the application that contains a global object that will initialize the plugin.
If OpenDDS was built using CMake, then dds/DCPS/StaticIncludes.h
can be included and the initialization headers will be included automatically based on the static libraries that were linked.
Explicit linking and initialization headers can also be used with dynamic libraries.
This will always load and initialize the plugin when the application starts instead of delaying until the plugin is needed.
Transports¶
Transmission of samples and information related to their management is accomplished via an OpenDDS-specific transport framework that allows the service to be used with a variety of transport protocols. Transports are typically specified via configuration files and are attached to various entities in the publisher and subscriber processes. See Transport Configuration for details on configuring transports generally.
Transports are used along with discovery to define how OpenDDS communicates.
TCP Transport¶
The TCP transport (tcp
) uses TCP as the transmission mechanism.
It’s the default transport normally.
It’s reliable, regardless of configuration.
Important
Library filename: OpenDDS_Tcp
MPC base project name: dcps_tcp
CMake target Name: OpenDDS::Tcp
Initialization header: dds/DCPS/transport/tcp/Tcp.h
[transport] transport_type
: tcp
Configuration: TCP Transport Configuration Properties
RTPS/UDP Transport¶
The RTPS/UDP transport (rtps_udp
) uses the UDP-based transport described in Real-time Publish-Subscribe (RTPS) as the transmission mechanism.
It’s interoperable with other DDS implementations when used with RTPS Discovery.
It’s the default transport when Safety Profile is being used.
It supports reliability.
Important
Library filename: OpenDDS_Rtps_Udp
MPC base project name: dcps_rtps_udp
CMake target Name: OpenDDS::Rtps_Udp
Initialization header: dds/DCPS/transport/rtps_udp/RtpsUdp.h
[transport] transport_type
: rtps_udp
Configuration: RTPS UDP Transport Configuration Properties
See also
- DDS Security
For security capabilities that are possible when using RTPS Discovery and the RTPS/UDP Transport
- Internet-Enabled RTPS
For using RTPS Discovery and the RTPS/UDP Transport over the internet
UDP Transport¶
The UDP transport (udp
) uses unicasted UDP as the transmission mechanism.
It doesn’t support reliability at all.
Important
Library filename: OpenDDS_Udp
MPC base project name: dcps_udp
CMake target Name: OpenDDS::Udp
Initialization header: dds/DCPS/transport/udp/Udp.h
[transport] transport_type
: udp
Configuration: UDP Transport Configuration Properties
Multicast Transport¶
The multicast transport (mutlicast
) uses multicasted UDP as the transmission mechanism.
It supports reliability.
Important
Library filename: OpenDDS_Multicast
MPC base project name: dcps_multicast
CMake target Name: OpenDDS::Multicast
Initialization header: dds/DCPS/transport/multicast/Multicast.h
[transport] transport_type
: multicast
Configuration: Multicast Transport Configuration Properties
Custom Transports¶
The transport framework enables application developers to implement their own customized transports.
Implementing a custom transport involves specializing a number of classes defined in the transport framework.
The udp
transport provides a good foundation developers may use when creating their own implementation.
See the dds/DCPS/transport/udp/
directory for details.
Discovery¶
DDS applications must discover one another via some central agent or through some distributed scheme. OpenDDS provides three options for discovery: InfoRepo Discovery, RTPS Discovery, and Static Discovery. The choice of discovery is independent of the choice of transport in most cases. For example, one can use the TCP Transport with RTPS Discovery. Notable exceptions are:
DDS Security requires using both RTPS Discovery and the RTPS/UDP Transport.
To get the most out of XTypes, it’s recommended to both RTPS Discovery and the RTPS/UDP Transport
Static Discovery requires RTPS/UDP Transport.
Like transports, additional discovery implementations can be created and plugged in.
InfoRepo Discovery¶
Note
InfoRepo discovery is scheduled for deprecation with OpenDDS 4 and scheduled for removal with OpenDDS 5.
OpenDDS contains a standalone CORBA service called The DCPS Information Repository. An instance of the DCPSInfoRepo is shared by all the participants in a domain and constitutes a centralized approach to discovery. Each OpenDDS application connects to the DCPSInfoRepo and creates records for its participants, topics, data writers, and data readers. As records for data writers and data readers are created, they are matched against the existing set of records. When matches are found, the DCPSInfoRepo invokes the participant to perform the necessary associations.
Important
Library filename: OpenDDS_InfoRepoDiscovery
MPC base project name: dcps_inforepodiscovery
CMake target Name: OpenDDS::InfoRepoDiscovery
Initialization header: dds/DCPS/InfoRepoDiscovery/InfoRepoDiscovery.h
Configuration: Configuring for InfoRepo Discovery
The DCPSInfoRepo is not involved in data propagation; its role is limited in scope to OpenDDS applications discovering one another. The DCPSInfoRepo populates the Built-in Topics (BITs) for a participant if configured to do so. OpenDDS creates its own ORB and a separate thread to run that ORB when using DCPSInfoRepo discovery.
Application developers are free to run multiple information repositories with each managing their own non-overlapping sets of DCPS domains.
It is also possible to operate domains with more than a single repository, thus forming a distributed virtual repository. This is known as Repository Federation. In order for individual repositories to participate in a federation, each one must specify its own federation identifier value (a 32-bit numeric value) upon start-up. See Repository Federation for further information about repository federations.
See also
- The DCPS Information Repository
Documentation on the
DCPSInfoRepo
program
RTPS Discovery¶
RTPS discovery is a peer-to-peer discovery mechanism standardized as part of the RTPS spec. Other DDS implementations can interoperate with OpenDDS when RTPS discovery is used with the RTPS/UDP Transport.
Important
Library filename: OpenDDS_Rtps
MPC base project name: dcps_rtps
CMake target Name: OpenDDS::Rtps
Initialization header: dds/DCPS/RTPS/RtpsDiscovery.h
Configuration: Configuring for RTPS Discovery
RTPS Discovery uses the RTPS protocol to advertise and discover participants, data writers, and data readers. RTPS Discovery uses multicast to discover participants and built-in endpoints (not to be confused with built-in topics) each other without a centralized broker such as InfoRepo. This part of RTPS discovery is called the Simple Participant Discovery Protocol (SPDP). After the built-in endpoints are discovered and associated, they exchange information about data writers and data readers which are called endpoints. This part of RTPS discovery is called Simple Endpoint Discovery Protocol (SEDP). RTPS Discovery is a peer-to-peer approach to discovery as each participant interacts directly with other participants to accomplish discovery.
The following are additional implementation limits that developers need to take into consideration when developing and deploying applications that use RTPS discovery:
Domain IDs should be between 0 and 231 (inclusive) due to the way UDP ports are assigned to domain IDs. In each OpenDDS process, up to 120 domain participants are supported in each domain.
Topic names and type identifiers are limited to 256 characters.
The Multicast Transport does not work with RTPS Discovery due to the way GUIDs are assigned (a warning will be issued if this is attempted).
See also
- XTypes
For expanded type-system capabilities that are possible when using RTPS discovery
- DDS Security
For security capabilities that are possible when using RTPS Discovery and the RTPS/UDP Transport
- Internet-Enabled RTPS
For using RTPS Discovery and the RTPS/UDP Transport over the internet
Static Discovery¶
In Static Discovery, each participant starts with a database containing identifiers, QoS settings, and network locators for all participants, topics, data writers, data readers.
Important
The RTPS/UDP Transport is the only transport that can be used with Static Discovery.
Static Discovery is built-in to the core Dcps library, so it doesn’t require linking a separate library or including an initialization header.
Configuration: Configuring for Static Discovery
When an application creates a data writer or data reader, Static Discovery causes it to send out periodic announcements. Upon receiving one of these announcements, Static Discovery consults its local database of entities to look up the details necessary for matching and matches it against local entities.
Static Discovery requires that the User Data QoS be configured for each participant, data writer, and data reader. This user data must contain the identifier of the entity that is being created. Thus, the user data QoS is not available for general use when using Static Discovery. Static Discovery also requires that the network locators for all entities be determined up front by configuring the transport with the necessary networking information.
Threading¶
OpenDDS creates its own threads for handling I/O, timers, asynchronous jobs, and cleanup tasks. These threads are collectively called service threads. Applications may receive a callback from these threads via Listeners.
When publishing a sample, OpenDDS normally attempts to send the sample to any connected subscribers using the calling thread. If the send call would block, then the sample may be queued for sending on a separate service thread. This behavior depends on the QoS policies described in Quality of Service.
All incoming data is read by a service thread and queued for reading in DataReaders by the application. If a DataReader has a listener that should be invoked when data is available, then the listener is invoked by the service thread.
Configuration¶
OpenDDS includes a file-based configuration framework for configuring both global items such as debug level, memory allocation, and discovery, as well as transport implementation details for publishers and subscribers. Configuration can also be achieved directly in code, however, it is recommended that configuration be externalized for ease of maintenance and reduction in runtime errors. The complete set of configuration options are described in Run-time Configuration.
Footnotes