RTI Connext

Core Libraries and Utilities

User’s Manual

Version 5.0

© 2012 Real-Time Innovations, Inc.

All rights reserved.

Printed in U.S.A. First printing.

August 2012.

Trademarks

Real-Time Innovations, RTI, DataBus, and Connext are trademarks or registered trademarks of Real-Time Innovations, Inc. All other trademarks used in this document are the property of their respective owners.

Copy and Use Restrictions

No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form (including electronic, mechanical, photocopy, and facsimile) without the prior written permission of Real- Time Innovations, Inc. The software described in this document is furnished under and subject to the RTI software license agreement. The software may be used or copied only under the terms of the license agreement.

Third-Party Copyright Notices

Note: In this section, "the Software" refers to third-party software, portions of which are used in Connext; "the Software" does not refer to Connext.

This product implements the DCPS layer of the Data Distribution Service (DDS) specification version 1.2 and the DDS Interoperability Wire Protocol specification version 2.1, both of which are owned by the Object Management, Inc. Copyright 1997-2007 Object Management Group, Inc. The publication of these specifications can be found at the Catalog of OMG Data Distribution Service (DDS) Specifications. This documentation uses material from the OMG specification for the Data Distribution Service, section 7. Reprinted with permission. Object Management, Inc. © OMG. 2005.

Portions of this product were developed using ANTLR (www.ANTLR.org). This product includes software developed by the University of California, Berkeley and its contributors.

Portions of this product were developed using AspectJ, which is distributed per the CPL license. AspectJ source code may be obtained from Eclipse. This product includes software developed by the University of California, Berkeley and its contributors.

Portions of this product were developed using MD5 from Aladdin Enterprises.

Portions of this product include software derived from Fnmatch, (c) 1989, 1993, 1994 The Regents of the University of California. All rights reserved. The Regents and contributors provide this software "as is" without warranty.

Portions of this product were developed using EXPAT from Thai Open Source Software Center Ltd and Clark Cooper Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper Copyright (c) 2001, 2002 Expat maintainers. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

Technical Support

Real-Time Innovations, Inc.

232 E. Java Drive

Sunnyvale, CA 94089

Phone:

(408) 990-7444

Email:

support@rti.com

Website:

https://support.rti.com/

Available Documentation

To get you up and running as quickly as possible, we have divided the RTI® Connext™ (for- merly, RTI Data Distribution Service) documentation into several parts.

Getting Started Guide (RTI_CoreLibrariesAndUtilities_GettingStarted.pdf)—This doc- ument describes how to install Connext. It also lays out the core value and concepts behind the product and takes you step-by-step through the creation of a simple example application. Developers should read this document first.

If you want to use the Connext Extensible Types feature, please read:

Addendum for Extensible Types (RTI_CoreLibrariesAndUtilities_GettingStarted _ExtensibleTypesAddendum.pdf) Extensible Types allow you to define data types in a more flexible way. Your data types can evolve over time—without giving up porta- bility, interoperability, or the expressiveness of the DDS type system.

If you are using Connext on an embedded platform or with a database, you will find additional documents that specifically address these configurations:

Addendum for Embedded Systems (RTI_CoreLibrariesAndUtilities_GettingStarted _EmbeddedSystemsAddendum.pdf)

Addendum for Database Setup (RTI_CoreLibrariesAndUtilities_GettingStarted

_DatabaseAddendum.pdf).

What’s New (RTI_CoreLibrariesAndUtilities_WhatsNew.pdf)—This document describes changes and enhancements in the current version of Connext. Those upgrading from a previous version should read this document first.

Release Notes and Platform Notes (RTI_CoreLibrariesAndUtilities_ReleaseNotes.pdf and RTI_CoreLibrariesAndUtilities_PlatformNotes.pdf)—These documents provide system requirements, compatibility, and other platform-specific information about the product, including specific information required to build your applications using RTI, such as compiler flags and libraries.

Core Libraries and Utilities User’s Manual (RTI_CoreLibrariesAndUtilities _UsersManual.pdf)—This document describes the features of the product and how to use them. It is organized around the structure of the Connext APIs and certain common high-level tasks.

API Reference Documentation (ReadMe.html, RTI_CoreLibrariesAndUtilities _ApiReference<Language>.pdf)—This extensively cross-referenced documentation, available both in HTML and printable PDF formats for all supported programming lan- guages, is your in-depth reference to every operation and configuration parameter in the middleware. Even experienced Connext developers will often consult this information.

iii

The Programming How To's provide a good place to begin learning the APIs. These are hyperlinked code snippets to the full API documentation. From the ReadMe.html file, select one of the supported programming languages, then scroll down to the Program- ming How To’s. Start by reviewing the Publication Example and Subscription Example, which provide step-by step examples of how to send and receive data with Connext.

Many readers will also want to look at additional documentation available online. In particular, RTI recommends the following:

The RTI Customer Portal, https://support.rti.com, provides access to RTI software, doc- umentation, and support. It also allows you to log support cases. Furthermore, the portal provides detailed solutions and a free public knowledge base. To access the software, documentation or log support cases, the RTI Customer Portal requires a username and password. You will receive this in the email confirming your purchase. If you do not have this email, please contact license@rti.com. Resetting your login password can be done directly at the RTI Customer Portal.

Examples—Accessible from http://www.rti.com/examples. This page contains example code snippets on how to use individual features, examples illustrating specific use cases, as well as:

Example Performance Test (available for C++, Java and .NET1)—This example appli- cation includes code and configuration files for testing and optimizing the perfor- mance of a simple Connext application on your system. The program will test both throughput and latency under a wide variety of middleware configurations. It also includes documentation on tuning the middleware and the underlying operating sys- tem. You can also review the data from several performance benchmarks here: http://www.rti.com/products/dds/benchmarks-cpp-linux.html.

Whitepapers and other articles—Available from http://www.rti.com/resources/.

1. RTI Connext .NET language binding is currently supported for C# and C++/CLI.

iv

Contents

 

 

Available Documentation..............................................................

iii

 

 

Welcome to RTI Connext............................................................................

xix

 

 

Conventions ...............................................................................................................................................

xix

 

 

 

Extensions to the DDS Standard ...............................................................................................

xix

 

 

 

Environment Variables ...............................................................................................................

xix

 

 

 

Names of Supported Platforms .................................................................................................

xix

 

 

Additional Resources.................................................................................................................................

xx

Part 1: Introduction

 

1

Overview............................................................................................

1-1

 

1.1

What is Connext? ...................................................................................................................................

1-1

 

1.2

What is Middleware? ............................................................................................................................

1-2

 

1.3

Network Communications Models.....................................................................................................

1-2

 

1.4

Features of Connext...............................................................................................................................

1-4

2

Data-Centric Publish-Subscribe Communications........................

2-1

 

2.1

What is DCPS?........................................................................................................................................

2-1

 

 

2.1.1 DCPS for Real-Time Requirements........................................................................................

2-2

 

2.2

Data Types, Topics, Keys, Instances, and Samples............................................................................

2-3

 

 

2.2.1 Data Topics — What is the Data Called? ..............................................................................

2-3

 

 

2.2.2 Samples, Instances, and Keys .................................................................................................

2-4

 

2.3

DataWriters/Publishers and DataReaders/Subscribers..................................................................

2-5

 

2.4

Domains and DomainParticipants ......................................................................................................

2-7

 

2.5

Quality of Service (QoS)........................................................................................................................

2-8

 

 

2.5.1 Controlling Behavior with Quality of Service (QoS) Policies ............................................

2-8

 

2.6

Application Discovery...........................................................................................................................

2-9

Part 2: Core Concepts

 

3 Data Types and Data Samples ........................................................

3-1

 

3.1

Introduction to the Type System..........................................................................................................

3-3

 

 

3.1.1

Sequences...................................................................................................................................

3-4

 

 

3.1.2 Strings and Wide Strings .........................................................................................................

3-4

 

 

3.1.3

Introduction to TypeCode .......................................................................................................

3-4

 

3.2

Built-in Data Types ................................................................................................................................

3-5

 

 

3.2.1

Registering Built-in Types .......................................................................................................

3-6

v

3.2.2 Creating Topics for Built-in Types..........................................................................................

3-6

3.2.3 Creating ContentFilteredTopics for Built-in Types..............................................................

3-8

3.2.4

String Built-in Type ..................................................................................................................

3-9

3.2.5

KeyedString Built-in Type.....................................................................................................

3-13

3.2.6

Octets Built-in Type................................................................................................................

3-20

3.2.7

KeyedOctets Built-in Type ....................................................................................................

3-25

3.2.8 Managing Memory for Built-in Types.................................................................................

3-32

3.2.9 Type Codes for Built-in Types ..............................................................................................

3-36

3.3 Creating User Data Types with IDL ..................................................................................................

3-37

3.3.1

Variable-Length Types ...........................................................................................................

3-38

3.3.2

Value Types..............................................................................................................................

3-39

3.3.3

TypeCode and rtiddsgen .......................................................................................................

3-40

3.3.4 rtiddsgen Translations for IDL Types ..................................................................................

3-40

3.3.5

Escaped Identifiers .................................................................................................................

3-54

3.3.6 Referring to Other IDL Files .................................................................................................

3-55

3.3.7

Preprocessor Directives .........................................................................................................

3-55

3.3.8

Using Custom Directives.......................................................................................................

3-55

3.4 Creating User Data Types with Extensible Markup Language (XML) ........................................

3-61

3.5 Creating User Data Types with XML Schemas (XSD) ....................................................................

3-66

3.5.1

Primitive Types .......................................................................................................................

3-79

3.6 Using rtiddsgen....................................................................................................................................

3-79

3.6.1

rtiddsgen Command-Line Arguments................................................................................

3-81

3.7 Using Generated Types without Connext (Standalone).................................................................

3-85

3.7.1 Using Standalone Types in C ................................................................................................

3-85

3.7.2 Using Standalone Types in C++ ...........................................................................................

3-86

3.7.3 Standalone Types in Java.......................................................................................................

3-86

3.8 Interacting Dynamically with User Data Types ..............................................................................

3-87

3.8.1

Introduction to TypeCode .....................................................................................................

3-87

3.8.2

Defining New Types ..............................................................................................................

3-88

3.8.3 Sending Only a Few Fields ...................................................................................................

3-89

3.8.4 Type Extension and Versioning ............................................................................................

3-90

3.8.5 Sending Type Codes on the Network..................................................................................

3-91

3.9 Working with Data Samples...............................................................................................................

3-92

3.9.1 Objects of Concrete Types .....................................................................................................

3-93

3.9.2 Objects of Dynamically Defined Types ...............................................................................

3-94

4 Entities

................................................................................................

4-1

4.1 Common Operations for All Entities ..................................................................................................

4-1

4.1.1 Creating and Deleting Entities ...............................................................................................

4-2

4.1.2

Enabling Entities .......................................................................................................................

4-3

4.1.3 Getting an Entity’s Instance Handle......................................................................................

4-4

4.1.4 Getting Status and Status Changes........................................................................................

4-5

4.1.5 .................................................................................................Getting and Setting Listeners

4-5

4.1.6 ...................................................................................................

Getting the StatusCondition

4-5

4.1.7 .............................................................................................Getting and Setting QosPolicies

4-6

4.2 QosPolicies..............................................................................................................................................

4-9

4.2.1 .......................................QoS Requested vs. Offered Compatibility—the RxO Property

4-12

4.2.2 ............................................................Special QosPolicy Handling Considerations for C

4-13

vi

 

4.3

Statuses ..................................................................................................................................................

4-14

 

 

4.3.1 Types of Communication Status...........................................................................................

4-14

 

 

4.3.2 Special Status-Handling Considerations for C...................................................................

4-19

 

4.4

Listeners ................................................................................................................................................

4-19

 

 

4.4.1

Types of Listeners ...................................................................................................................

4-20

 

 

4.4.2 Creating and Deleting Listeners...........................................................................................

4-21

 

 

4.4.3 Special Considerations for Listeners in C ...........................................................................

4-21

 

 

4.4.4 Hierarchical Processing of Listeners....................................................................................

4-22

 

 

4.4.5 Operations Allowed within Listener Callbacks.................................................................

4-23

 

4.5

Exclusive Areas (EAs) .........................................................................................................................

4-23

 

 

4.5.1 Restricted Operations in Listener Callbacks.......................................................................

4-26

 

4.6

Conditions and WaitSets.....................................................................................................................

4-27

 

 

4.6.1 Creating and Deleting WaitSets............................................................................................

4-27

 

 

4.6.2

WaitSet Operations.................................................................................................................

4-29

 

 

4.6.3

Waiting for Conditions ..........................................................................................................

4-29

 

 

4.6.4 Processing Triggered Conditions—What to do when Wait() Returns ............................

4-30

 

 

4.6.5 Conditions and WaitSet Example.........................................................................................

4-31

 

 

4.6.6

GuardConditions....................................................................................................................

4-33

 

 

4.6.7

ReadConditions and QueryConditions...............................................................................

4-33

 

 

4.6.8

StatusConditions ....................................................................................................................

4-35

 

 

4.6.9 Using Both Listeners and WaitSets ......................................................................................

4-36

5

Topics .................................................................................................

 

5-1

 

5.1

Topics .......................................................................................................................................................

 

5-1

 

 

5.1.1

Creating Topics .........................................................................................................................

5-3

 

 

5.1.2

Deleting Topics..........................................................................................................................

5-4

 

 

5.1.3

Setting Topic QosPolicies ........................................................................................................

5-4

 

 

5.1.4 Copying QoS From a Topic to a DataWriter or DataReader ..............................................

5-7

 

 

5.1.5

Setting Up TopicListeners .......................................................................................................

5-7

 

 

5.1.6 Navigating Relationships Among Entities ...........................................................................

5-8

 

5.2

Topic QosPolicies ...................................................................................................................................

5-8

 

 

5.2.1

TOPIC_DATA QosPolicy.........................................................................................................

5-8

 

5.3

Status Indicator for Topics ..................................................................................................................

5-10

 

 

5.3.1

INCONSISTENT_TOPIC Status...........................................................................................

5-10

 

5.4

ContentFilteredTopics .........................................................................................................................

5-10

 

 

5.4.1

Overview ..................................................................................................................................

5-11

 

 

5.4.2 Where Filtering is Applied—Publishing vs. Subscribing Side ........................................

5-12

 

 

5.4.3

Creating ContentFilteredTopics............................................................................................

5-12

 

 

5.4.4

Deleting ContentFilteredTopics............................................................................................

5-14

 

 

5.4.5

Using a ContentFilteredTopic...............................................................................................

5-14

 

 

5.4.6 SQL Filter Expression Notation............................................................................................

5-16

 

 

5.4.7 STRINGMATCH Filter Expression Notation .....................................................................

5-24

 

 

5.4.8

Custom Content Filters..........................................................................................................

5-25

6

Sending Data.....................................................................................

6-1

 

6.1

Preview: Steps to Sending Data ...........................................................................................................

6-1

 

6.2

Publishers................................................................................................................................................

6-2

 

 

6.2.1 Creating Publishers Explicitly vs. Implicitly ........................................................................

6-3

vii

 

6.2.2

Creating Publishers ..................................................................................................................

6-5

 

6.2.3

Deleting Publishers ..................................................................................................................

6-7

 

6.2.4

Setting Publisher QosPolicies .................................................................................................

6-7

 

6.2.5

Setting Up PublisherListeners ..............................................................................................

6-13

 

6.2.6

Finding a Publisher’s Related Entities ................................................................................

6-15

 

6.2.7

Waiting for Acknowledgments in a Publisher ...................................................................

6-15

 

6.2.8

Statuses for Publishers...........................................................................................................

6-15

 

6.2.9

Suspending and Resuming Publications ............................................................................

6-16

6.3

DataWriters ...........................................................................................................................................

6-16

 

6.3.1

Creating DataWriters .............................................................................................................

6-19

 

6.3.2

Getting All DataWriters.........................................................................................................

6-20

 

6.3.3

Deleting DataWriters .............................................................................................................

6-20

 

6.3.4

Setting Up DataWriterListeners ...........................................................................................

6-21

 

6.3.5

Checking DataWriter Status..................................................................................................

6-22

 

6.3.6

Statuses for DataWriters ........................................................................................................

6-22

 

6.3.7

Using a Type-Specific DataWriter (FooDataWriter) ..........................................................

6-30

 

6.3.8

Writing Data ............................................................................................................................

6-31

 

6.3.9

Flushing Batches of Data Samples .......................................................................................

6-34

 

6.3.10

Writing Coherent Sets of Data Samples ..............................................................................

6-34

 

6.3.11

Waiting for Acknowledgments in a DataWriter ................................................................

6-34

 

6.3.12

Application Acknowledgment .............................................................................................

6-35

 

6.3.13

Required Subscriptions..........................................................................................................

6-39

 

6.3.14

Managing Data Instances (Working with Keyed Data Types).........................................

6-41

 

6.3.15

Setting DataWriter QosPolicies ............................................................................................

6-44

 

6.3.16

Navigating Relationships Among Entities .........................................................................

6-52

 

6.3.17

Asserting Liveliness ...............................................................................................................

6-53

6.4

Publisher/Subscriber QosPolicies.....................................................................................................

6-54

 

6.4.1

ASYNCHRONOUS_PUBLISHER QosPolicy (DDS Extension) ......................................

6-54

 

6.4.2

ENTITYFACTORY QosPolicy...............................................................................................

6-56

 

6.4.3

EXCLUSIVE_AREA QosPolicy (DDS Extension)..............................................................

6-58

 

6.4.4

GROUP_DATA QosPolicy ....................................................................................................

6-60

 

6.4.5

PARTITION QosPolicy ..........................................................................................................

6-62

 

6.4.6

PRESENTATION QosPolicy .................................................................................................

6-67

6.5

DataWriter QosPolicies .......................................................................................................................

6-71

 

6.5.1

AVAILABILITY QosPolicy (DDS Extension)......................................................................

6-72

 

6.5.2

BATCH QosPolicy (DDS Extension)....................................................................................

6-76

 

6.5.3

DATA_WRITER_PROTOCOL QosPolicy (DDS Extension).............................................

6-80

 

6.5.4

DATA_WRITER_RESOURCE_LIMITS QosPolicy (DDS Extension)..............................

6-90

 

6.5.5

DEADLINE QosPolicy...........................................................................................................

6-92

 

6.5.6

DESTINATION_ORDER QosPolicy ....................................................................................

6-94

 

6.5.7

DURABILITY QosPolicy .......................................................................................................

6-96

 

6.5.8

DURABILITY SERVICE QosPolicy......................................................................................

6-99

 

6.5.9

ENTITY_NAME QosPolicy (DDS Extension) ..................................................................

6-101

 

6.5.10

HISTORY QosPolicy ............................................................................................................

6-102

 

6.5.11

LATENCYBUDGET QoS Policy .........................................................................................

6-105

 

6.5.12

LIFESPAN QoS Policy..........................................................................................................

6-105

 

6.5.13

LIVELINESS QosPolicy .......................................................................................................

6-106

 

6.5.14

MULTI_CHANNEL QosPolicy (DDS Extension)............................................................

6-109

 

6.5.15

OWNERSHIP QosPolicy ......................................................................................................

6-111

viii

6.5.16

OWNERSHIP_STRENGTH QosPolicy ..............................................................................

6-114

6.5.17

PROPERTY QosPolicy (DDS Extension) ..........................................................................

6-115

6.5.18

PUBLISH_MODE QosPolicy (DDS Extension).................................................................

6-117

6.5.19

RELIABILITY QosPolicy ......................................................................................................

6-119

6.5.20

RESOURCE_LIMITS QosPolicy .........................................................................................

6-122

6.5.21

TRANSPORT_PRIORITY QosPolicy .................................................................................

6-125

6.5.22

TRANSPORT_SELECTION QosPolicy (DDS Extension)...............................................

6-126

6.5.23

TRANSPORT_UNICAST QosPolicy (DDS Extension) ...................................................

6-127

6.5.24

TYPESUPPORT QosPolicy (DDS Extension) ...................................................................

6-130

6.5.25

USER_DATA QosPolicy ......................................................................................................

6-131

6.5.26

WRITER_DATA_LIFECYCLE QoS Policy ........................................................................

6-132

6.6 FlowControllers (DDS Extension) ...................................................................................................

6-134

6.6.1

Flow Controller Scheduling Policies..................................................................................

6-136

6.6.2

Managing Fast DataWriters When Using a FlowController ..........................................

6-137

6.6.3

Token Bucket Properties ......................................................................................................

6-137

6.6.4

Prioritized Samples ..............................................................................................................

6-138

6.6.5

Creating and Configuring Custom FlowControllers with Property QoS ....................

6-141

6.6.6

Creating and Deleting FlowControllers ............................................................................

6-143

6.6.7

Getting/Setting Default FlowController Properties .......................................................

6-144

6.6.8

Getting/Setting Properties for a Specific FlowController ..............................................

6-144

6.6.9

Adding an External Trigger ................................................................................................

6-144

6.6.10

Other FlowController Operations......................................................................................

6-145

7

Receiving Data..................................................................................

7-1

 

7.1 Preview: Steps to Receiving Data ........................................................................................................

7-1

 

7.2

Subscribers ..............................................................................................................................................

7-3

 

 

7.2.1 Creating Subscribers Explicitly vs. Implicitly ......................................................................

7-6

 

 

7.2.2

Creating Subscribers ................................................................................................................

7-6

 

 

7.2.3

Deleting Subscribers ................................................................................................................

7-7

 

 

7.2.4

Setting Subscriber QosPolicies ...............................................................................................

7-8

 

 

7.2.5 Beginning and Ending Group-Ordered Access .................................................................

7-13

 

 

7.2.6

Setting Up SubscriberListeners ............................................................................................

7-13

 

 

7.2.7 Getting DataReaders with Specific Samples ......................................................................

7-15

 

 

7.2.8 Finding a Subscriber’s Related Entities...............................................................................

7-15

 

 

7.2.9

Statuses for Subscribers .........................................................................................................

7-16

 

7.3

DataReaders..........................................................................................................................................

7-17

 

 

7.3.1

Creating DataReaders ............................................................................................................

7-20

 

 

7.3.2

Getting All DataReaders........................................................................................................

7-21

 

 

7.3.3

Deleting DataReaders ............................................................................................................

7-21

 

 

7.3.4

Setting Up DataReaderListeners ..........................................................................................

7-22

 

 

7.3.5 Checking DataReader Status and StatusConditions .........................................................

7-22

 

 

7.3.6 Waiting for Historical Data ...................................................................................................

7-24

 

 

7.3.7

Statuses for DataReaders.......................................................................................................

7-24

 

 

7.3.8

Setting DataReader QosPolicies ...........................................................................................

7-33

 

 

7.3.9 Navigating Relationships Among Entities .........................................................................

7-38

 

7.4 Using DataReaders to Access Data (Read & Take) .........................................................................

7-39

 

 

7.4.1 Using a Type-Specific DataReader (FooDataReader)........................................................

7-39

 

 

7.4.2 Loaning and Returning Data and SampleInfo Sequences................................................

7-39

 

 

7.4.3 Accessing Data Samples with Read or Take.......................................................................

7-40

ix

 

7.4.4

Acknowledging Samples.......................................................................................................

7-46

 

7.4.5 The Sequence Data Structure................................................................................................

7-47

 

7.4.6

The SampleInfo Structure......................................................................................................

7-48

7.5

Subscriber QosPolicies ........................................................................................................................

7-52

7.6

DataReader QosPolicies ......................................................................................................................

7-52

 

7.6.1 DATA_READER_PROTOCOL QosPolicy (DDS Extension)............................................

7-52

 

7.6.2 DATA_READER_RESOURCE_LIMITS QosPolicy (DDS Extension) .............................

7-57

 

7.6.3

READER_DATA_LIFECYCLE QoS Policy .........................................................................

7-62

 

7.6.4

TIME_BASED_FILTER QosPolicy .......................................................................................

7-64

 

7.6.5 TRANSPORT_MULTICAST QosPolicy (DDS Extension) ................................................

7-66

 

7.6.6

TYPE_CONSISTENCY_ENFORCEMENT QosPolicy ......................................................

7-69

8 Working with Domains ......................................................................

8-1

8.1 Fundamentals of Domains and DomainParticipants .......................................................................

8-1

8.2

DomainParticipantFactory ...................................................................................................................

8-3

 

8.2.1

Setting DomainParticipantFactory QosPolicies ...................................................................

8-5

 

8.2.2

Getting and Setting Default QoS for DomainParticipants .................................................

8-6

 

8.2.3

Freeing Resources Used by the DomainParticipantFactory...............................................

8-6

 

8.2.4

Looking Up a DomainParticipant..........................................................................................

8-6

 

8.2.5

Getting QoS Values from a QoS Profile.................................................................................

8-7

8.3

DomainParticipants...............................................................................................................................

8-7

 

8.3.1

Creating a DomainParticipant...............................................................................................

8-11

 

8.3.2

Deleting DomainParticipants ...............................................................................................

8-13

 

8.3.3

Deleting Contained Entities ..................................................................................................

8-13

 

8.3.4

Choosing a Domain ID and Creating Multiple Domains.................................................

8-13

 

8.3.5

Setting Up DomainParticipantListeners .............................................................................

8-14

 

8.3.6

Setting DomainParticipant QosPolicies ..............................................................................

8-16

 

8.3.7

Looking up Topic Descriptions ............................................................................................

8-21

 

8.3.8

Finding a Topic .......................................................................................................................

8-21

 

8.3.9

Getting the Implicit Publisher or Subscriber......................................................................

8-21

 

8.3.10

Asserting Liveliness ...............................................................................................................

8-22

 

8.3.11

Learning about Discovered DomainParticipants ..............................................................

8-23

 

8.3.12

Learning about Discovered Topics.......................................................................................

8-23

 

8.3.13

Other DomainParticipant Operations .................................................................................

8-23

8.4

DomainParticipantFactory QosPolicies............................................................................................

8-24

 

8.4.1

LOGGING QosPolicy (DDS Extension) ..............................................................................

8-24

 

8.4.2

PROFILE QosPolicy (DDS Extension) ................................................................................

8-25

 

8.4.3

SYSTEM_RESOURCE_LIMITS QoS Policy (DDS Extension)..........................................

8-27

8.5

DomainParticipant QosPolicies .........................................................................................................

8-28

 

8.5.1

DATABASE QosPolicy (DDS Extension) ............................................................................

8-28

 

8.5.2

DISCOVERY QosPolicy (DDS Extension)...........................................................................

8-30

 

8.5.3

DISCOVERY_CONFIG QosPolicy (DDS Extension).........................................................

8-34

 

8.5.4

DOMAIN_PARTICIPANT_RESOURCE_LIMITS QosPolicy (DDS Extension) ............

8-41

 

8.5.5

EVENT QosPolicy (DDS Extension) ....................................................................................

8-46

 

8.5.6

RECEIVER_POOL QosPolicy (DDS Extension).................................................................

8-48

 

8.5.7

TRANSPORT_BUILTIN QosPolicy (DDS Extension) .......................................................

8-49

 

8.5.8

TRANSPORT_MULTICAST_MAPPING QosPolicy (DDS Extension)...........................

8-50

 

8.5.9

WIRE_PROTOCOL QosPolicy (DDS Extension)...............................................................

8-52

x

8.6

Clock Selection .....................................................................................................................................

8-58

 

8.6.1

Available Clocks .....................................................................................................................

8-58

 

8.6.2

Clock Selection Strategy ........................................................................................................

8-58

8.7

System Properties.................................................................................................................................

8-59

9 Building Applications........................................................................

9-1

9.1

Running on a Computer Not Connected to a Network ...................................................................

9-1

9.2

Connext Header Files — All Architectures........................................................................................

9-2

9.3

UNIX-Based Platforms..........................................................................................................................

9-2

 

9.3.1

Required Libraries....................................................................................................................

9-3

 

9.3.2

Compiler Flags..........................................................................................................................

9-3

9.4

Windows Platforms ...............................................................................................................................

9-3

 

9.4.1 Using Microsoft Visual C++ 6.0..............................................................................................

9-4

 

9.4.2 Using Visual Studio .NET, Visual Studio .NET 2003, or Visual Studio 2005 ...................

9-5

9.5

Java Platforms.........................................................................................................................................

9-6

 

9.5.1

Java Libraries.............................................................................................................................

9-6

 

9.5.2

Native Libraries ........................................................................................................................

9-6

Part 3: Advanced Concepts

10 Reliable Communications..............................................................

10-1

10.1

Sending Data Reliably .........................................................................................................................

10-1

 

10.1.1

Best-effort Delivery Model....................................................................................................

10-1

 

10.1.2

Reliable Delivery Model........................................................................................................

10-2

10.2

Overview of the Reliable Protocol.....................................................................................................

10-3

10.3

Using QosPolicies to Tune the Reliable Protocol.............................................................................

10-6

 

10.3.1

Enabling Reliability................................................................................................................

10-7

 

10.3.2 Tuning Queue Sizes and Other Resource Limits ...............................................................

10-7

 

10.3.3 Controlling Queue Depth with the History QosPolicy...................................................

10-13

 

10.3.4 Controlling Heartbeats and Retries with DataWriterProtocol QosPolicy....................

10-13

 

10.3.5 Avoiding Message Storms with DataReaderProtocol QosPolicy ..................................

10-19

 

10.3.6 Resending Samples to Late-Joiners with the Durability QosPolicy..............................

10-19

 

10.3.7

Use Cases ...............................................................................................................................

10-20

11 Collaborative DataWriters..............................................................

11-1

11.1

Collaborative DataWriters Use Cases ................................................................................................

11-2

11.2

Sample Combination (Synchronization) Process in a DataReader................................................

11-3

11.3

Configuring Collaborative DataWriters ............................................................................................

11-3

 

11.3.1 Assocating Virtual GUIDs with Data Samples....................................................................

11-3

 

11.3.2 Assocating Virtual Sequence Numbers with Data Samples..............................................

11-3

 

11.3.3 Specifying which DataWriters will Deliver Samples to the DataReader from a Logical

 

Data Source11-3

 

 

11.3.4 Specifying How Long to Wait for a Missing Sample .........................................................

11-4

11.4

Collaborative DataWriters and Persistence Service.........................................................................

11-4

xi

12

Mechanisms for Achieving Information Durability and

 

 

Persistence .................................................................................................

12-1

 

12.1

Introduction ..........................................................................................................................................

12-1

 

 

12.1.1 Scenario 1. DataReader Joins after DataWriter Restarts (Durable Writer History).......

12-2

 

 

12.1.2 Scenario 2: DataReader Restarts While DataWriter Stays Up (Durable Reader State). 12-2

 

 

12.1.3 Scenario 3. DataReader Joins after DataWriter Leaves Domain (Durable Data) ..........

12-3

 

12.2

Durability and Persistence Based on Virtual GUIDs ......................................................................

12-4

 

12.3

Durable Writer History .......................................................................................................................

12-5

 

 

12.3.1 Durable Writer History Use Case.........................................................................................

12-5

 

 

12.3.2 How To Configure Durable Writer History........................................................................

12-6

 

12.4

Durable Reader State...........................................................................................................................

12-9

 

 

12.4.1 Durable Reader State With Protocol Acknowledgment ...................................................

12-9

 

 

12.4.2

Durable Reader State with Application Acknowledgment ..........................................

12-10

 

 

12.4.3 Durable Reader State Use Case ...........................................................................................

12-11

 

 

12.4.4 How To Configure a DataReader for Durable Reader State ...........................................

12-11

 

12.5

Data Durability...................................................................................................................................

12-13

 

 

12.5.1

RTI Persistence Service ........................................................................................................

12-13

13

Guaranteed Delivery of Data ........................................................

13-1

 

13.1

Introduction ..........................................................................................................................................

13-1

 

 

13.1.1 Identifying the Required Consumers of Information .......................................................

13-2

 

 

13.1.2 Ensuring Consumer Applications Process the Data Successfully...................................

13-3

 

 

13.1.3 Ensuring Information is Available to Late-Joining Applications ....................................

13-4

 

13.2

Scenarios................................................................................................................................................

13-5

 

 

13.2.1 Scenario 1: Guaranteed Delivery to a-priori known subscribers ....................................

13-5

 

 

13.2.2 Scenario 2: Surviving a Writer Restart when Delivering Samples to a priori Known

 

 

 

Subscribers...............................................................................................................................

13-7

 

 

13.2.3 Scenario 3: Delivery Guaranteed by Persistence Service (Store and Forward) to

 

 

 

 

a priori Known Subscribers ..................................................................................................

13-7

14

Discovery .........................................................................................

14-1

 

14.1

What is Discovery? ..............................................................................................................................

14-1

 

 

14.1.1

Simple Participant Discovery ...............................................................................................

14-2

 

 

14.1.2

Simple Endpoint Discovery ..................................................................................................

14-2

 

14.2

Configuring the Peers List Used in Discovery ................................................................................

14-3

 

 

14.2.1

Peer Descriptor Format..........................................................................................................

14-4

 

 

14.2.2 NDDS_DISCOVERY_PEERS Environment Variable Format...........................................

14-6

 

 

14.2.3

NDDS_DISCOVERY_PEERS File Format...........................................................................

14-7

 

14.3

Discovery Implementation .................................................................................................................

14-8

 

 

14.3.1

Participant Discovery.............................................................................................................

14-9

 

 

14.3.2

Endpoint Discovery .............................................................................................................

14-15

 

 

14.3.3

Discovery Traffic Summary ............................................................................................

14-20

 

 

14.3.4

Discovery-Related QoS........................................................................................................

14-20

 

14.4

Debugging Discovery........................................................................................................................

14-21

 

14.5

Ports Used for Discovery ..................................................................................................................

14-23

 

 

14.5.1 Inbound Ports for Meta-Traffic...........................................................................................

14-25

 

 

14.5.2 Inbound Ports for User Traffic............................................................................................

14-25

xii

 

 

14.5.3 Automatic Selection of participant_id and Port Reservation ........................................

14-25

 

 

14.5.4 Tuning domain_id_gain and participant_id_gain...........................................................

14-25

15

Transport Plugins .............................................................................

15-1

 

15.1

Builtin Transport Plugins....................................................................................................................

15-2

 

15.2

Extension Transport Plugins ..............................................................................................................

15-2

 

15.3

The NDDSTransportSupport Class ...................................................................................................

15-3

 

15.4

Explicitly Creating Builtin Transport Plugin Instances ..................................................................

15-3

 

15.5

Setting Builtin Transport Properties of the Default Transport Instance

 

 

 

—get/set_builtin_transport_properties().........................................................................................

15-4

 

15.6

Setting Builtin Transport Properties with the PropertyQosPolicy................................................

15-5

 

 

15.6.1 Notes Regarding Loopback and Shared Memory ...........................................................

15-19

 

 

15.6.2 Setting the Maximum Gather-Send Buffer Count for UDPv4 and UDPv6..................

15-19

 

 

15.6.3 Formatting Rules for IPv6 ‘Allow’ and ‘Deny’ Address Lists .......................................

15-20

 

15.7

Installing Additional Builtin Transport Plugins with register_transport() ...............................

15-20

 

 

15.7.1

Transport Lifecycles .............................................................................................................

15-21

 

 

15.7.2

Transport Aliases ..................................................................................................................

15-22

 

 

15.7.3

Transport Network Addresses ...........................................................................................

15-22

 

15.8

Installing Additional Builtin Transport Plugins with PropertyQosPolicy ................................

15-23

 

15.9

Other Transport Support Operations.............................................................................................

15-24

 

 

15.9.1 Adding a Send Route...........................................................................................................

15-24

 

 

15.9.2 Adding a Receive Route ......................................................................................................

15-24

 

 

15.9.3 Looking Up a Transport Plugin..........................................................................................

15-25

16

Built-In Topics...................................................................................

16-1

 

16.1

Listeners for Built-in Entities..............................................................................................................

16-1

 

16.2

Built-in DataReaders ...........................................................................................................................

16-2

 

 

16.2.1 LOCATOR_FILTER QoS Policy (DDS Extension) .............................................................

16-8

 

16.3

Accessing the Built-in Subscriber ......................................................................................................

16-9

 

16.4

Restricting Communication—Ignoring Entities............................................................................

16-10

 

 

16.4.1 Ignoring Specific Remote DomainParticipants.................................................................

16-11

 

 

16.4.2 Ignoring Publications and Subscriptions..........................................................................

16-12

 

 

16.4.3

Ignoring Topics .....................................................................................................................

16-12

17 Configuring QoS with XML..............................................................

17-1

 

17.1

Example XML File................................................................................................................................

17-2

 

17.2

How to Load XML-Specified QoS Settings ......................................................................................

17-2

 

 

17.2.1 Loading, Reloading and Unloading Profiles......................................................................

17-3

 

17.3

How to Use XML-Specified QoS Settings ........................................................................................

17-4

 

17.4

XML File Syntax ...................................................................................................................................

17-6

 

17.5

Using Environment Variables in XML..............................................................................................

17-6

 

17.6

XML String Syntax...............................................................................................................................

17-7

 

17.7

How the XML is Validated .................................................................................................................

17-7

 

 

17.7.1

Validation at Run-Time..........................................................................................................

17-7

 

 

17.7.2 XML File Validation During Editing ...................................................................................

17-8

xiii

17.8

Configuring QoS with XML ...............................................................................................................

17-9

 

17.8.1

QosPolicies ..............................................................................................................................

17-9

 

17.8.2

Sequences...............................................................................................................................

17-10

 

17.8.3

Arrays.....................................................................................................................................

17-12

 

17.8.4

Enumeration Values .............................................................................................................

17-13

 

17.8.5

Time Values (Durations)......................................................................................................

17-13

 

17.8.6

Transport Properties.............................................................................................................

17-13

 

17.8.7

Thread Settings .....................................................................................................................

17-14

17.9

QoS Profiles.........................................................................................................................................

17-14

 

17.9.1

QoS Profiles with a Single QoS...........................................................................................

17-15

 

17.9.2

QoS Profile Inheritance........................................................................................................

17-15

 

17.9.3

Topic Filters ...........................................................................................................................

17-18

 

17.9.4

Overwriting Default QoS Values........................................................................................

17-20

 

17.9.5

Get Qos Profiles ....................................................................................................................

17-21

17.10

QoS Libraries ......................................................................................................................................

17-21

 

17.10.1 Get Qos Profile Libraries .....................................................................................................

17-22

17.11

URL Groups........................................................................................................................................

17-22

17.12

Configuring Logging Via XML ........................................................................................................

17-23

18 Multi-channel DataWriters .............................................................

18-1

18.1

What is a Multi-channel DataWriter?................................................................................................

18-2

18.2

How to Configure a Multi-channel DataWriter...............................................................................

18-4

 

18.2.1

Limitations...............................................................................................................................

18-5

18.3

Multi-channel Configuration on the Reader Side ...........................................................................

18-6

18.4

Where Does the Filtering Occur?.......................................................................................................

18-7

 

18.4.1 Filtering at the DataWriter ....................................................................................................

18-7

 

18.4.2 Filtering at the DataReader ...................................................................................................

18-8

 

18.4.3 Filtering on the Network Hardware....................................................................................

18-8

18.5

Fault Tolerance and Redundancy ......................................................................................................

18-8

18.6

Reliability with Multi-Channel DataWriters....................................................................................

18-9

 

18.6.1

Reliable Delivery ....................................................................................................................

18-9

 

18.6.2

Reliable Protocol Considerations .......................................................................................

18-10

18.7

Performance Considerations .............................................................................................................

18-11

 

18.7.1

Network-Switch Filtering.....................................................................................................

18-11

 

18.7.2 DataWriter and DataReader Filtering.................................................................................

18-11

19

Connext Threading Model .............................................................

19-1

 

19.1

Database Thread...................................................................................................................................

19-1

 

19.2

Event Thread.........................................................................................................................................

19-2

 

19.3

Receive Threads ...................................................................................................................................

19-3

 

19.4

Exclusive Areas, Connext Threads and User Listeners..................................................................

19-4

 

19.5

Controlling CPU Core Affinity for RTI Threads..............................................................................

19-5

20

Sample-Data Memory Management ...........................................

20-1

 

20.1

Sample-Data Memory Management for DataWriters.....................................................................

20-1

 

 

20.1.1 Memory Management without Batching............................................................................

20-2

xiv

20.1.2 Memory Management with Batching .................................................................................

20-2

20.1.3 Writer-Side Memory Management when Using Java .......................................................

20-3

20.1.4 Writer-Side Memory Management when Working with Large Data .............................

20-4

20.2 Sample-Data Memory Management for DataReaders ...................................................................

20-6

20.2.1 Memory Management for DataReaders Using Generated Type-Plugins ......................

20-6

20.2.2 Reader-Side Memory Management when Using Java......................................................

20-7

20.2.3 Memory Management for DynamicData DataReaders ....................................................

20-8

20.2.6 Memory Management for Fragmented Samples .............................................................

20-10

20.2.7 Reader-Side Memory Management when Working with Large Data ..........................

20-10

21 Troubleshooting...............................................................................

21-1

21.1

What Version am I Running? .............................................................................................................

21-1

 

21.1.1 Finding Version Information in Revision Files ..................................................................

21-1

 

21.1.2 Finding Version Information Programmatically................................................................

21-1

21.2

Controlling Messages from Connext.................................................................................................

21-2

 

21.2.1 Format of Logged Messages .................................................................................................

21-3

 

21.2.2 Configuring Logging via XML .............................................................................................

21-6

 

21.2.3 Customizing the Handling of Generated Log Messages..................................................

21-7

Part 4: Request-Reply Communication Pattern

22

Introduction to the Request-Reply Communication Pattern ......

22-1

 

22.1

The Request-Reply Pattern .................................................................................................................

22-2

 

 

22.1.1

Request-Reply Correlation....................................................................................................

22-3

 

22.2

Single-Request, Multiple-Replies ......................................................................................................

22-3

 

22.3

Multiple Repliers..................................................................................................................................

22-4

 

22.4

Combining Request-Reply and Publish-Subscribe .........................................................................

22-5

23

Using the Request-Reply Communication Pattern ......................

23-1

 

23.1

Requesters .............................................................................................................................................

23-2

 

 

23.1.1

Creating a Requester ..............................................................................................................

23-2

 

 

23.1.2

Destroying a Requester..........................................................................................................

23-3

 

 

23.1.3

Setting Requester Parameters ...............................................................................................

23-3

 

 

23.1.4 Summary of Requester Operations......................................................................................

23-4

 

 

23.1.5

Sending Requests....................................................................................................................

23-5

 

 

23.1.6 Processing Incoming Replies with a Requester .................................................................

23-5

 

23.2

Repliers..................................................................................................................................................

23-8

 

 

23.2.1

Creating a Replier...................................................................................................................

23-9

 

 

23.2.2

Destroying a Replier ..............................................................................................................

23-9

 

 

23.2.3

Setting Replier Parameters..................................................................................................

23-10

 

 

23.2.4 Summary of Replier Operations.........................................................................................

23-10

 

 

23.2.5 Processing Incoming Requests with a Replier ..................................................................

23-11

 

 

23.2.6

Sending Replies ....................................................................................................................

23-13

 

23.3

SimpleRepliers....................................................................................................................................

23-13

 

 

23.3.1

Creating a SimpleReplier.....................................................................................................

23-14

 

 

23.3.2

Destroying a SimpleReplier ................................................................................................

23-14

xv

23.3.3

Setting SimpleReplier Parameters......................................................................................

23-14

23.3.4

Getting Requests and Sending Replies with a SimpleReplierListener .........................

23-14

23.4 Accessing Underlying DataWriters and DataReaders..................................................................

23-15

Part 5: RTI Secure WAN Transport

24 Secure WAN Transport ....................................................................

24-1

24.1

WAN Traversal via UDP Hole-Punching .........................................................................................

24-2

 

24.1.1

Protocol Details.......................................................................................................................

24-2

24.2

WAN Locators ......................................................................................................................................

24-5

24.3

Datagram Transport-Layer Security (DTLS)....................................................................................

24-6

 

24.3.1

Security Model........................................................................................................................

24-6

 

24.3.2

Liveliness Mechanism............................................................................................................

24-7

24.4

Certificate Support...............................................................................................................................

24-7

24.5

License Issues .......................................................................................................................................

24-8

25 Configuring RTI Secure WAN Transport .........................................

25-1

25.1

Example Applications .........................................................................................................................

25-1

25.2

Setting Up a Transport with the Property QoS................................................................................

25-2

25.3

WAN Transport Properties .................................................................................................................

25-3

25.4

Secure Transport Properties................................................................................................................

25-8

25.5

Explicitly Instantiating a WAN or Secure Transport Plugin.........................................................

25-11

 

25.5.1 Additional Header Files and Include Directories............................................................

25-12

 

25.5.2

Additional Libraries.............................................................................................................

25-12

 

25.5.3

Compiler Flags......................................................................................................................

25-12

Part 6: RTI Persistence Service

26

Introduction to RTI Persistence Service.........................................

26-1

27

Configuring Persistence Service....................................................

27-1

 

27.1

How to Load the XML Configuration...............................................................................................

27-1

 

27.2

XML Configuration File ......................................................................................................................

27-2

 

 

27.2.1

Configuration File Syntax .....................................................................................................

27-3

 

 

27.2.2

XML Validation.......................................................................................................................

27-4

 

27.3

QoS Configuration...............................................................................................................................

27-5

 

27.4

Configuring the Persistence Service Application............................................................................

27-6

 

27.5

Configuring Remote Administration................................................................................................

27-7

 

27.6

Configuring Persistent Storage ..........................................................................................................

27-8

 

27.7

Configuring Participants....................................................................................................................

27-11

 

27.8

Creating Persistence Groups ............................................................................................................

27-12

 

 

27.8.1

QoSs........................................................................................................................................

27-16

xvi

 

 

27.8.2

DurabilityService QoS Policy..............................................................................................

27-16

 

 

27.8.3

Sharing a Publisher/Subscriber .........................................................................................

27-17

 

 

27.8.4

Sharing a Database Connection..........................................................................................

27-17

 

 

27.8.5

Memory Management .........................................................................................................

27-17

 

27.9

Configuring Durable Subscriptions in Persistence Service .........................................................

27-18

 

 

27.9.1

Sample Memory Management With Durable Subscriptions .........................................

27-19

 

27.10

Synchronizing of Persistence Service Instances ............................................................................

27-20

 

27.11

Enabling RTI Distributed Logger in Persistence Service .............................................................

27-20

 

27.12

Enabling RTI Monitoring Library in Persistence Service.............................................................

27-21

 

27.13

Support for Extensible Types ...........................................................................................................

27-21

 

 

27.13.1 Type Version Discrimination...............................................................................................

27-22

28

Running RTI Persistence Service ....................................................

28-1

 

28.1

Starting Persistence Service ................................................................................................................

28-1

 

28.2

Stopping Persistence Service..............................................................................................................

28-2

29

Administering Persistence Service from a Remote Location......

29-1

 

29.1

Enabling Remote Administration......................................................................................................

29-1

 

29.2

Remote Commands .............................................................................................................................

29-1

 

 

29.2.1

start ...........................................................................................................................................

29-2

 

 

29.2.2

stop ...........................................................................................................................................

29-2

 

 

29.2.3

shutdown.................................................................................................................................

29-2

 

 

29.2.4

status.........................................................................................................................................

29-2

 

29.3

Accessing Persistence Service from a Connext Application..........................................................

29-2

30

Advanced Persistence Service Scenarios ...................................

30-1

 

30.1

Scenario: Load-balanced Persistence Services .................................................................................

30-1

 

30.2

Scenario: Delegated Reliability .........................................................................................................

30-2

 

30.3

Scenario: Slow Consumer ...................................................................................................................

30-3

Part 7: RTI CORBA Compatibility Kit

31

Introduction to RTI CORBA Compatibility Kit ................................

31-1

32

Generating CORBA-Compatible Code with rtiddsgen...............

32-1

 

32.1

Generating C++ Code..........................................................................................................................

32-2

 

32.2

Generating Java Code..........................................................................................................................

32-2

xvii

33 Supported IDL Types .......................................................................

33-1

Part 8: RTI RTSJ Extension Kit

34

Introduction to RTI RTSJ Extension Kit.............................................

34-1

35

Using RTI RTSJ Extension Kit ............................................................

35-1

Part 9: RTI TCP Transport

36 Configuring the RTI TCP Transport..................................................

36-1

36.1 TCP Communication Scenarios .........................................................................................................

36-1

36.1.1 Communication Within a Single LAN ................................................................................

36-1

36.1.2 Symmetric Communication Across NATs ..........................................................................

36-2

36.1.3 Asymmetric Communication Across NATs .......................................................................

36-3

36.2 Configuring the TCP Transport .........................................................................................................

36-4

36.2.1 Choosing a Transport Mode .................................................................................................

36-4

36.2.2 Explicitly Instantiating the TCP Transport Plugin ............................................................

36-5

36.2.3 Configuring the TCP Transport with the Property QosPolicy.........................................

36-6

36.2.4 Setting the Initial Peers ..........................................................................................................

36-8

36.2.5 TCP/TLS Transport Properties.............................................................................................

36-8

xviii

Welcome to RTI Connext

RTI Connext solutions provide a flexible data distribution infrastructure for integrating data sources of all types. At its core is the world's leading ultra-high performance, distributed net- working DataBus™. It connects data within applications as well as across devices, systems and networks. Connext also delivers large data sets with microsecond performance and granular quality-of-service control. Connext is a standards-based, open architecture that connects devices from deeply embedded real-time platforms to enterprise servers across a variety of networks.

Conventions

The terminology and example code in this manual assume you are using C++ without namespace support.

C, C++/CLI, C#, and Java APIs are also available; they are fully described in the API Reference HTML documentation.

Namespace support in C++, C++/CLI, and C# is also available; see the API Reference HTML documentation (from the Modules page, select Using DDS:: Namespace) for details.

Extensions to the DDS Standard

Connext implements the DDS Standard published by the OMG. It also includes features that are extensions to DDS. These include additional Quality of Service parameters, function calls, struc- ture fields, etc.

Extensions also include product-specific APIs that complement the DDS API. These include APIs to create and use transport plug-ins, and APIs to control the verbosity and logging capabil- ities. These APIs are prefixed with NDDS, such as NDDSTransportSup- port::register_transport().

Environment Variables

Connext documentation refers to pathnames that have been customized during installation. NDDSHOME refers to the installation directory of Connext.

Names of Supported Platforms

Connext runs on several different target platforms. To support this vast array of platforms, Con- next separates the executable, library, and object files for each platform into individual directo- ries.

xix

Each platform name has four parts: hardware architecture, operating system, operating system version and compiler. For example, i86Linux2.4gcc3.2 is the directory that contains files specific to Linux® version 2.4 for the Intel processor, compiled with gcc version 3.2.

For a full list of supported platforms, see the Platform Notes.

Additional Resources

The details of each API (such as function parameters, return values, etc.) and examples are in the API Reference HTML documentation. In case of discrepancies between the information in this document and the API Reference HTML documentation, the latter should be considered more up-to-date.

xx

Part 1: Introduction

This introduces the general concepts behind data-centric publish-subscribe communications and provides a brief tour of Connext.

Chapter 1: Overview

Chapter 2: Data-Centric Publish-Subscribe Communications

1

Chapter 1 Overview

RTI Connext (formerly, RTI Data Distribution Service) is network middleware for distributed real- time applications. Connext simplifies application development, deployment and maintenance and provides fast, predictable distribution of time-critical data over a variety of transport net- works.

With Connext, you can:

Perform complex one-to-many and many-to-many network communications.

Customize application operation to meet various real-time, reliability, and quality-of-ser- vice goals.

Provide application-transparent fault tolerance and application robustness.

Use a variety of transports.

This chapter introduces basic concepts of middleware and common communication models, and describes how Connext’s feature-set addresses the needs of real-time systems.

1.1What is Connext?

Connext is network middleware for real-time distributed applications. It provides the communi- cations service programmers need to distribute time-critical data between embedded and/or enterprise devices or nodes. Connext uses the publish-subscribe communications model to make data distribution efficient and robust.

Connext implements the Data-Centric Publish-Subscribe (DCPS) API within the OMG’s Data Distribution Service (DDS) for Real-Time Systems. DDS is the first standard developed for the needs of real-time systems. DCPS provides an efficient way to transfer data in a distributed sys- tem.

With Connext, systems designers and programmers start with a fault-tolerant and flexible com- munications infrastructure that will work over a wide variety of computer hardware, operating systems, languages, and networking transport protocols. Connext is highly configurable so pro- grammers can adapt it to meet the application’s specific communication requirements.

1-1

What is Middleware?

1.2What is Middleware?

Middleware is a software layer between an application and the operating system. Network middle- ware isolates the application from the details of the underlying computer architecture, operating system and network stack (see Figure 1.1). Network middleware simplifies the development of distributed systems by allowing applications to send and receive information without having to program using lower-level protocols such as sockets and TCP or UDP/IP.

Figure 1.1 Network Middleware

Connext is middleware that insulates applications from the raw operating-system network stack.

Publish-subscribe middleware Connext is based on a publish-subscribe communications model. Publish-subscribe (PS) middleware provides a simple and intuitive way to distribute data. It decouples the software that creates and sends data—the data publishers—from the software that receives and uses the data—the data subscribers. Publishers simply declare their intent to send and then publish the data. Subscribers declare their intent to receive, then the data is automati- cally delivered by the middleware.

Despite the simplicity of the model, PS middleware can handle complex patterns of information flow. The use of PS middleware results in simpler, more modular distributed applications. Per- haps most importantly, PS middleware can automatically handle all network chores, including connections, failures, and network changes, eliminating the need for user applications to pro- gram of all those special cases. What experienced network middleware developers know is that handling special cases accounts for over 80% of the effort and code.

1.3Network Communications Models

The communications model underlying the network middleware is the most important factor in how applications communicate. The communications model impacts the performance, the ease to accomplish different communication transactions, the nature of detecting errors, and the robustness to different error conditions. Unfortunately, there is no “one size fits all” approach to distributed applications. Different communications models are better suited to handle different classes of application domains.

This section describes three main types of network communications models:

Point-to-point

Client-server

1-2

Network Communications Models

Publish-subscribe

Point-to-point model Point-to-point is the simplest form of communication, as illustrated in Figure 1.2. The telephone is an example of an everyday point-to-point communications device. To use a telephone, you must know the address (phone number) of the other party. Once a con- nection is established, you can have a reasonably high-bandwidth conversation. However, the telephone does not work as well if you have to talk to many people at the same time. The tele- phone is essentially one-to-one communication.

TCP is a point-to-point network protocol designed in the 1970s. While it provides reliable, high- bandwidth communication, TCP is cumbersome for systems with many communicating nodes.

Figure 1.2 Point-to-Point

A

B

Point-to-point is one-to-one communications.

Client-server model To address the scalability issues of the Point-to-Point model, developers turned to the Client-Server model. Client-server networks designate one special server node that connects simultaneously to many client nodes, as illustrated in Figure 1.3. Client-server is a "many-to-one" architecture. Ordering pizza over the phone is an example of client-server com- munication. Clients must know the phone number of the pizza parlor to place an order. The par- lor can handle many orders without knowing ahead of time where people (clients) are located. After the order (request), the parlor asks the client where the response (pizza) should be sent. In the client-server model, each response is tied to a prior request. As a result, the response can be tailored to each request. In other words, each client makes a request (order) and each reply (pizza) is made for one specific client in mind.

The client-server network architecture works best when information is centralized, such as in databases, transaction processing systems, and file servers. However, if information is being generated at multiple nodes, a client-server architecture requires that all information are sent to the server for later redistribution to the clients. This approach is inefficient and precludes deter- ministic communications, since the client does not know when new information is available. The time between when the information is available on the server, and when the client asks and receives it adds a variable latency to the system.

Figure 1.3 Client-Server

Client

Client

 

Server

request

Client

Client

reply

 

Client-server is many-to-one communications.

Publish-subscribe model In the publish-subscribe communications model, computer applica- tions (nodes) “subscribe” to data they need and “publish” data they want to share. Messages pass directly between the publisher and the subscribers, rather than moving into and out of a centralized server. Most time-sensitive information intended to reach many people is sent by a publish-subscribe system. Examples of publish-subscribe systems in everyday life include tele- vision, magazines, and newspapers.

1-3

Features of Connext

Publish-subscribe communication architectures are good for distributing large quantities of time-sensitive information efficiently, even in the presence of unreliable delivery mechanisms. This direct and simultaneous communication among a variety of nodes makes publish-sub- scribe network architecture the best choice for systems with complex time-critical data flows.

While the publish-subscribe model provides system architects with many advantages, it may not be the best choice for all types of communications, including:

File-based transfers (alternate solution: FTP)

Remote Method Invocation (alternate solutions: CORBA, COM, SOAP)

Connection-based architectures (alternate solution: TCP/IP)

Synchronous transfers (alternate solution: CORBA)

Figure 1.4 Publish-Subscribe

Subscriber

Subscriber

 

Publisher

Subscriber

Publisher

Publish-subscribe is many-to-many communications.

1.4Features of Connext

Connext supports mechanisms that go beyond the basic publish-subscribe model. The key bene- fit is that applications that use Connext for their communications are entirely decoupled. Very lit- tle of their design time has to be spent on how to handle their mutual interactions. In particular, the applications never need information about the other participating applications, including their existence or locations. Connext automatically handles all aspects of message delivery, with- out requiring any intervention from the user applications, including:

determining who should receive the messages,

where recipients are located,

what happens if messages cannot be delivered.

This is made possible by how Connext allows the user to specify Quality of Service (QoS) param- eters as a way to configure automatic-discovery mechanisms and specify the behavior used when sending and receiving messages. The mechanisms are configured up-front and require no further effort on the user's part. By exchanging messages in a completely anonymous manner, Connext greatly simplifies distributed application design and encourages modular, well-struc- tured programs.

Furthermore, Connext includes the following features, which are designed to meet the needs of distributed real-time applications:

Data-centric publish-subscribe communications Simplifies distributed application pro- gramming and provides time-critical data flow with minimal latency.

Clear semantics for managing multiple sources of the same data.

1-4

Features of Connext

Efficient data transfer, customizable Quality of Service, and error notification.

Guaranteed periodic samples, with maximum rate set by subscriptions.

Notification by a callback routine on data arrival to minimize latency.

Notification when data does not arrive by an expected deadline.

Ability to send the same message to multiple computers efficiently.

User-definable data types Enables you to tailor the format of the information being sent to each application.

Reliable messaging Enables subscribing applications to specify reliable delivery of samples.

Multiple Communication Networks Multiple independent communication networks (domains) each using Connext can be used over the same physical network. Applications are only able to participate in the domains to which they belong. Individual applications can be configured to participate in multiple domains.

Symmetric architecture Makes your application robust:

No central server or privileged nodes, so the system is robust to node failures.

Subscriptions and publications can be dynamically added and removed from the sys- tem at any time.

Pluggable Transports Framework Includes the ability to define new transport plug-ins and run over them. Connext comes with a standard UDP/IP pluggable transport and a shared memory transport. It can be configured to operate over a variety of transport mechanisms, including backplanes, switched fabrics, and new networking technologies.

Multiple Built-in Transports Includes UDP/IP and shared memory transports.

Multi-language support Includes APIs for the C, C++, C++/CLI, C#, and Java™ pro- gramming languages.

Multi-platform support Includes support for flavors of UNIX® (Linux® and Solaris™), real-time operating systems (INTEGRITY®, VxWorks®, QNX®, and LynxOS®), and Win- dows® (2000, 2003, CE, Vista, and XP). (Consult the Platform Notes to see which platforms are supported in this release.)

Compliance with Standards

API complies with the DCPS layer of the OMG’s DDS specification.

Data types comply with OMG Interface Definition Language™ (IDL).

Data packet format complies with the International Engineering Consortium’s (IEC’s) publicly available specification for the RTPS wire protocol.

1-5

Chapter 2 Data-Centric Publish-Subscribe

Communications

This chapter describes the formal communications model used by Connext: the Data-Centric Publish-Subscribe (DCPS) standard. DCPS is a formalization (through a standardized API) and extension of the publish-subscribe communications model presented in Section 1.3.

This chapter includes the following sections:

What is DCPS? (Section 2.1)

Data Types, Topics, Keys, Instances, and Samples (Section 2.2)

DataWriters/Publishers and DataReaders/Subscribers (Section 2.3)

Domains and DomainParticipants (Section 2.4)

Quality of Service (QoS) (Section 2.5)

Application Discovery (Section 2.6)

2.1What is DCPS?

DCPS is the portion of the OMG DDS (Data Distribution Service) Standard that addresses data- centric publish-subscribe communications. The DDS standard defines a language-independent model of publish-subscribe communications that has standardized mappings into various implementation languages. Connext offers C, C++, C++/CLI, C#, and Java versions of the DCPS API.

The publish-subscribe approach to distributed communications is a generic mechanism that can be employed by many different types of applications. The DCPS model described in this chapter extends the publish-subscribe model to address the specific needs of real-time, data-critical applications. As you’ll see, it provides several mechanisms that allow application developers to control how communications works and how the middleware handles resource limitations and error conditions.

The “data-centric” portion of the term DCPS describes the fundamental concept supported by the design of the API. In data-centric communications, the focus is on the distribution of data between communicating applications. A data-centric system is comprised of data publishers and data subscribers. The communications are based on passing data of known types in named streams from publishers to subscribers.

In contrast, in object-centric communications the fundamental concept is the interface between the applications. An interface is comprised of a set of methods of known types (number and

2-1

What is DCPS?

types of method arguments). An object-centric system is comprised of interface servers and interface clients, and communications are based on clients invoking methods on named inter- faces that are serviced by the corresponding server.

Data and object-centric communications are complementary paradigms in a distributed system. Applications may require both. However, real-time communications often fit a data-centric model more naturally.

2.1.1DCPS for Real-Time Requirements

DCPS, and specifically the Connext implementation, is well suited for real-time applications. For instance, real-time applications often require the following features:

Efficiency Real-time systems require efficient data collection and delivery. Only minimal delays should be introduced into the critical data-transfer path. Publish-subscribe is more efficient than client-server in both latency and bandwidth for periodic data exchange.

Publish-subscribe greatly reduces the overhead required to send data over the network compared to a client-server architecture. Occasional subscription requests, at low band- width, replace numerous high-bandwidth client requests. Latency is also reduced, since the outgoing request message time is eliminated. As soon as a new publication data sam- ple becomes available, it is sent to the corresponding subscriptions.

Determinism Real-time applications often care about the determinism of delivering periodic data as well as the latency of delivering event data. Once buffers are introduced into a data stream to support reliable connections, new data may be held undelivered for a unpredictable amount of time while waiting for confirmation that old data was received. Since publish-subscribe does not inherently require reliable connections, implementa- tions, like Connext, can provide configurable trade-offs between the deterministic delivery of new data and the reliable delivery of all data.

Flexible delivery bandwidth Typical real-time systems include both real-time and non-real-time nodes. The bandwidth requirements for these nodes—even for the same data—are quite different. For example, an application may be sending data samples faster than a non-real- time application is capable of handling. However, a real-time application may want the same data as fast as it is produced.

DCPS allows subscribers to the same data to set individual limits on how fast data should be delivered each subscriber. This is similar to how some people get a newspaper every day while others can subscribe to only the Sunday paper.

Thread awareness Real-time communications must work without slowing the thread that sends data samples. On the receiving side, some data streams should have higher priority so that new data for those streams are processed before lower priority streams.

Connext provides user-level configuration of its internal threads that process incoming data. Users may configure Connext so that different threads are created with different pri- orities to process received data of different data streams.

Fault-tolerant operation Real-time applications are often in control of systems that are required to run in the presence of component failures. Often, those systems are safety critical or carry financial penalties for loss of service. The applications running those systems are usually designed to be fault-tolerant using redundant hardware and software. Backup applications are often “hot” and interconnected to primary systems so that they can take over as soon as a failure is detected.

Publish-subscribe is capable of supporting many-to-many connectivity with redundant DataWriters and DataReaders. This feature is ideal for constructing fault-tolerant or high- availability applications with redundant nodes and robust fault detection and handling services.

2-2

Data Types, Topics, Keys, Instances, and Samples

DCPS, and thus Connext, was designed and implemented specifically to address the require- ments above through configuration parameters known as QosPolicies defined by the DCPS standard (see QosPolicies (Section 4.2)). The following section introduces basic DCPS terminol- ogy and concepts.

2.2Data Types, Topics, Keys, Instances, and Samples

In data-centric communications, the applications participating in the communication need to share a common view of the types of data being passed around.

Within different programming languages there are several ‘primitive’ data types that all users of that language naturally share (integers, floating point numbers, characters, booleans, etc.). How- ever, in any non-trivial software system, specialized data types are constructed out of the lan- guage primitives. So the data to be shared between applications in the communication system could be structurally simple, using the primitive language types mentioned above, or it could be more complicated, using, for example, C and C++ structs, like this:

struct Time { long year; short day; short hour; short minute; short second;

};

struct StockPrice { float price; Time timeStamp;

};

Within a set of applications using DCPS, the different applications do not automatically know the structure of the data being sent, nor do they necessarily interpret it in the same way (if, for instance, they use different operating systems, were written with different languages, or were compiled with different compilers). There must be a way to share not only the data, but also information about how the data is structured.

In DCPS, data definitions are shared among applications using OMG IDL, a language-indepen- dent means of describing data. For more information on data types and IDL, see Chapter 3.

2.2.1Data Topics — What is the Data Called?

Shared knowledge of the data types is a requirement for different applications to communicate with DCPS. The applications must also share a way to identify which data is to be shared. Data (of any data type) is uniquely distinguished by using a name called a Topic. By definition, a Topic corresponds to a single data type. However, several Topics may refer to the same data type.

Topics interconnect DataWriters and DataReaders. A DataWriter is an object in an application that tells Connext (and indirectly, other applications) that it has some values of a certain Topic. A cor- responding DataReader is an object in an application that tells Connext that it wants to receive values for the same Topic. And the data that is passed from the DataWriter to the DataReader is of the data type associated with the Topic. DataWriters and DataReaders are described more in Section 2.3.

2-3

Data Types, Topics, Keys, Instances, and Samples

For a concrete example, consider a system that distributes stock quotes between applications. The applications could use a data type called StockPrice. There could be multiple Topics of the StockPrice data type, one for each company’s stock, such as IBM, MSFT, GE, etc. Each Topic uses the same data type.

Data Type: StockPrice

struct StockPrice { float price;

Time timeStamp;

};

Topic: “IBM”

Topic: “MSFT”

Topic: “GE”

Now, an application that keeps track of the current value of a client’s portfolio would subscribe to all of the topics of the stocks owned by the client. As the value of each stock changes, the new price for the corresponding topic is published and sent to the application.

2.2.2Samples, Instances, and Keys

The value of data associated with a Topic can change over time. The different values of the Topic passed between applications are called samples. In our stock-price example, samples show the price of a stock at a certain point in time. So each sample may show a different price.

For a data type, you can select one or more fields within the data type to form a key. A key is something that can be used to uniquely identify one instance of a Topic from another instance of the same Topic. Think of a key as a way to sub-categorize or group related data values for the same Topic. Note that not all data types are defined to have keys, and thus, not all topics have keys. For topics without keys, there is only a single instance of that topic.

However, for topics with keys, a unique value for the key identifies a unique instance of the topic. Samples are then updates to particular instances of a topic. Applications can subscribe to a topic and receive samples for many different instances. Applications can publish samples of one, all, or any number of instances of a topic. Many quality of service parameters actually apply on a per instance basis. Keys are also useful for subscribing to a group of related data streams (instances) without pre-knowledge of which data streams (instances) exist at runtime.

For example, let’s change the StockPrice data type to include the symbol of the stock. Then instead of having a Topic for every stock, which would result in hundreds or thousands of topics and related DataWriters and DataReaders, each application would only have to publish or sub- scribe to a single Topic, say “StockPrices.” Successive values of a stock would be presented as successive samples of an instance of “StockPrices”, with each instance corresponding to a single stock symbol.

Data Type: StockPrice

struct StockPrice { float price; Time timeStamp;

char *symbol; //@key

};

Instance 1 = (Topic: “StockPrices”) + (Key: “MSFT”)

sample a, price = $28.00

sample b, price = $27.88

2-4

DataWriters/Publishers and DataReaders/Subscribers

Instance 2 = (Topic: “StockPrices”) + (Key: “IBM”)

sample a, price = $74.02

sample b, price = $73.50

Etc.

Just by subscribing to “StockPrices,” an application can get values for all of the stocks through a single topic. In addition, the application does not have to subscribe explicitly to any particular stock, so that if a new stock is added, the application will immediately start receiving values for that stock as well.

To summarize, the unique values of data being passed using DCPS are called samples. A sample is a combination of a Topic (distinguished by a Topic name), an instance (distinguished by a key), and the actual user data of a certain data type. As seen in Figure 2.1 on page 2-5, a Topic identifies data of a single type, ranging from one single instance to a whole collection of instances of that given topic for keyed data types. For more information, see Chapter 3: Data Types and Data Samples and Chapter 5: Topics.

Figure 2.1 Relationship of Topics, Keys, and Instances

 

 

 

 

 

 

 

a_type:instance1

Type:a_type

 

 

 

 

 

 

 

 

 

 

 

 

 

Key = key1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Key = ...

 

 

 

 

 

 

 

 

 

Topic:a_topic

 

 

 

a_type:instance2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Key = key2

 

 

 

 

 

 

 

 

a_type:instance3

Key = key3

By using keys, a Topic can identify a collection of data-object instances.

2.3DataWriters/Publishers and DataReaders/Subscribers

In DCPS, applications must use APIs to create entities (objects) in order to establish publish-sub- scribe communications between each other. The entities and terminology associated with the data itself have been discussed already—Topics, keys, instances, samples. This section will intro- duce the DCPS entities that user code must create to send and receive the data. Note that Entity is actually a basic DCPS concept. In object-oriented terms, Entity is the base class from which other DCPS classes—Topic, DataWriter, DataReader, Publisher, Subscriber, DomainParticipants— derive. For general information on Entities, see Chapter 4: Entities.

The sending side uses objects called Publishers and DataWriters. The receiving side uses objects called Subscribers and DataReaders. Figure 2.2 illustrates the relationship of these objects.

An application uses DataWriters to send data. A DataWriter is associated with a single Topic. You can have multiple DataWriters and Topics in a single application. In addition, you can have more than one DataWriter for a particular Topic in a single application.

2-5

DataWriters/Publishers and DataReaders/Subscribers

Figure 2.2 Overview

A Publisher is the DCPS object responsible for the actual sending of data. Publishers own and manage DataWriters. A DataWriter can only be owned by a single Publisher while a Publisher can own many DataWriters. Thus the same Publisher may be sending data for many different Topics of different data types. When user code calls the write() method on a DataWriter, the data sample is passed to the Publisher object which does the actual dis- semination of data on the network. For more information, see Chapter 6: Sending Data.

The association between a DataWriter and a Publisher is often referred to as a publication although you never create a DCPS object known as a publication.

An application uses DataReaders to access data received over DCPS. A DataReader is asso- ciated with a single Topic. You can have multiple DataReaders and Topics in a single appli- cation. In addition, you can have more than one DataReader for a particular Topic in a single application.

A Subscriber is the DCPS object responsible for the actual receipt of published data. Sub- scribers own and manage DataReaders. A DataReader can only be owned by a single Sub- scriber while a Subscriber can own many DataReaders. Thus the same Subscriber may receive data for many different Topics of different data types. When data is sent to an application, it is first processed by a Subscriber; the data sample is then stored in the appropriate DataReader. User code can either register a listener to be called when new data arrives or actively poll the DataReader for new data using its read() and take() meth- ods. For more information, see Chapter 7: Receiving Data.

The association between a DataReader and a Subscriber is often referred to as a subscription although you never create a DCPS object known as a subscription.

Example: The publish-subscribe communications model is analogous to that of magazine publi- cations and subscriptions. Think of a publication as a weekly periodical such as Newsweek®. The Topic is the name of the periodical (in this case the string "Newsweek"). The type specifies the for-

2-6

Domains and DomainParticipants

mat of the information, e.g., a printed magazine. The user data is the contents (text and graphics) of each sample (weekly issue). The middleware is the distribution service (usually the US Postal service) that delivers the magazine from where it is created (a printing house) to the individual subscribers (people’s homes). This analogy is illustrated in Figure 2.3. Note that by subscribing to a publication, subscribers are requesting current and future samples of that publication (such as once a week in the case of Newsweek), so that as new samples are published, they are delivered without having to submit another request for data.

Figure 2.3 An Example of Publish-Subscribe

Topic = "Newsweek"

 

 

 

Topic = "Newsweek"

 

 

Sample

 

 

 

 

 

 

 

 

 

 

 

 

 

Publisher

Issue for Feb. 15

Subscriber

 

Send

 

 

 

Receive

 

 

 

 

 

 

Delivery

 

Service

 

 

 

 

 

 

 

The publish-subscribe model is analogous to publishing magazines. The Publisher sends samples of a particular Topic to all Subscribers of that Topic. With Newsweek® magazine, the Topic would be "Newsweek." The sample consists of the data (articles and pictures) sent to all Subscribers every week. The middleware (Connext) is the distribution channel: all of the planes, trucks, and people who distribute the weekly issues to the Subscribers.

By default, each data sample is propagated individually, independently, and uncorrelated with other samples. However, an application may request that several samples be sent as a coherent set, so that they may be interpreted as such on the receiving side.

2.4Domains and DomainParticipants

You may have several independent DCPS applications all running on the same set of computers. You may want to isolate one (or more) of those applications so that it isn’t affected by the others. To address this issue, DCPS has a concept called Domains.

Domains represent logical, isolated, communication networks. Multiple applications running on the same set of hosts on different Domains are completely isolated from each other (even if they are on the same machine). DataWriters and DataReaders belonging to different domains will never exchange data.

Applications that want to exchange data using DCPS must belong to the same Domain. To belong to a Domain, DCPS APIs are used to configure and create a DomainParticipant with a spe- cific Domain Index. Domains are differentiated by the Domain Index (an integer value). Applica- tions that have created DomainParticipants with the same Domain Index belong to the same

Domain. DomainParticipants own Topics, Publishers and Subscribers which in turn owns DataWrit- ers and DataReaders. Thus all DCPS Entities belong to a specific domain.

An application may belong to multiple domains simultaneously by creating multiple Domain- Participants with different domain indices. However, Publishers/DataWriters and Subscribers/

DataReaders only belong to the domain in which they were created.

As mentioned before, multiple domains may be used for application isolation which is useful when users are testing their applications using computers on the same network or even the same computers. By assigning each user different domains, one can guarantee that the data pro- duced by one user’s application won’t accidentally be received by another. In addition, domains

2-7

Quality of Service (QoS)

may be a way to scale and construct larger systems that are composed of multi-node subsys- tems. Each subsystem would use an internal domain for intra-system communications and an external domain to connect to other subsystems.

For more information, see Chapter 8: Working with Domains.

2.5Quality of Service (QoS)

The publish-subscribe approach to distributed communications is a generic mechanism that can be employed by many different types of systems. The DCPS model described here extends the publish-subscribe model to address the needs of real-time, data-critical applications. It provides standardized mechanisms, known as Quality of Service Policies, that allow application develop- ers to configure how communications occur, to limit resources used by the middleware, to detect system incompatibilities and setup error handling routines.

2.5.1Controlling Behavior with Quality of Service (QoS) Policies

QosPolicies control many aspects of how and when data is distributed between applications. The overall QoS of the DCPS system is made up of the individual QosPolicies for each DCPS

Entity. There are QosPolicies for Topics, DataWriters, Publishers, DataReaders, Subscribers, and DomainParticipants.

On the publishing side, the QoS of each Topic, the Topic’s DataWriter, and the DataWriter’s Pub- lisher all play a part in controlling how and when data samples are sent to the middleware. Sim- ilarly, the QoS of the Topic, the Topic’s DataReader, and the DataReader’s Subscriber control behavior on the subscribing side.

Users will employ QosPolicies to control a variety of behaviors. For example, the DEADLINE policy sets up expectations of how often a DataReader expects to see samples. The OWNERSHIP and OWNERSHIP_STRENGTH policy are used together to configure and arbitrate whose data is passed to the DataReader when there are multiple DataWriters for the same instance of a Topic. The HISTORY policy specifies whether a DataWriter should save old data to send to new sub- scriptions that join the network later. Many other policies exist and they are presented in QosPolicies (Section 4.2).

Some QosPolicies represent “contracts” between publications and subscriptions. For communi- cations to take place properly, the QosPolicies set on the DataWriter side must be compatible with corresponding policies set on the DataReader side.

For example, the RELIABILITY policy is set by the DataWriter to state whether it is configured to send data reliably to DataReaders. Because it takes additional resources to send data reliably, some DataWriters may only support a best-effort level of reliability. This implies that for those DataWriters, Connext will not spend additional effort to make sure that the data sent is received by DataReaders or resend any lost data. However, for certain applications, it could be imperative that their DataReaders receive every piece of data with total reliability. Running a system where the DataWriters have not been configured to support the DataReaders could lead to erratic fail- ures.

To address this issue, and yet keep the publications and subscriptions as decoupled as possible, DCPS provides a way to detect and notify when QosPolicies set by DataWriters and DataReaders are incompatible. DCPS employs a pattern known as RxO (Requested versus Offered). The DataReader sets a “requested” value for a particular QosPolicy. The DataWriter sets an “offered” value for that QosPolicy. When Connext matches a DataReader to a DataWriter, QosPolicies are checked to make sure that all requested values can be supported by the offered values.

2-8

Application Discovery

Note that not all QosPolicies are constrained by the RxO pattern. For example, it does not make sense to compare policies that affect only the DataWriter but not the DataReader or vice versa.

If the DataWriter can not satisfy the requested QosPolicies of a DataReader, Connext will not con- nect the two entities and will notify the applications on each side of the incompatibility if so con- figured.

For example, a DataReader sets its DEADLINE QoS to 4 seconds—that is, the DataReader is requesting that it receive new data at least every 4 seconds.

In one application, the DataWriter sets its DEADLINE QoS to 2 seconds—that is, the DataWriter is committing to sending data at least every 2 seconds. This writer can satisfy the request of the reader, and thus, Connext will pass the data sent from the writer to the reader.

In another application, the DataWriter sets its DEADLINE QoS to 5 seconds. It only commits to sending data at 5 second intervals. This will not satisfy the request of the DataReader. Connext will flag this incompatibility by calling user-installed listeners in both DataWriter and DataReader applications and not pass data from the writer to the reader.

For a summary of the QosPolicies supported by Connext, see QosPolicies (Section 4.2).

2.6Application Discovery

The DCPS model provides anonymous, transparent, many-to-many communications. Each time an application sends a sample of a particular Topic, the middleware distributes the sample to all the applications that want that Topic. The publishing application does not need to specify how many applications receive the Topic, nor where those applications are located. Similarly, subscrib- ing applications do not specify the location of the publications. In addition, new publications and subscriptions of the Topic can appear at any time, and the middleware will automatically inter- connect them.

So how is this all done? Ultimately, in each application for each publication, Connext must keep a list of applications that have subscribed to the same Topic, nodes on which they are located, and some additional QoS parameters that control how the data is sent. Also, Connext must keep a list of applications and publications for each of the Topics to which the application has subscribed.

This propagation of this information (the existence of publications and subscriptions and associ- ated QoS) between applications by Connext is known as the discovery process. While the DDS (DCPS) standard does not specify how discovery occurs, Connext uses a standard protocol RTPS for both discovery and formatting on-the-wire packets.

When a DomainParticipant is created, Connext sends out packets on the network to announce its existence. When an application finds out that another application belongs to the same domain, then it will exchange information about its existing publications and subscriptions and associ- ated QoS with the other application. As new DataWriters and DataReaders are created, this infor- mation is sent to known applications.

The Discovery process is entirely configurable by the user and is discussed extensively in Chapter 14: Discovery.

2-9

Part 2: Core Concepts

This section includes the following chapters:

Chapter 3: Data Types and Data Samples

Chapter 4: Entities

Chapter 5: Topics

Chapter 6: Sending Data

Chapter 7: Receiving Data

Chapter 8: Working with Domains

Chapter 9: Building Applications

Chapter 3 Data Types and Data Samples

How data is stored or laid out in memory can vary from language to language, compiler to com- piler, operating system to operating system, and processor to processor. This combination of lan- guage/compiler/operating system/processor is called a platform. Any modern middleware must be able to take data from one specific platform (say C/gcc.3.2.2/Solaris/Sparc) and trans- parently deliver it to another (for example, Java/JDK 1.6/Windows XP/Pentium). This process is commonly called serialization/deserialization, or marshalling/demarshalling.

Messaging products have typically taken one of two approaches to this problem:

1.Do nothing. Messages consist only of opaque streams of bytes. The JMS BytesMessage is an example of this approach.

2.Send everything, every time. Self-describing messages are at the opposite extreme, embedding full reflective information, including data types and field names, with each message. The JMS MapMessage and the messages in TIBCO Rendezvous are examples of this approach.

The “do nothing” approach is lightweight on its surface but forces you, the user of the middle- ware API, to consider all data encoding, alignment, and padding issues. The “send everything” alternative results in large amounts of redundant information being sent with every packet, impacting performance.

Connext takes an intermediate approach. Just as objects in your application program belong to some data type, data samples sent on the same Connext topic share a data type. This type defines the fields that exist in the data samples and what their constituent types are. The middleware stores and propagates this meta-information separately from the individual data samples, allowing it to propagate samples efficiently while handling byte ordering and alignment issues for you.

To publish and/or subscribe to data with Connext, you will carry out the following steps:

1.Select a type to describe your data.

You have a number of choices. You can choose one of these options, or you can mix and match them.

Use a built-in type provided by the middleware.

This option may be sufficient if your data typing needs are very simple. If your data is highly structured, or you need to be able to examine fields within that data for filter- ing or other purposes, this option may not be appropriate. The built-in types are described in Built-in Data Types (Section 3.2).

Use the RTI code generator, rtiddsgen, to define a type at compile-time using a lan- guage-independent description language.

3-1

Code generation offers two strong benefits not available with dynamic type defini- tion: (1) it allows you to share type definitions across programming languages, and (2) because the structure of the type is known at compile time, it provides rigorous static type safety.

The code generator accepts input in a number of formats to make it easy to integrate Connext with your development processes and IT infrastructure:

OMG IDL. This format is a standard component of both the DDS and CORBA specifications. It describes data types with a C++-like syntax. This format is described in Creating User Data Types with IDL (Section 3.3).

XML schema (XSD), either independent or embedded in a WSDL file. XSD should be the format of choice for those using Connext alongside or connected to a web- services infrastructure. This format is described in Creating User Data Types with XML Schemas (XSD) (Section 3.5).

XML in a DDS-specific format. This XML format is terser, and therefore easier to read and write by hand, than an XSD file. It offers the general benefits of XML- extensibility and ease of integration, while fully supporting DDS-specific data types and concepts. This format is described in Creating User Data Types with Extensible Markup Language (XML) (Section 3.4).

Define a type programmatically at run time.

This method may be appropriate for applications with dynamic data description needs: applications for which types change frequently or cannot be known ahead of time. It is described in Defining New Types (Section 3.8.2).

2.Register your type with a logical name.

If you've chosen to use a built-in type instead of defining your own, you can omit this step; the middleware pre-registers the built-in types for you.

This step is described in the Defining New Types (Section 3.8.2).

3.Create a Topic using the type name you previously registered.

If you've chosen to use a built-in type instead of defining your own, you will use the API constant corresponding to that type's name.

Creating and working with Topics is discussed in Chapter 5: Topics.

4.Create one or more DataWriters to publish your data and one or more DataReaders to sub- scribe to it.

The concrete types of these objects depend on the concrete data type you've selected, in order to provide you with a measure of type safety.

Creating and working with DataWriters and DataReaders are described in Chapter 6: Sending Data and Chapter 7: Receiving Data, respectively.

Whether publishing or subscribing to data, you will need to know how to create and delete data samples and how to get and set their fields. These tasks are described in Working with Data Samples (Section 3.9).

This chapter describes:

Introduction to the Type System (Section 3.1 on Page 3-3)

Built-in Data Types (Section 3.2 on Page 3-5)

Creating User Data Types with IDL (Section 3.3 on Page 3-37)

Creating User Data Types with Extensible Markup Language (XML) (Section 3.4 on Page 3-61)

3-2

Introduction to the Type System

Creating User Data Types with XML Schemas (XSD) (Section 3.5 on Page 3-66)

Using rtiddsgen (Section 3.6 on Page 3-79)

Using Generated Types without Connext (Standalone) (Section 3.7 on Page 3-85)

Interacting Dynamically with User Data Types (Section 3.8 on Page 3-87)

Working with Data Samples (Section 3.9 on Page 3-92)

3.1Introduction to the Type System

A user data type is any custom type that your application defines for use with Connext. It may be a structure, a union, a value type, an enumeration, or a typedef (or language equivalents).

Your application can have any number of user data types. They can be composed of any of the primitive data types listed below or of other user data types.

Only structures, unions, and value types may be read and written directly by Connext; enums, typedefs, and primitive types must be contained within a structure, union, or value type. In order for a DataReader and DataWriter to communicate with each other, the data types associated with their respective Topic definitions must be identical.

octet, char, wchar

short, unsigned short

long, unsigned long

long long, unsigned long long

float

double, long double

boolean

enum (with or without explicit values)

bounded and unbounded string and wstring

The following type-building constructs are also supported:

module (also called a package or namespace)

pointer

array of primitive or user type elements

bounded/unbounded sequence of elements1—a sequence is a variable-length ordered col- lection, such as a vector or list

typedef

bitfield2

union

struct

value type, a complex type that supports inheritance and other object-oriented features

1.Sequences of sequences are not supported directly. To work around this constraint, typedef the inner sequence and form a sequence of that new type.

2.Data types containing bitfield members are not supported by DynamicData.

3-3

Introduction to the Type System

To use a data type with Connext, you must define that type in a way the middleware under- stands and then register the type with the middleware. These steps allow Connext to serialize, deserialize, and otherwise operate on specific types. They will be described in detail in the fol- lowing sections.

3.1.1Sequences

A sequence contains an ordered collection of elements that are all of the same type. The opera- tions supported in the sequence are documented in the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Refer- ence, Infrastructure Module, Sequence Support).

Java sequences implement the java.util.List interface from the standard Collections framework.

C++ users will find sequences conceptually similar to the deque class in the Standard Template Library (STL).

Elements in a sequence are accessed with their index, just like elements in an array. Indices start from zero. Unlike arrays, however, sequences can grow in size. A sequence has two sizes associ- ated with it: a physical size (the "maximum") and a logical size (the "length"). The physical size indicates how many elements are currently allocated by the sequence to hold; the logical size indicates how many valid elements the sequence actually holds. The length can vary from zero up to the maximum. Elements cannot be accessed at indices beyond the current length.

A sequence may be declared as bounded or unbounded. A sequence's "bound" is the maximum number of elements tha tthe sequence can contain at any one time. The bound is very important because it allows Connext to preallocate buffers to hold serialized and deserialized samples of your types; these buffers are used when communicating with other nodes in your distributed system. If a sequence had no bound, Connext would not know how large to allocate its buffers and would therefore have to allocate them on the fly as individual samples were read and writ- ten—severely impacting the latency and determinism of your application. Therefore, Connext supports only bounded sequences; any unbounded sequences found in an IDL file will be given a default bound of 100 elements (see rtiddsgen Command-Line Arguments (Section 3.6.1)).

3.1.2Strings and Wide Strings

Connext supports both strings consisting of single-byte characters (the IDL string type) and strings consisting of wide characters (IDL wstring). The wide characters supported by Connext are four bytes long, large enough to store not only two-byte Unicode/UTF16 characters but also UTF32 characters.

Like sequences, strings may be bounded or unbounded. A string's "bound" is its maximum length (not counting the trailing NULL character in C and C++).

3.1.3Introduction to TypeCode

Type schemas—the names and definitions of a type and its fields—are represented by TypeCode objects. A type code value consists of a type code kind (see the TCKind enumeration below) and a list of members. For compound types like structs and arrays, this list will recursively include one or more type code values.

enum TCKind { TK_NULL, TK_SHORT, TK_LONG, TK_USHORT, TK_ULONG,

3-4

Built-in Data Types

TK_FLOAT,

TK_DOUBLE,

TK_BOOLEAN, TK_CHAR, TK_OCTET, TK_STRUCT, TK_UNION, TK_ENUM, TK_STRING, TK_SEQUENCE, TK_ARRAY, TK_ALIAS, TK_LONGLONG, TK_ULONGLONG, TK_LONGDOUBLE, TK_WCHAR, TK_WSTRING, TK_VALUE, TK_SPARSE

}

Type codes unambiguously match type representations and provide a more reliable test than comparing the string type names.

The TypeCode class, modeled after the corresponding CORBA API, provides access to type- code information. For details on the available operations for the TypeCode class, see the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Topic Module, Type Code Support).

3.1.3.1Sending TypeCodes on the Network

In addition to being used locally, serialized type codes are typically published automatically during discovery as part of the built-in topics for publications and subscriptions. See Built-in DataReaders (Section 16.2). This allows applications to publish or subscribe to topics of arbitrary types. This functionality is useful for generic system monitoring tools like the rtiddsspy debug tool (see the API Reference HTML documentation).

Note: Type codes are not cached by Connext upon receipt and are therefore not available from the built-in data returned by the DataWriter's get_matched_subscription_data() operation or the

DataReader's get_matched_publication_data() operation.

If your data type has an especially complex type code, you may need to increase the value of the type_code_max_serialized_length field in the DomainParticipant's

DOMAIN_PARTICIPANT_RESOURCE_LIMITS QosPolicy (DDS Extension) (Section 8.5.4). Or, to prevent the propagation of type codes altogether, you can set this value to zero (0). Be aware that some features of monitoring tools, as well as some features of the middleware itself (such as ContentFilteredTopics) will not work correctly if you disable TypeCode propagation.

3.2Built-in Data Types

Connext provides a set of standard types that are built into the middleware. These types can be used immediately; they do not require writing IDL, invoking the rtiddsgen utility (see Section 3.6), or using the dynamic type API (see Section 3.2.8).

The supported built-in types are String, KeyedString, Octets, and KeyedOctets. (The latter two types are called Bytes and KeyedBytes, respectively, on Java and .NET platforms.)

3-5

Built-in Data Types

The built-in type API is located under the DDS namespace in C++ and .NET. For Java, the API is contained inside the package com.rti.dds.type.builtin.

Built-in data types are discussed in the following sections:

Registering Built-in Types (Section 3.2.1)

Creating Topics for Built-in Types (Section 3.2.2)

Creating ContentFilteredTopics for Built-in Types (Section 3.2.3)

String Built-in Type (Section 3.2.4)

KeyedString Built-in Type (Section 3.2.5)

Octets Built-in Type (Section 3.2.6)

KeyedOctets Built-in Type (Section 3.2.7)

Type Codes for Built-in Types (Section 3.2.9)

3.2.1Registering Built-in Types

By default, the built-in types are automatically registered when a DomainParticipant is created. You can change this behavior by setting the DomainParticipant’s dds.builtin_type.auto_register property to 0 (false) using the PROPERTY QosPolicy (DDS Extension) (Section 6.5.17).

3.2.2Creating Topics for Built-in Types

To create a topic for a built-in type, just use the standard DomainParticipant operations, create_topic() or create_topic_with_profile() (see Creating Topics (Section 5.1.1)); for the type_name parameter, use the value returned by the get_type_name() operation, listed below for each API.

Note: In the following examples, you will see the sentinel "<BuiltinType>."

For C and C++: <BuiltinType> = String, KeyedString, Octets or KeyedOctets For Java and .NET1: <BuiltinType> = String, KeyedString, Bytes or KeyedBytes

C API:

const char* DDS_<BuiltinType>TypeSupport_get_type_name();

C++ API with namespace:

const char* DDS::<BuiltinType>TypeSupport::get_type_name();

C++ API without namespace:

const char* DDS<BuiltinType>TypeSupport::get_type_name();

C++/CLI API:

System::String^ DDS:<BuiltinType>TypeSupport::get_type_name();

C# API:

System.String DDS.<BuiltinType>TypeSupport.get_type_name();

1. RTI Connext .NET language binding is currently supported for C# and C++/CLI.

3-6

Built-in Data Types

Java API:

String com.rti.dds.type.builtin.<BuiltinType>TypeSupport.get_type_name();

3.2.2.1Topic Creation Examples

For simplicity, error handling is not shown in the following examples.

C Example:

DDS_Topic * topic = NULL;

/* Create a builtin type Topic */

topic = DDS_DomainParticipant_create_topic( participant, "StringTopic",

DDS_StringTypeSupport_get_type_name(), &DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

C++ Example with Namespaces:

using namespace DDS;

...

/* Create a String builtin type Topic */ Topic * topic = participant->create_topic(

"StringTopic", StringTypeSupport::get_type_name(),

DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

C++/CLI Example:

using namespace DDS;

...

/* Create a builtin type Topic */

Topic^ topic = participant->create_topic(

"StringTopic", StringTypeSupport::get_type_name(), DomainParticipant::TOPIC_QOS_DEFAULT,

nullptr, StatusMask::STATUS_MASK_NONE);

C# Example:

using namespace DDS;

...

/* Create a builtin type Topic */

Topic topic = participant.create_topic(

"StringTopic", StringTypeSupport.get_type_name(), DomainParticipant.TOPIC_QOS_DEFAULT,

null, StatusMask.STATUS_MASK_NONE);

Java Example:

import com.rti.dds.type.builtin.*;

...

/* Create a builtin type Topic */

Topic topic = participant.create_topic(

"StringTopic", StringTypeSupport.get_type_name(), DomainParticipant.TOPIC_QOS_DEFAULT,

null, StatusKind.STATUS_MASK_NONE);

3-7

Built-in Data Types

3.2.3Creating ContentFilteredTopics for Built-in Types

To create a ContentFilteredTopic for a built-in type, just use the standard DomainParticipant operations, create_contentfilteredtopic() or create_contentfilteredtopic_with_filter (see Section 5.4.3).

The field names used in the filter expressions for the built-in SQL (see Section 5.4.6) and String- Match filters (see Section 5.4.7) must correspond to the names provided in the IDL description of the built-in types (see Section 3.2.4).

3.2.3.1ContentFilteredTopic Creation Examples

For simplicity, error handling is not shown in the following examples.

C Example:

DDS_Topic * topic = NULL;

DDS_ContentFilteredTopic * contentFilteredTopic = NULL; struct DDS_StringSeq parameters = DDS_SEQUENCE_INITIALIZER;

/* Create a string ContentFilteredTopic */ topic = DDS_DomainParticipant_create_topic(

participant, "StringTopic", DDS_StringTypeSupport_get_type_name(), &DDS_TOPIC_QOS_DEFAULT,NULL, DDS_STATUS_MASK_NONE);

contentFilteredTopic = DDS_DomainParticipant_create_contentfilteredtopic( participant, "StringContentFilteredTopic",

topic, "value = 'Hello World!'", ¶meters);

C++ Example with Namespaces:

using namespace DDS;

...

/* Create a String ContentFilteredTopic */ Topic * topic = participant->create_topic(

"StringTopic", StringTypeSupport::get_type_name(), TOPIC_QOS_DEFAULT, NULL, STATUS_MASK_NONE);

StringSeq parameters;

ContentFilteredTopic * contentFilteredTopic = participant->create_contentfilteredtopic(

"StringContentFilteredTopic", topic, "value = 'Hello World!'", parameters);

C++/CLI Example:

using namespace DDS;

...

/* Create a String ContentFilteredTopic */ Topic^ topic = participant->create_topic(

"StringTopic", StringTypeSupport::get_type_name(), DomainParticipant::TOPIC_QOS_DEFAULT,

nullptr, StatusMask::STATUS_MASK_NONE);

StringSeq^ parameters = gcnew StringSeq();

3-8

Built-in Data Types

ContentFilteredTopic^ contentFilteredTopic = participant->create_contentfilteredtopic(

"StringContentFilteredTopic", topic, "value = 'Hello World!'", parameters);

C# Example:

using namespace DDS;

...

/* Create a String ContentFilteredTopic */ Topic topic = participant.create_topic(

"StringTopic", StringTypeSupport.get_type_name(), DomainParticipant.TOPIC_QOS_DEFAULT,

null, StatusMask.STATUS_MASK_NONE);

StringSeq parameters = new StringSeq();

ContentFilteredTopic contentFilteredTopic = participant.create_contentfilteredtopic(

"StringContentFilteredTopic", topic, "value = 'Hello World!'", parameters);

Java Example:

import com.rti.dds.type.builtin.*;

...

/* Create a String ContentFilteredTopic */ Topic topic = participant.create_topic(

"StringTopic", StringTypeSupport.get_type_name(), DomainParticipant.TOPIC_QOS_DEFAULT,

null, StatusKind.STATUS_MASK_NONE);

StringSeq parameters = new StringSeq();

ContentFilteredTopic contentFilteredTopic = participant.create_contentfilteredtopic(

"StringContentFilteredTopic", topic, "value = 'Hello World!'", parameters);

3.2.4String Built-in Type

The String built-in type is represented by a NULL-terminated character array (char *) in C and C++ and an immutable String object in Java and .NET1. This type can be used to publish and subscribe to a single string.

3.2.4.1Creating and Deleting Strings

In C and C++, Connext provides a set of operations to create (DDS::String_alloc()), destroy (DDS::String_free()), and clone strings (DDS::String_dup()). Select Modules, DDS API Refer- ence, Infrastructure Module, String support in the API Reference HTML documentation, which is available for all supported programming languages.

1. RTI Connext .NET language binding is currently supported for C# and C++/CLI.

3-9

Built-in Data Types

Memory Considerations in Copy Operations:

When the read/take operations that take a sequence of strings as a parameter are used in copy mode, Connext allocates the memory for the string elements in the sequence if they are initialized to NULL.

If the elements are not initialized to NULL, the behavior depends on the language:

In Java and .NET, the memory associated with the elements is reallocated with every sample, because strings are immutable objects.

In C and C++, the memory associated with the elements must be large enough to hold the received data. Insufficient memory may result in crashes.

When take_next_sample() and read_next_sample() are called in C and C++, you must make sure that the input string has enough memory to hold the received data. Insuffi- cient memory may result in crashes.

3.2.4.2String DataWriter

The string DataWriter API matches the standard DataWriter API (see Using a Type-Specific DataWriter (FooDataWriter) (Section 6.3.7)). There are no extensions.

The following examples show how to write simple strings with a string built-in type DataWriter. For simplicity, error handling is not shown.

C Example:

DDS_StringDataWriter * stringWriter = ... ; DDS_ReturnCode_t retCode;

char * str = NULL;

/* Write some data */

retCode = DDS_StringDataWriter_write(

stringWriter, "Hello World!", &DDS_HANDLE_NIL);

str = DDS_String_dup("Hello World!");

retCode = DDS_StringDataWriter_write(stringWriter, str, &DDS_HANDLE_NIL); DDS_String_free(str);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

StringDataWriter * stringWriter = ... ;

/* Write some data */

ReturnCode_t retCode = stringWriter->write("Hello World!", HANDLE_NIL); char * str = DDS::String_dup("Hello World!");

retCode = stringWriter->write(str, HANDLE_NIL);

DDS::String_free(str);

C++/CLI Example:

using namespace System; using namespace DDS;

...

StringDataWriter^ stringWriter = ... ;

/* Write some data */

3-10

Built-in Data Types

stringWriter->write("Hello World!", InstanceHandle_t::HANDLE_NIL); String^ str = "Hello World!";

stringWriter->write(str, InstanceHandle_t::HANDLE_NIL);

C# Example:

using System; using DDS;

...

StringDataWriter stringWriter = ... ;

/* Write some data */

stringWriter.write("Hello World!", InstanceHandle_t.HANDLE_NIL); String str = "Hello World!";

stringWriter.write(str, InstanceHandle_t.HANDLE_NIL);

Java Example:

import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;

...

StringDataWriter stringWriter = ... ;

/* Write some data */

stringWriter.write("Hello World!", InstanceHandle_t.HANDLE_NIL); String str = "Hello World!";

stringWriter.write(str, InstanceHandle_t.HANDLE_NIL);

3.2.4.3String DataReader

The string DataReader API matches the standard DataReader API (see Using a Type-Specific DataReader (FooDataReader) (Section 7.4.1)). There are no extensions.

The following examples show how to read simple strings with a string built-in type DataReader. For simplicity, error handling is not shown.

C Example:

struct DDS_StringSeq dataSeq = DDS_SEQUENCE_INITIALIZER; struct DDS_SampleInfoSeq infoSeq = DDS_SEQUENCE_INITIALIZER; DDS_StringDataReader * stringReader = ... ; DDS_ReturnCode_t retCode;

int i;

/* Take and print the data */

retCode = DDS_StringDataReader_take(stringReader, &dataSeq, &infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);

for (i = 0; i < DDS_StringSeq_get_length(&data_seq); ++i) {

if (DDS_SampleInfoSeq_get_reference(&info_seq, i)->valid_data) { DDS_StringTypeSupport_print_data(

DDS_StringSeq_get(&data_seq, i));

}

}

/* Return loan */

retCode = DDS_StringDataReader_return_loan(stringReader, &data_seq, &info_seq);

3-11

Built-in Data Types

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

StringSeq dataSeq;

SampleInfoSeq infoSeq;

StringDataReader * stringReader = ... ;

/* Take a print the data */

ReturnCode_t retCode = stringReader->take(dataSeq, infoSeq, LENGTH_UNLIMITED, ANY_SAMPLE_STATE, ANY_VIEW_STATE, ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq[i].valid_data) {

StringTypeSupport::print_data(dataSeq[i]);

}

}

/* Return loan */

retCode = stringReader->return_loan(dataSeq, infoSeq);

C++/CLI Example:

using namespace System; using namespace DDS;

...

StringSeq^ dataSeq = gcnew StringSeq();

SampleInfoSeq^ infoSeq = gcnew SampleInfoSeq();

StringDataReader^ stringReader = ... ;

/* Take and print the data */ stringReader->take(dataSeq, infoSeq,

ResourceLimitsQosPolicy::LENGTH_UNLIMITED, SampleStateKind::ANY_SAMPLE_STATE, ViewStateKind::ANY_VIEW_STATE, InstanceStateKind::ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq->get_at(i)->valid_data) {

StringTypeSupport::print_data(dataSeq->get_at(i));

}

}

/* Return loan */ stringReader->return_loan(dataSeq, infoSeq);

C# Example:

using System; using DDS;

...

StringSeq dataSeq = new StringSeq();

SampleInfoSeq infoSeq = new SampleInfoSeq();

StringDataReader stringReader = ... ;

/* Take and print the data */

3-12

Built-in Data Types

stringReader.take(dataSeq, infoSeq, ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq.get_at(i)).valid_data) {

StringTypeSupport.print_data(dataSeq.get_at(i));

}

}

}

}

Java Example:

import com.rti.dds.infrastructure.*; import com.rti.dds.subscription.*; import com.rti.dds.type.builtin.*;

...

StringSeq dataSeq = new StringSeq();

SampleInfoSeq infoSeq = new SampleInfoSeq();

StringDataReader stringReader = ... ;

/* Take and print the data */ stringReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) {

if (((SampleInfo)infoSeq.get(i)).valid_data) { System.out.println((String)dataSeq.get(i));

}

}

/* Return loan */ stringReader.return_loan(dataSeq, infoSeq);

3.2.5KeyedString Built-in Type

The Keyed String built-in type is represented by a (key, value) pair, where key and value are strings. This type can be used to publish and subscribe to keyed strings. The language specific representations of the type are as follows:

C/C++ Representation (without namespaces):

struct DDS_KeyedString { char * key;

char * value;

};

C++/CLI Representation:

namespace DDS {

public ref struct KeyedString: { public:

System::String^ key; System::String^ value;

...

3-13

Built-in Data Types

};

};

C# Representation:

namespace DDS {

public class KeyedString { public System.String key; public System.String value;

};

};

Java Representation:

namespace DDS {

public class KeyedString { public System.String key; public System.String value;

};

};

3.2.5.1Creating and Deleting Keyed Strings

Connext provides a set of constructors/destructors to create/destroy Keyed Strings. For details, see the API Reference HTML documentation, which is available for all supported programming languages (select Modules, DDS API Reference, Topic Module, Built-in Types).

If you want to manipulate the memory of the fields 'value' and 'key' in the KeyedString struct in C/C++, use the operations DDS::String_alloc(), DDS::String_dup(), and DDS::String_free(), as described in the API Reference HTML documentation (select Modules, DDS API Reference, Infrastructure Module, String Support).

3.2.5.2Keyed String DataWriter

The keyed string DataWriter API is extended with the following methods (in addition to the standard methods described in Using a Type-Specific DataWriter (FooDataWriter) (Section 6.3.7)):

DDS::ReturnCode_t DDS::KeyedStringDataWriter::dispose( const char* key,

const DDS::InstanceHandle_t* instance_handle);

DDS::ReturnCode_t DDS::KeyedStringDataWriter::dispose_w_timestamp( const char* key,

const DDS::InstanceHandle_t* instance_handle, const struct DDS::Time_t* source_timestamp);

DDS::ReturnCode_t DDS::KeyedStringDataWriter::get_key_value( char * key,

const DDS::InstanceHandle_t* handle);

DDS::InstanceHandle_t DDS::KeyedStringDataWriter::lookup_instance(

const char * key);

DDS::InstanceHandle_t DDS::KeyedStringDataWriter::register_instance(

const char* key);

DDS::InstanceHandle_t

DDS_KeyedStringDataWriter::register_instance_w_timestamp(

const char * key,

const struct DDS_Time_t* source_timestamp);

3-14

Built-in Data Types

DDS::ReturnCode_t DDS::KeyedStringDataWriter::unregister_instance( const char * key,

const DDS::InstanceHandle_t* handle);

DDS::ReturnCode_t DDS::KeyedStringDataWriter::unregister_instance_w_timestamp(

const char* key,

const DDS::InstanceHandle_t* handle,

const struct DDS::Time_t* source_timestamp);

DDS::ReturnCode_t DDS::KeyedStringDataWriter::write ( const char * key,

const char * str,

const DDS::InstanceHandle_t* handle);

DDS::ReturnCode_t DDS::KeyedStringDataWriter::write_w_timestamp( const char * key,

const char * str,

const DDS::InstanceHandle_t* handle,

const struct DDS::Time_t* source_timestamp);

These operations are introduced to provide maximum flexibility in the format of the input parameters for the write and instance management operations. For additional information and a complete description of the operations, see the API Reference HTML documentation, which is available for all supported programming languages.

The following examples show how to write keyed strings using a keyed string built-in type DataWriter and some of the extended APIs. For simplicity, error handling is not shown.

C Example:

DDS_KeyedStringDataWriter * stringWriter = ... ; DDS_ReturnCode_t retCode;

struct DDS_KeyedString * keyedStr = NULL; char * str = NULL;

/* Write some data using the KeyedString structure */ keyedStr = DDS_KeyedString_new(255, 255); strcpy(keyedStr->key, "Key 1"); strcpy(keyedStr->value, "Value 1");

retCode = DDS_KeyedStringDataWriter_write_string_w_key( stringWriter, keyedStr, &DDS_HANDLE_NIL);

DDS_KeyedString_delete(keyedStr);

/* Write some data using individual strings */

retCode = DDS_KeyedStringDataWriter_write_string_w_key( stringWriter, "Key 1",

"Value 1", &DDS_HANDLE_NIL);

str = DDS_String_dup("Value 2");

retCode = DDS_KeyedStringDataWriter_write_string_w_key( stringWriter, "Key 1", str, &DDS_HANDLE_NIL);

DDS_String_free(str);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

3-15

Built-in Data Types

...

KeyedStringDataWriter * stringWriter = ... ;

/* Write some data using the KeyedString */ KeyedString * keyedStr = new KeyedString(255, 255); strcpy(keyedStr->key, "Key 1"); strcpy(keyedStr->value, "Value 1");

ReturnCode_t retCode = stringWriter->write(keyedStr, HANDLE_NIL);

delete keyedStr;

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

KeyedStringDataWriter * stringWriter = ... ;

/* Write some data using the KeyedString */ KeyedString * keyedStr = new KeyedString(255, 255); strcpy(keyedStr->key, "Key 1"); strcpy(keyedStr->value, "Value 1");

ReturnCode_t retCode = stringWriter->write(keyedStr, HANDLE_NIL);

delete keyedStr;

C++/CLI Example:

using namespace System; using namespace DDS;

...

KeyedStringDataWriter^ stringWriter = ... ;

/* Write some data using the KeyedString */ KeyedString^ keyedStr = gcnew KeyedString(); keyedStr->key = "Key 1";

keyedStr->value = "Value 1";

stringWriter->write(keyedStr, InstanceHandle_t::HANDLE_NIL);

/* Write some data using individual strings */ stringWriter->write("Key 1","Value 1",InstanceHandle_t::HANDLE_NIL);

String^ str = "Value 2";

stringWriter->write("Key 1", str, InstanceHandle_t::HANDLE_NIL);

C# Example

using System; using DDS;

...

KeyedStringDataWriter stringWriter = ... ;

/* Write some data using the KeyedString */ KeyedString keyedStr = new KeyedString(); keyedStr.key = "Key 1";

keyedStr.value = "Value 1";

stringWriter.write(keyedStr, InstanceHandle_t.HANDLE_NIL);

3-16

Built-in Data Types

/* Write some data using individual strings */ stringWriter.write("Key 1", "Value 1", InstanceHandle_t.HANDLE_NIL);

String str = "Value 2";

stringWriter.write("Key 1", str, InstanceHandle_t.HANDLE_NIL);

Java Example :

import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;

...

KeyedStringDataWriter stringWriter = ... ;

/* Write some data using the KeyedString */ KeyedString keyedStr = new KeyedString(); keyedStr.key = "Key 1";

keyedStr.value = "Value 1";

stringWriter.write(keyedStr, InstanceHandle_t.HANDLE_NIL);

/* Write some data using individual strings */ stringWriter.write("Key 1", "Value 1", InstanceHandle_t.HANDLE_NIL);

String str = "Value 2";

stringWriter.write("Key 1", str, InstanceHandle_t.HANDLE_NIL);

3.2.5.3Keyed String DataReader

The KeyedString DataReader API is extended with the following operations (in addition to the standard methods described in Using a Type-Specific DataReader (FooDataReader) (Section 7.4.1)):

DDS::ReturnCode_t DDS::KeyedStringDataReader::get_key_value(

char * key, const DDS::InstanceHandle_t* handle);

DDS::InstanceHandle_t DDS::KeyedStringDataReader::lookup_instance(

const char * key);

For additional information and a complete description of these operations in all supported lan- guages, see the API Reference HTML documentation, which is available for all supported pro- gramming languages.

Memory considerations in copy operations:

For read/take operations with copy semantics, such as read_next_sample() and take_next_sample(), Connext allocates memory for the fields 'value' and 'key' if they are initialized to NULL.

If the fields are not initialized to NULL, the behavior depends on the language:

In Java and .NET, the memory associated to the fields 'value' and 'key' will be reallo- cated with every sample.

In C and C++, the memory associated with the fields 'value' and 'key' must be large enough to hold the received data. Insufficient memory may result in crashes.

The following examples show how to read keyed strings with a keyed string built-in type DataReader. For simplicity, error handling is not shown.

3-17

Built-in Data Types

C Example:

struct DDS_KeyedStringSeq dataSeq = DDS_SEQUENCE_INITIALIZER; struct DDS_SampleInfoSeq infoSeq = DDS_SEQUENCE_INITIALIZER; DDS_KeyedKeyedStringDataReader * stringReader = ... ; DDS_ReturnCode_t retCode;

int i;

/* Take and print the data */

retCode = DDS_KeyedStringDataReader_take(stringReader, &dataSeq, &infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);

for (i = 0; i < DDS_KeyedStringSeq_get_length(&data_seq); ++i) {

if (DDS_SampleInfoSeq_get_reference(&info_seq, i)->valid_data) { DDS_KeyedStringTypeSupport_print_data(

DDS_KeyedStringSeq_get_reference(&data_seq, i));

}

}

/* Return loan */

retCode = DDS_KeyedStringDataReader_return_loan(

stringReader, &data_seq, &info_seq);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

KeyedStringSeq dataSeq;

SampleInfoSeq infoSeq;

KeyedStringDataReader * stringReader = ... ;

/* Take a print the data */

ReturnCode_t retCode = stringReader->take(dataSeq, infoSeq, LENGTH_UNLIMITED, ANY_SAMPLE_STATE, ANY_VIEW_STATE, ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq[i].valid_data) {

KeyedStringTypeSupport::print_data(&dataSeq[i]);

}

}

/* Return loan */

retCode = stringReader->return_loan(dataSeq, infoSeq);

C++/CLI Example:

using namespace System; using namespace DDS;

...

KeyedStringSeq^ dataSeq = gcnew KeyedStringSeq();

SampleInfoSeq^ infoSeq = gcnew SampleInfoSeq();

KeyedStringDataReader^ stringReader = ... ;

3-18

Built-in Data Types

/* Take and print the data */ stringReader->take(dataSeq, infoSeq,

ResourceLimitsQosPolicy::LENGTH_UNLIMITED, SampleStateKind::ANY_SAMPLE_STATE, ViewStateKind::ANY_VIEW_STATE, InstanceStateKind::ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq->get_at(i)->valid_data) {

KeyedStringTypeSupport::print_data(dataSeq->get_at(i));

}

}

/* Return loan */ stringReader->return_loan(dataSeq, infoSeq);

C# Example:

using System; using DDS;

...

KeyedStringSeq dataSeq = new KeyedStringSeq();

SampleInfoSeq infoSeq = new SampleInfoSeq();

KeyedStringDataReader stringReader = ... ;

/* Take and print the data */ stringReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq.get_at(i)).valid_data) {

KeyedStringTypeSupport.print_data(dataSeq.get_at(i));

}

}

/* Return loan */ stringReader.return_loan(dataSeq, infoSeq);

Java Example:

import com.rti.dds.infrastructure.*; import com.rti.dds.subscription.*; import com.rti.dds.type.builtin.*;

...

KeyedStringSeq dataSeq = new KeyedStringSeq();

SampleInfoSeq infoSeq = new SampleInfoSeq();

KeyedStringDataReader stringReader = ... ;

/* Take and print the data */ stringReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) {

if (((SampleInfo)infoSeq.get(i)).valid_data) { System.out.println((

(KeyedString)dataSeq.get(i)).toString());

}

3-19

Built-in Data Types

}

/* Return loan */ stringReader.return_loan(dataSeq, infoSeq);

3.2.6Octets Built-in Type

The octets built-in type is used to send sequences of octets. The language-specific representa- tions are as follows:

C/C++ Representation (without Namespaces):

struct DDS_Octets { int length;

unsigned char * value;

};

C++/CLI Representation:

namespace DDS {

public ref struct Bytes: { public:

System::Int32 length; System::Int32 offset; array<System::Byte>^ value;

...

};

};

C# Representation:

namespace DDS {

public class Bytes {

public System.Int32 length; public System.Int32 offset; public System.Byte[] value;

...

};

};

Java Representation:

package com.rti.dds.type.builtin;

public class Bytes implements Copyable { public int length;

public int offset; public byte[] value;

...

};

3.2.6.1Creating and Deleting Octets

Connext provides a set of constructors/destructors to create and destroy Octet objects. For details, see the API Reference HTML documentation, which is available for all supported pro- gramming languages (select Modules, DDS API Reference, Topic Module, Built-in Types).

If you want to manipulate the memory of the value field inside the Octets struct in C/C++, use the operations DDS::OctetBuffer_alloc(), DDS::OctetBuffer_dup(), and

DDS::OctetBuffer_free(), described in the API Reference HTML documentation (select Mod- ules, DDS API Reference, Infrastructure Module, Octet Buffer Support).

3-20

Built-in Data Types

3.2.6.2Octets DataWriter

In addition to the standard methods (see Using a Type-Specific DataWriter (FooDataWriter) (Section 6.3.7)), the octets DataWriter API is extended with the following methods:

DDS::ReturnCode_t DDS::OctetsDataWriter::write(

const DDS::OctetSeq & octets,

const DDS::InstanceHandle_t & handle);

DDS::ReturnCode_t DDS::OctetsDataWriter::write(

const unsigned char * octets, int length,

const DDS::InstanceHandle_t& handle);

DDS::ReturnCode_t DDS::OctetsDataWriter::write_w_timestamp( const DDS::OctetSeq & octets,

const DDS::InstanceHandle_t & handle, const DDS::Time_t & source_timestamp);

DDS::ReturnCode_t DDS::OctetsDataWriter::write_w_timestamp( const unsigned char * octets, int length,

const DDS::InstanceHandle_t& handle, const DDS::Time_t& source_timestamp);

These methods are introduced to provide maximum flexibility in the format of the input param- eters for the write operations. For additional information and a complete description of these operations in all supported languages, see the API Reference HTML documentation.

The following examples show how to write an array of octets using an octets built-in type DataWriter and some of the extended APIs. For simplicity, error handling is not shown.

C Example:

DDS_OctetsDataWriter * octetsWriter = ... ; DDS_ReturnCode_t retCode;

struct DDS_Octets * octets = NULL; char * octetArray = NULL;

/* Write some data using the Octets structure */ octets = DDS_Octets_new_w_size(1024); octets->length = 2;

octets->value[0] = 46; octets->value[1] = 47;

retCode = DDS_OctetsDataWriter_write(octetsWriter, octets, &DDS_HANDLE_NIL); DDS_Octets_delete(octets);

/* Write some data using an octets array */ octetArray = (unsigned char *)malloc(1024); octetArray[0] = 46;

octetArray[1] = 47;

retCode = DDS_OctetsDataWriter_write_octets (octetsWriter, octetArray, 2, &DDS_HANDLE_NIL);

free(octetArray);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

3-21

Built-in Data Types

OctetsDataWriter * octetsWriter = ... ;

/* Write some data using the Octets structure */ Octets * octets = new Octets(1024); octets->length = 2;

octets->value[0] = 46; octets->value[1] = 47;

ReturnCode_t retCode = octetsWriter->write(octets, HANDLE_NIL);

delete octets;

/* Write

some

data using an octet array */

unsigned

char

* octetArray = new unsigned char[1024];

octetArray[0]

= 46;

octetArray[1]

= 47;

retCode = octetsWriter->write(octetArray, 2, HANDLE_NIL);

delete []octetArray;

C++/CLI Example:

using namespace System; using namespace DDS;

...

BytesDataWriter^ octetsWriter = ...;

/* Write some data using Bytes */ Bytes^ octets = gcnew Bytes(1024); octets->value[0] =46; octets->value[1] =47; octets.length = 2;

octets.offset = 0;

octetWriter->write(octets, InstanceHandle_t::HANDLE_NIL);

/* Write some data using individual strings */ array<Byte>^ octetAray = gcnew array<Byte>(1024); octetArray[0] = 46;

octetArray[1] = 47;

octetsWriter->write(octetArray, 0, 2, InstanceHandle_t::HANDLE_NIL);

C# Example:

using System; using DDS;

...

BytesDataWriter stringWriter = ...;

/* Write some data using the Bytes */ Bytes octets = new Bytes(1024); octets.value[0] = 46;

octets.value[1] = 47; octets.length = 2; octets.offset = 0;

octetWriter.write(octets, InstanceHandle_t.HANDLE_NIL);

/* Write some data using individual strings */ byte[] octetArray = new byte[1024]; octetArray[0] = 46;

3-22

Built-in Data Types

octetArray[1] = 47;

octetsWriter.write(octetArray, 0, 2, InstanceHandle_t.HANDLE_NIL);

Java Example:

import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;

...

BytesDataWriter octetsWriter = ... ;

/* Write some data using the Bytes class*/ Bytes octets = new Bytes(1024); octets.length = 2;

octets.offset = 0; octets.value[0] = 46; octets.value[1] = 47;

octetsWriter.write(octets, InstanceHandle_t.HANDLE_NIL);

/* Write some data using a byte array */ byte[] octetArray = new byte[1024]; octetArray[0] = 46;

octetArray[1] = 47;

octetsWriter.write(octetArray, 0, 2, InstanceHandle_t.HANDLE_NIL);

3.2.6.3Octets DataReader

The octets DataReader API matches the standard DataReader API (see Using a Type-Specific DataReader (FooDataReader) (Section 7.4.1)). There are no extensions.

Memory considerations in copy operations:

For read/take operations with copy semantics, such as read_next_sample() and take_next_sample(), Connext allocates memory for the field 'value' if it is initialized to NULL.

If the field 'value' is not initialized to NULL, the behavior depends on the language:

In Java and .NET, the memory for the field 'value' will be reallocated if the current size is not large enough to hold the received data.

In C and C++, the memory associated with the field 'value' must be big enough to hold the received data. Insufficient memory may result in crashes.

The following examples show how to read octets with an octets built-in type DataReader. For simplicity, error handling is not shown.

C Example:

struct DDS_OctetsSeq dataSeq = DDS_SEQUENCE_INITIALIZER; struct DDS_SampleInfoSeq infoSeq = DDS_SEQUENCE_INITIALIZER; DDS_OctetsDataReader * octetsReader = ... ;

DDS_ReturnCode_t retCode; int i;

/* Take and print the data */

retCode = DDS_OctetsDataReader_take(octetsReader, &dataSeq, &infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);

3-23

Built-in Data Types

for (i = 0; i < DDS_OctetsSeq_get_length(&dataSeq); ++i) {

if (DDS_SampleInfoSeq_get_reference(&infoSeq, i)->valid_data) { DDS_OctetsTypeSupport_print_data(

DDS_OctetsSeq_get_reference(&dataSeq, i));

}

}

/* Return loan */

retCode = DDS_OctetsDataReader_return_loan(octetsReader, &dataSeq, &infoSeq);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

OctetsSeq dataSeq; SampleInfoSeq infoSeq;

OctetsDataReader * octetsReader = ... ;

/* Take a print the data */

ReturnCode_t retCode = octetsReader->take(dataSeq, infoSeq, LENGTH_UNLIMITED, ANY_SAMPLE_STATE, ANY_VIEW_STATE,ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq[i].valid_data) {

OctetsTypeSupport::print_data(&dataSeq[i]);

}

}

/* Return loan */

retCode = octetsReader->return_loan(dataSeq, infoSeq);

C++/CLI Example:

using namespace System; using namespace DDS;

...

BytesSeq^ dataSeq = gcnew BytesSeq();

SampleInfoSeq^ infoSeq = gcnew SampleInfoSeq();

BytesDataReader^ octetsReader = ... ;

/* Take and print the data */ octetsReader->take(dataSeq, infoSeq,

ResourceLimitsQosPolicy::LENGTH_UNLIMITED, SampleStateKind::ANY_SAMPLE_STATE, ViewStateKind::ANY_VIEW_STATE, InstanceStateKind::ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq->get_at(i)->valid_data) {

BytesTypeSupport::print_data(dataSeq->get_at(i));

}

}

/* Return loan */ octetsReader->return_loan(dataSeq, infoSeq);

C# Example:

using System; using DDS;

...

BytesSeq dataSeq = new BytesSeq(); SampleInfoSeq infoSeq = new SampleInfoSeq(); BytesDataReader octetsReader = ... ;

3-24

Built-in Data Types

/* Take and print the data */ octetsReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq.get_at(i)).valid_data) {

BytesTypeSupport.print_data(dataSeq.get_at(i));

}

}

/* Return loan */ octetsReader.return_loan(dataSeq, infoSeq);

Java Example:

import com.rti.dds.infrastructure.*; import com.rti.dds.subscription.*; import com.rti.dds.type.builtin.*;

...

BytesSeq dataSeq = new BytesSeq(); SampleInfoSeq infoSeq = new SampleInfoSeq(); BytesDataReader octetsReader = ... ;

/* Take and print the data */ octetsReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) {

if (((SampleInfo)infoSeq.get(i)).valid_data) { System.out.println(((Bytes)dataSeq.get(i)).toString());

}

}

/* Return loan */ octetsReader.return_loan(dataSeq, infoSeq);

3.2.7KeyedOctets Built-in Type

The keyed octets built-in type is used to send sequences of octets with a key. The language-spe- cific representations of the type are as follows:

C/C++ Representation (without Namespaces):

struct DDS_KeyedOctets { char * key;

int length;

unsigned char * value;

};

C++/CLI Representation:

namespace DDS {

public ref struct KeyedBytes { public:

System::String^ key; System::Int32 length; System::Int32 offset; array<System::Byte>^ value;

3-25

Built-in Data Types

...

};

};

C# Representation:

namespace DDS {

public class KeyedBytes { public System.String key; public System.Int32 length; public System.Int32 offset; public System.Byte[] value;

};

};

Java Representation:

package com.rti.dds.type.builtin; public class KeyedBytes {

public String key; public int length; public int offset; public byte[] value;

...

};

3.2.7.1Creating and Deleting KeyedOctets

Connext provides a set of constructors/destructors to create/destroy KeyedOctets objects. For details, see the API Reference HTML documentation, which is available for all supported pro- gramming languages (select Modules, DDS API Reference, Topic Module, Built-in Types).

To manipulate the memory of the value field in the KeyedOctets struct in C/C++: use

DDS::OctetBuffer_alloc(), DDS::OctetBuffer_dup(), and DDS::OctetBuffer_free(). See the API Reference HTML documentation (select Modules, DDS API Reference, Infrastructure Module, Octet Buffer Support).

To manipulate the memory of the key field in the KeyedOctets struct in C/C++: use

DDS::String_alloc(), DDS::String_dup(), and DDS::String_free(). See the API Reference HTML documentation (select Modules, DDS API Reference, Infrastructure Module, String Support).

3.2.7.2Keyed Octets DataWriter

In addition to the standard methods (see Using a Type-Specific DataWriter (FooDataWriter) (Section 6.3.7)), the keyed octets DataWriter API is extended with the following methods:

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::dispose( const char* key,

const DDS::InstanceHandle_t & instance_handle);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::dispose_w_timestamp( const char* key,

const DDS::InstanceHandle_t & instance_handle, const DDS::Time_t & source_timestamp);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::get_key_value( char * key,

const DDS::InstanceHandle_t& handle);

DDS::InstanceHandle_t DDS::KeyedOctetsDataWriter::lookup_instance(

const char * key);

3-26

Built-in Data Types

DDS::InstanceHandle_t DDS::KeyedOctetsDataWriter::register_instance(

const char* key);

DDS::InstanceHandle_t

DDS::KeyedOctetsDataWriter::register_instance_w_timestamp(

const char * key,

const DDS::Time_t & source_timestamp);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::unregister_instance( const char * key,

const DDS::InstanceHandle_t & handle);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::unregister_instance_w_timestamp(

const char* key,

const DDS::InstanceHandle_t & handle, const DDS::Time_t & source_timestamp);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::write( const char * key,

const unsigned char * octets, int length,

const DDS::InstanceHandle_t& handle);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::write( const char * key,

const DDS::OctetSeq & octets,

const DDS::InstanceHandle_t & handle);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::write_w_timestamp( const char * key,

const unsigned char * octets, int length,

const DDS::InstanceHandle_t& handle, const DDS::Time_t& source_timestamp);

DDS::ReturnCode_t DDS::KeyedOctetsDataWriter::write_w_timestamp( const char * key,

const DDS::OctetSeq & octets,

const DDS::InstanceHandle_t & handle, const DDS::Time_t & source_timestamp);

These methods are introduced to provide maximum flexibility in the format of the input param- eters for the write and instance management operations. For more information and a complete description of these operations in all supported languages, see the API Reference HTML docu- mentation.

The following examples show how to write keyed octets using a keyed octets built-in type DataWriter and some of the extended APIs. For simplicity, error handling is not shown.

C Example:

DDS_KeyedOctetsDataWriter * octetsWriter = ... ; DDS_ReturnCode_t retCode;

struct DDS_KeyedOctets * octets = NULL; char * octetArray = NULL;

/* Write some data using the KeyedOctets structure */ octets = DDS_KeyedOctets_new_w_size(128,1024); strcpy(octets->key, "Key 1");

3-27

Built-in Data Types

octets->length = 2; octets->value[0] = 46; octets->value[1] = 47;

retCode = DDS_KeyedOctetsDataWriter_write(

octetsWriter, octets, &DDS_HANDLE_NIL);

DDS_KeyedOctets_delete(octets);

/* Write some data using an octets array */ octetArray = (unsigned char *)malloc(1024); octetArray[0] = 46;

octetArray[1] = 47;

retCode = DDS_KeyedOctetsDataWriter_write_octets_w_key ( octetsWriter, "Key 1", octetArray, 2, &DDS_HANDLE_NIL);

free(octetArray);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

KeyedOctetsDataWriter * octetsWriter = ... ;

/* Write some data using the KeyedOctets structure */ KeyedOctets * octets = new KeyedOctets(128,1024); strcpy(octets->key, "Key 1");

octets->length = 2; octets->value[0] = 46; octets->value[1] = 47;

ReturnCode_t retCode = octetsWriter->write(octets, HANDLE_NIL);

delete octets;

/* Write

some

data using an octet array */

unsigned

char

* octetArray = new unsigned char[1024];

octetArray[0]

= 46;

octetArray[1]

= 47;

retCode = octetsWriter->write("Key 1", octetArray, 2, HANDLE_NIL);

delete []octetArray;

C++/CLI Example:

using namespace System; using namespace DDS;

...

KeyedOctetsDataWriter^ octetsWriter = ... ;

/* Write some data using KeyedBytes */ KeyedBytes^ octets = gcnew KeyedBytes(1024); octets->key = "Key 1";

octets->value[0] =46; octets->value[1] =47; octets.length = 2; octets.offset = 0;

3-28

Built-in Data Types

octetWriter->write(octets, InstanceHandle_t::HANDLE_NIL);

/* Write some data using individual strings */ array<Byte>^ octetAray = gcnew array<Byte>(1024); octetArray[0] = 46;

octetArray[1] = 47;

octetsWriter->write(

"Key 1", octetArray, 0, 2, InstanceHandle_t::HANDLE_NIL);

C# Example:

using System; using DDS;

...

KeyedBytesDataWriter stringWriter = ... ;

/* Write some data using the KeyedBytes */ KeyedBytes octets = new KeyedBytes(1024); octets.key = "Key 1";

octets.value[0] = 46; octets.value[1] = 47; octets.length = 2; octets.offset = 0;

octetWriter.write(octets, InstanceHandle_t.HANDLE_NIL);

/* Write some data using individual strings */ byte[] octetArray = new byte[1024]; octetArray[0] = 46;

octetArray[1] = 47;

octetsWriter.write(

"Key 1", octetArray, 0, 2, InstanceHandle_t.HANDLE_NIL);

Java Example:

import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;

...

KeyedBytesDataWriter octetsWriter = ... ;

/* Write some data using the KeyedBytes class*/ KeyedBytes octets = new KeyedBytes(1024); octets.key = "Key 1";

octets.length = 2; octets.offset = 0; octets.value[0] = 46; octets.value[1] = 47;

octetsWriter.write(octets, InstanceHandle_t.HANDLE_NIL);

/* Write some data using a byte array */ byte[] octetArray = new byte[1024]; octetArray[0] = 46;

octetArray[1] = 47; octetsWriter.write(

"Key 1", octetArray, 0, 2, InstanceHandle_t.HANDLE_NIL);

3-29

Built-in Data Types

3.2.7.3Keyed Octets DataReader

The KeyedOctets DataReader API is extended with the following methods (in addition to the standard methods described in Using a Type-Specific DataReader (FooDataReader) (Section 7.4.1)):

DDS::ReturnCode_t DDS::KeyedOctetsDataReader::get_key_value( char * key,

const DDS::InstanceHandle_t* handle);

DDS::InstanceHandle_t DDS::KeyedOctetsDataReader::lookup_instance(

const char * key);

For more information and a complete description of these operations in all supported lan- guages, see the API Reference HTML documentation.

Memory considerations in copy operations:

For read/take operations with copy semantics, such as read_next_sample() and take_next_sample(), Connext allocates memory for the fields 'value' and 'key' if they are initialized to NULL.

If the fields are not initialized to NULL, the behavior depends on the language:

In Java and .NET, the memory of the field 'value' will be reallocated if the current size is not large enough to hold the received data. The memory associated with the field 'key' will be reallocated with every sample (the key is an immutable object).

In C and C++, the memory associated with the fields 'value' and 'key' must be large enough to hold the received data. Insufficient memory may result in crashes.

The following examples show how to read keyed octets with a keyed octets built-in type DataReader. For simplicity, error handling is not shown.

C Example:

struct DDS_KeyedOctetsSeq dataSeq = DDS_SEQUENCE_INITIALIZER; struct DDS_SampleInfoSeq infoSeq = DDS_SEQUENCE_INITIALIZER; DDS_KeyedOctetsDataReader * octetsReader = ... ; DDS_ReturnCode_t retCode;

int i;

/* Take and print the data */

retCode = DDS_KeyedOctetsDataReader_take( octetsReader,

&dataSeq, &infoSeq, DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);

for (i = 0; i < DDS_KeyedOctetsSeq_get_length(&data_seq); ++i) {

if (DDS_SampleInfoSeq_get_reference(&info_seq, i)->valid_data) { DDS_KeyedOctetsTypeSupport_print_data(

DDS_KeyedOctetsSeq_get_reference(&data_seq, i));

}

}

/* Return loan */

retCode = DDS_KeyedOctetsDataReader_return_loan(

octetsReader, &data_seq, &info_seq);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

KeyedOctetsSeq dataSeq;

3-30

Built-in Data Types

SampleInfoSeq infoSeq;

KeyedOctetsDataReader * octetsReader = ... ;

/* Take a print the data */

ReturnCode_t retCode = octetsReader->take( dataSeq, infoSeq, LENGTH_UNLIMITED,

ANY_SAMPLE_STATE, ANY_VIEW_STATE, ANY_INSTANCE_STATE); for (int i = 0; i < data_seq.length(); ++i) {

if (infoSeq[i].valid_data) { KeyedOctetsTypeSupport::print_data(&dataSeq[i]);

}

}

/* Return loan */

retCode = octetsReader->return_loan(dataSeq, infoSeq);

C++/CLI Example:

using namespace System; using namespace DDS;

...

KeyedBytesSeq^ dataSeq = gcnew KeyedBytesSeq(); SampleInfoSeq^ infoSeq = gcnew SampleInfoSeq(); KeyedBytesDataReader^ octetsReader = ... ;

/* Take and print the data */ octetsReader->take(dataSeq, infoSeq,

ResourceLimitsQosPolicy::LENGTH_UNLIMITED, SampleStateKind::ANY_SAMPLE_STATE, ViewStateKind::ANY_VIEW_STATE, InstanceStateKind::ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq->get_at(i)->valid_data) {

KeyedBytesTypeSupport::print_data(dataSeq->get_at(i));

}

}

/* Return loan */ octetsReader->return_loan(dataSeq, infoSeq);

C# Example:

using System; using DDS;

...

KeyedBytesSeq dataSeq = new KeyedButesSeq(); SampleInfoSeq infoSeq = new SampleInfoSeq(); KeyedBytesDataReader octetsReader = ... ;

/* Take and print the data */ octetsReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) { if (infoSeq.get_at(i)).valid_data) {

KeyedBytesTypeSupport.print_data(dataSeq.get_at(i));

}

}

/* Return loan */ octetsReader.return_loan(dataSeq, infoSeq);

3-31

Built-in Data Types

Java Example:

import com.rti.dds.infrastructure.*; import com.rti.dds.subscription.*; import com.rti.dds.type.builtin.*;

...

KeyedBytesSeq dataSeq = new KeyedBytesSeq(); SampleInfoSeq infoSeq = new SampleInfoSeq(); KeyedBytesDataReader octetsReader = ... ;

/* Take and print the data */ octetsReader.take(dataSeq, infoSeq,

ResourceLimitsQosPolicy.LENGTH_UNLIMITED, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE);

for (int i = 0; i < data_seq.length(); ++i) {

if (((SampleInfo)infoSeq.get(i)).valid_data) { System.out.println(((KeyedBytes)dataSeq.get(i)).toString());

}

}

/* Return loan */ octetsReader.return_loan(dataSeq, infoSeq);

3.2.8Managing Memory for Built-in Types

When a sample is written, the DataWriter serializes it and stores the result in a buffer obtained from a pool of preallocated buffers. In the same way, when a sample is received, the DataReader deserializes it and stores the result in a sample coming from a pool of preallocated samples.

For data types generated by rtiddsgen, the size of the buffers and samples in both pools is known based on the IDL or XML description of the type.

For example:

struct MyString { string<128> value;

};

This IDL-defined type has a maximum serialized size of 133 bytes (4 bytes for length + 128 char- acters + 1 NULL terminating character). So the serialization buffers will have a size of 133 bytes. It can hold samples with 128 characters strings. Consequently, the preallocated samples will be sized to keep this length.

However, for built-in types, the maximum size of the buffers/samples is unknown and depends on the nature of the application using the built-in type.

For example, a video surveillance application that is using the keyed octets built-in type to pub- lish a stream of images will require bigger buffers than a market-data application that uses the same built-in type to publish market-data values.

To accommodate both kinds of applications and optimize memory usage, you can configure the maximum size of the built-in types on a per-DataWriter or per-Datareader basis using the PROP- ERTY QosPolicy (DDS Extension) (Section 6.5.17). Table 3.1 on page 3-33 lists the supported built-in type properties. When the properties are defined in the DomainParticipant, they are applicable to all DataWriters and DataReaders belonging to the DomainParticipant, unless they are overwritten in the DataWriters and DataReaders.

Note: These properties must be set consistently with respect to the corresponding *.max_size properties in the DomainParticipant (see Table 3.16 on page 3-92). The value of the alloc_size

3-32

Built-in Data Types

property must be less than or equal to the max_size property with the same name prefix in the

DomainParticipant.

Section 3.2.8.1 includes examples of how to set the maximum size of a string built-in type for a DataWriter programmatically, for each API. You can also set the maximum size of the built-in types using XML QoS Profiles. For example, the following XML shows how to set the maximum size of a string built-in type for a DataWriter.

<dds>

<qos_library name="BuiltinExampleLibrary"> <qos_profile name="BuiltinExampleProfile">

<datawriter_qos> <property>

<value>

<element> <name>dds.builtin_type.string.alloc_size</name> <value>2048</value>

</element>

</value>

</property> </datawriter_qos> <datareader_qos>

<property>

<value>

<element> <name>dds.builtin_type.string.alloc_size</name> <value>2048</value>

</element>

</value>

</property> </datareader_qos>

</qos_profile> </qos_library>

</dds>

Table 3.1 Properties for Allocating Size of Built-in Types, per DataWriter and DataReader

Built-in

Property

 

Description

 

Type

 

 

 

 

 

 

 

 

 

 

 

Maximum size of the strings published by the DataWriter

 

 

or received by the DataReader (includes the NULL-termi-

string

dds.builtin_type.string.alloc_size

nated character).

 

 

 

Default: dds.builtin_type.string.max_size if defined (see

 

 

Table 3.16 on page 3-92). Otherwise, 1024.

 

 

 

 

 

 

Maximum size of the keys used by the DataWriter or

 

dds.builtin_type.keyed_string.

DataReader (includes the NULL-terminated character).

 

 

alloc_key_size

Default: dds.builtin_type.keyed_string.max_key_size if

keyed-

 

defined (see Table 3.16 on page 3-92). Otherwise, 1024.

 

 

 

 

 

 

Maximum size of the strings published by the DataWriter

string

 

 

or received by the DataReader (includes the NULL-termi-

 

dds.builtin_type.keyed_string.

 

nated character).

 

 

alloc_size

 

 

Default:

dds.builtin_type.keyed_string.max_size

if

 

 

 

 

defined (see Table 3.16 on page 3-92). Otherwise, 1024.

 

 

 

 

 

 

Maximum size of the octet sequences published by the

octets

dds.builtin_type.octets.alloc_size

DataWriter or DataReader.

 

 

 

Default: dds.builtin_type.octets.max_size if defined (see

 

 

Table 3.16 on page 3-92). Otherwise, 2048.

 

 

 

 

 

 

3-33

Built-in Data Types

Table 3.1 Properties for Allocating Size of Built-in Types, per DataWriter and DataReader

Built-in

Property

 

Description

 

Type

 

 

 

 

 

 

 

 

 

 

 

Maximum size of the key published by the DataWriter or

 

dds.builtin_type.keyed_octets.

received

by the DataReader (includes the NULL-termi-

 

nated character).

 

 

alloc_key_size

 

 

Default:

dds.builtin_type.keyed_octets.max_key_size

if

keyed-

 

 

defined (see Table 3.16 on page 3-92). Otherwise, 1024.

 

octets

 

 

 

 

 

 

 

Maximum size of the octet sequences published by the

 

 

 

dds.builtin_type.keyed_octets.

DataWriter or DataReader.

 

 

alloc_size

Default:

dds.builtin_type.keyed_octets.max_size

if

 

 

defined (see Table 3.16 on page 3-92). Otherwise, 2048.

 

 

 

 

 

 

3.2.8.1Examples—Setting the Maximum Size for a String Programmatically

For simplicity, error handling is not shown in the following examples.

C Example:

DDS_DataWriter * writer = NULL; DDS_StringDataWriter * stringWriter = NULL; DDS_Publisher * publisher = ... ;

DDS_Topic * stringTopic = ... ;

struct DDS_DataWriterQos writerQos = DDS_DataWriterQos_INITIALIZER; DDS_ReturnCode_t retCode;

retCode = DDS_DomainParticipant_get_default_datawriter_qos ( participant, &writerQos);

retCode = DDS_PropertyQosPolicyHelper_add_property ( &writerQos.property, "dds.builtin_type.string.alloc_size", "1000", DDS_BOOLEAN_FALSE);

writer = DDS_Publisher_create_datawriter(

publisher, stringTopic, &writerQos, NULL, DDS_STATUS_MASK_NONE);

stringWriter = DDS_StringDataWriter_narrow(writer); DDS_DataWriterQos_finalize(&writerQos);

C++ Example with Namespaces:

#include "ndds/ndds_namespace_cpp.h" using namespace DDS;

...

Publisher * publisher = ... ;

Topic * stringTopic = ... ;

DataWriterQos writerQos;

ReturnCode_t retCode = participant->get_default_datawriter_qos(writerQos);

retCode = PropertyQosPolicyHelper::add_property (

&writerQos.property, dds.builtin_type.string.alloc_size", "1000", BOOLEAN_FALSE);

DataWriter * writer = publisher->create_datawriter( stringTopic, writerQos, NULL, STATUS_MASK_NONE);

3-34

Built-in Data Types

StringDataWriter * stringWriter = StringDataWriter::narrow(writer);

C++/CLI Example:

using namespace DDS;

...

Topic^ stringTopic = ... ;

Publisher^ publisher = ... ;

DataWriterQos^ writerQos = gcnew DataWriterQos();

participant->get_default_datawriter_qos(writerQos);

PropertyQosPolicyHelper::add_property(writerQos->property_qos,

"dds.builtin_type.string.alloc_size","1000", false);

DataWriter^ writer = publisher->create_datawriter(stringTopic, writerQos, nullptr, StatusMask::STATUS_MASK_NONE);

StringDataWriter^ stringWriter = safe_cast<StringDataWriter^>(writer);

C# Example:

using DDS;

...

Topic stringTopic = ... ;

Publisher publisher = ... ;

DataWriterQos writerQos = new DataWriterQos();

participant.get_default_datawriter_qos(writerQos);

PropertyQosPolicyHelper.add_property (writerQos.property_qos,

"dds.builtin_type.string.alloc_size", "1000", false);

StringDataWriter stringWriter =

(StringDataWriter) publisher.create_datawriter(stringTopic, writerQos, null, StatusMask.STATUS_MASK_NONE);

Java Example:

import com.rti.dds.publication.*; import com.rti.dds.type.builtin.*; import com.rti.dds.infrastructure.*;

...

Topic stringTopic = ... ;

Publisher publisher = ... ;

DataWriterQos writerQos = new DataWriterQos();

participant.get_default_datawriter_qos(writerQos);

PropertyQosPolicyHelper.add_property (writerQos.property,

"dds.builtin_type.string.alloc_size", "1000", false);

StringDataWriter stringWriter =

(StringDataWriter) publisher.create_datawriter(stringTopic, writerQos, null, StatusKind.STATUS_MASK_NONE);

3-35

Built-in Data Types

3.2.9Type Codes for Built-in Types

The type codes associated with the built-in types are generated from the following IDL type def- initions:

module DDS {

/* String */ struct String {

string<max_size> value;

};

/* KeyedString */ struct KeyedString {

string<max_size> key; //@key string<max_size> value;

};

/* Octets */ struct Octets {

sequence<octet, max_size> value;

};

/* KeyedOctets */ struct KeyedOctets {

string<max_size> key; //@key sequence<octet, max_size> value;

};

};

The maximum size (max_size) of the strings and sequences that will be included in the type code definitions can be configured on a per-DomainParticipant-basis by using the properties in Table 3.2.

Table 3.2 Properties for Allocating Size of Built-in Types, per DomainParticipant

Built-in

Property

Description

Type

 

 

 

 

 

 

 

 

 

 

Maximum size of the strings published by the DataWriters

String

dds.builtin_type.string.max_size

and received by the DataReaders belonging to a DomainPar-

ticipant (includes the NULL-terminated character).

 

 

 

 

Default: 1024

 

 

 

 

 

Maximum size of the keys used by the DataWriters and

 

dds.builtin_type.keyed_string.

DataReaders belonging to a DomainParticipant (includes the

 

max_key_size

NULL-terminated character).

Keyed-

 

Default: 1024

 

 

 

Maximum size of the strings published by the DataWriters

String

 

 

and received by the DataReaders belonging to a DomainPar-

 

dds.builtin_type.keyed_string.

 

ticipant using the built-in type (includes the NULL-termi-

 

max_size

 

nated character).

 

 

 

 

Default: 1024

 

 

 

 

 

Maximum size of the octet sequences published by the

Octets

dds.builtin_type.octets.max_size

DataWriters and DataReaders belonging to a DomainPartici-

pant.

 

 

 

 

Default: 2048

 

 

 

3-36

 

 

 

Creating User Data Types with IDL

Table 3.2 Properties for Allocating Size of Built-in Types, per DomainParticipant

 

 

 

 

 

Built-in

Property

Description

 

Type

 

 

 

 

 

 

 

 

 

 

Maximum size of the key published by the DataWriter and

 

 

dds.builtin_type.keyed_octets.

received by the DataReaders belonging to the

 

 

DomainParticipant (includes the NULL-terminated charac-

 

 

max_key_size

 

 

ter).

 

Keyed-

 

 

 

Default:1024.

 

Octets

 

 

 

 

 

 

Maximum size of the octet sequences published by the

 

 

 

 

 

dds.builtin_type.keyed_octets.

DataWriters and DataReaders belonging to a DomainPartici-

 

 

max_size

pant.

 

 

 

Default: 2048

 

 

 

 

3.3Creating User Data Types with IDL

You can create user data types in a text file using IDL (Interface Description Language). IDL is programming-language independent, so the same file can be used to generate code in C, C++, C++/CLI, and Java (the languages supported by rtiddsgen). The rtiddsgen utility parses the IDL file and automatically generates all the necessary routines and wrapper functions to bind the types for use by Connext at run time. You will end up with a set of required routines and struc- tures that your application and Connext will use to manipulate the data.

Connext only uses a subset of the IDL syntax. IDL was originally defined by the OMG for the use of CORBA client/server applications in an enterprise setting. Not all of the constructs that can be described by the language are as useful in the context of high-performance data-centric embedded applications. These include the constructs that define method and function proto- types like “interface.”

The rtiddsgen utility will parse any file that follows version 3.0.3 of the IDL specification. It will quietly ignore all syntax that is not recognized by Connext. In addition, even though “anony- mous sequences” (sequences of sequences with no intervening typedef) are currently legal in IDL, they have been deprecated by the specification, and thus rtiddsgen does not support them.

Certain keywords are considered reserved by the IDL specification; see Table 3.3.

Table 3.3 Reserved IDL Keywords

abstract

emits

local

pseudo

typeid

 

 

 

 

 

alias

enum

long

public

typename

 

 

 

 

 

any

eventtype

mirrorport

publishes

typeprefix

 

 

 

 

 

attribute

exception

module

raises

union

 

 

 

 

 

boolean

factory

multiple

readonly

unsigned

 

 

 

 

 

case

FALSE

native

sequence

uses

 

 

 

 

 

char

finder

object

setraises

valuebase

 

 

 

 

 

component

fixed

octet

short

valuetype

 

 

 

 

 

connector

float

oneway

string

void

 

 

 

 

 

const

getraises

out

struct

wchar

 

 

 

 

 

consumes

home

port

supports

wstring

 

 

 

 

 

context

import

porttype

switch

 

 

 

 

 

 

custom

in

primarykey

TRUE

 

 

 

 

 

 

3-37

Creating User Data Types with IDL

Table 3.3 Reserved IDL Keywords

default

inout

private

truncatable

 

 

 

 

 

 

double

interface

provides

typedef

 

 

 

 

 

 

The IDL constructs supported by rtiddsgen are described in Table 3.5, “Specifying Data Types in IDL for C and C++,” on page 3-40 and Table 3.7, “Specifying Data Types in IDL for Java,” on page 3-48. Use these tables to map primitive types to their equivalent IDL syntax, and vice versa.

For C and C++, rtiddsgen uses typedefs instead of the language keywords for primitive types. For example, DDS_Long instead of long or DDS_Double instead of double. This ensures that the types are of the same size regardless of the platform.1

The remainder of this section includes:

Variable-Length Types (Section 3.3.1)

Value Types (Section 3.3.2)

TypeCode and rtiddsgen (Section 3.3.3)

rtiddsgen Translations for IDL Types (Section 3.3.4)

Escaped Identifiers (Section 3.3.5)

Referring to Other IDL Files (Section 3.3.6)

Preprocessor Directives (Section 3.3.7)

Using Custom Directives (Section 3.3.8)

3.3.1Variable-Length Types

When rtiddsgen generates code for data structures with variable-length types—strings and sequences—it includes functions that create, initialize and finalize (destroy) those objects. These support functions will properly initialize pointers and allocate and deallocate the memory used for variable-length types. All Connext APIs assume that the data structures passed to them are properly initialized.

For variable-length types, the actual length (instead of the maximum length) of data is transmit- ted on the wire when the sample is written (regardless of whether the type has hard-coded bounds).

3.3.1.1Sequences

C, C++, C++/CLI, and C# users can allocate memory from a number of sources: from the heap, the stack, or from a custom allocator of some kind. In those languages, sequences provide the concept of memory "ownership." A sequence may own the memory allocated to it or be loaned memory from another source. If a sequence owns its memory, it will manage its underlying memory storage buffer itself. When a sequence's maximum size is changed, the sequence will free and reallocate its buffer as needed. However, if a sequence was created with loaned mem- ory by user code, then its memory is not its own to free or reallocate. Therefore, you cannot set the maximum size of a sequence whose memory is loaned. See the API Reference HTML docu- mentation, which is available for all supported programming languages (select Modules, DDS

1.The number of bytes sent on the wire for each data type is determined by the Common Data Representation (CDR) standard. For details on CDR, please see the Common Object Request Broker Architecture (CORBA) Specifica- tion, Version 3.1, Part 2: CORBA Interoperability, Section 9.3, CDR Transfer Syntax (http://www.omg.org/technology/ documents/corba_spec_catalog.htm).

3-38

Creating User Data Types with IDL

API Reference, Infrastructure Module, Sequence Support) for more information about how to loan and unloan memory for sequence.

In IDL, as described above, a sequence may be declared as bounded or unbounded. A sequence's "bound" is the greatest value its maximum may take. If you use the initializer func- tions rtiddsgen provides for your types, all sequences will have their maximums set to their declared bounds. However, the amount of data transmitted on the wire when the sample is writ- ten will vary.

3.3.1.2Strings and Wide Strings

The initialization functions that rtiddsgen provides for your types will allocate all of the memory for strings in a type to their declared bounds. Take care—if you assign a string pointer (char *) in a data structure allocated or initialized by a Connext-generated function, you should release (free) the memory originally allocated for the string, otherwise the memory will be leaked.

To Java and .NET users, an IDL string is a String object: it is immutable and knows its own length. C and C++ users must take care, however, as there is no way to determine how much memory is allocated to a character pointer "string"; all that can be determined is the string's cur- rent logical length. In some cases, Connext may need to copy a string into a structure that user code has provided. Connext does not free the memory of the string provided to it, as it cannot know from where that memory was allocated.

In the C and C++ APIs, Connext therefore uses the following conventions:

A string's memory is "owned" by the structure that contains that string. Calling the final- ization function provided for a type will free all recursively contained strings. If you have allocated a contained string in a special way, you must be careful to clean up your own memory and assign the pointer to NULL before calling the type’s finalize() method, so that Connext will skip over that string.

You must provide a non-NULL string pointer for Connext to copy into. Otherwise, Con- next will log an error.

When you provide a non-NULL string pointer in your data structure, Connext will copy into the provided memory without performing any additional memory allocations. Be careful—if you provide Connext with an uninitialized pointer or allocate a string that is too short, you may corrupt the memory or cause a program crash. Connext will never try to copy a string that is longer than the bound of the destination string. However, your application must insure that any string that it allocates is long enough.

Connext provides a small set of C functions for dealing with strings. These functions simplify common tasks, avoid some platform-specific issues (such as the lack of a strdup() function on some platforms), and provide facilities for dealing with wide strings, for which no standard C library exists. Connext always uses these functions internally for managing string memory; you are recommended—but not required—to use them as well. See the API Reference HTML docu- mentation, which is available for all supported programming languages (select Modules, DDS API Reference, Infrastructure Module, String Support) for more information about strings.

3.3.2Value Types

A value type is like a structure, but with support for additional object-oriented features such as inheritance. It is similar to what is sometimes referred to in Java as a POJO—a Plain Old Java Object.

Readers familiar with value types in the context of CORBA should consult Table 3.4 to see which value type-related IDL keywords are supported and what their behavior is in the context of Con- next.

3-39

 

 

Creating User Data Types with IDL

Table 3.4 Value Type Support

 

 

 

 

 

Aspect

Level of Support in rtiddsgen

 

 

 

 

 

 

 

Inheritance

Single inheritance from other value types

 

 

 

 

Public state members

Supported

 

 

 

 

Private state members

Become public when code is generated

 

 

 

 

Custom keyword

Ignored (the value type is parsed without the keyword and code is generated to

 

work with it)

 

 

 

 

 

 

Abstract value types

No code generated (the value type is parsed, but no code is generated)

 

 

 

 

Operations

No code generated (the value type is parsed, but no code is generated)

 

 

 

 

Truncatable keyword

Ignored (the value type is parsed without the keyword and code is generated to

 

work with it)

 

 

 

 

 

3.3.3TypeCode and rtiddsgen

Type codes are enabled by default when you run rtiddsgen. The -notypecode option disables generation of type code information. Type-code support does increase the amount of memory used, so if you need to save on memory, you may consider disabling type codes. (The -notype- code option is described in rtiddsgen Command-Line Arguments (Section 3.6.1)

Locally, your application can access the type code for a generated type "Foo" by calling the Foo::get_typecode() operation in the code for the type generated by rtiddsgen (unless type-code support is disabled with the -notypecode option).

Note: Type-code support must be enabled if you are going to use ContentFilteredTopics (Section 5.4) with the default SQL filter. You may disable type codes and use a custom filter, as described in Creating ContentFilteredTopics (Section 5.4.3).

3.3.4rtiddsgen Translations for IDL Types

This section describes how to specify your data types in an IDL file. The rtiddsgen utility sup- ports all the types listed in the following tables:

Table 3.5, “Specifying Data Types in IDL for C and C++,” on page 3-40

Table 3.6, “Specifying Data Types in IDL for C++/CLI,” on page 3-45

Table 3.7, “Specifying Data Types in IDL for Java,” on page 3-48

In each table, the middle column shows the syntax for an IDL data type in the IDL file. The rightmost column shows the corresponding language mapping created by rtiddsgen.

Table 3.5 Specifying Data Types in IDL for C and C++

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

char

struct PrimitiveStruct {

typedef struct PrimitiveStruct

{

(see Note 1

char char_member;

DDS_Char char_member;

below)

};

} PrimitiveStruct;

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

{

wchar

wchar wchar_member;

DDS_Wchar wchar_member;

 

};

 

} PrimitiveStruct;

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

octet

{

octet octet_member;

DDS_Octet octect_member;

 

};

 

} PrimitiveStruct;

 

 

 

 

 

3-40

 

 

 

Creating User Data Types with IDL

Table 3.5 Specifying Data Types in IDL for C and C++

 

 

 

 

 

 

 

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

short

{

 

 

short short_member;

 

 

DDS_Short short_member;

 

 

};

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

unsigned

{

 

 

unsigned short

 

 

DDS_UnsignedShort

 

short

unsigned_short_member;

 

unsigned_short_member;

 

 

};

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

 

{

 

 

long

long long_member;

 

 

DDS_Long long_member;

 

 

};

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

unsigned

{

 

 

unsigned long

 

 

DDS_UnsignedLong

 

long

unsigned_long_member;

 

unsigned_long_member;

 

 

};

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

long long

{

 

 

long long long_long_member;

 

 

DDS_LongLong long_long_member;

 

 

};

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

unsigned

{

 

 

unsigned long long

 

 

DDS_UnsignedLongLong

 

long long

unsigned_long_long_member;

 

unsigned_long_long_member;

 

 

};

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

 

{

 

 

float

float float_member;

 

 

DDS_Float float_member;

 

 

};

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

double

{

 

 

double double_member;

 

 

DDS_Double double_member;

 

 

};

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

 

long dou-

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

ble

{

 

 

long double long_double_member;

 

 

(see Note 2

DDS_LongDouble long_double_member;

 

};

 

} PrimitiveStruct;

 

below)

 

 

 

 

 

 

pointer

struct MyStruct {

typedef struct MyStruct {

 

(see Note 9

long * member;

DDS_Long * member;

 

below)

};

} MyStruct;

 

 

 

 

 

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

 

{

 

 

boolean

boolean boolean_member;

 

 

DDS_Boolean boolean_member;

 

 

};

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

 

3-41

 

 

 

 

Creating User Data Types with IDL

Table 3.5 Specifying Data Types in IDL for C and C++

 

 

 

 

 

 

 

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

 

 

 

 

 

 

 

enum PrimitiveEnum {

typedef enum PrimitiveEnum

 

 

 

{

 

 

 

 

ENUM1,

 

 

 

 

ENUM1,

 

 

 

ENUM2,

 

 

 

ENUM2,

 

 

 

ENUM3

 

 

 

ENUM3

 

 

 

};

 

 

 

} PrimitiveEnum;

 

 

 

 

 

enum

 

 

 

 

 

 

 

enum PrimitiveEnum {

typedef enum PrimitiveEnum

 

 

 

{

 

 

 

 

ENUM1 = 10,

 

 

 

 

ENUM1 = 10,

 

 

 

ENUM2 = 20,

 

 

 

ENUM2 = 20,

 

 

 

ENUM3 = 30

 

 

 

ENUM3 = 30

 

 

 

};

 

 

 

} PrimitiveEnum;

 

 

 

 

 

 

 

 

 

 

 

 

 

C: #define SIZE 5

 

constant

const short SIZE = 5;

C++: static const DDS_Short size = 5;

 

 

 

 

 

 

 

 

 

typedef struct BitfieldType

 

 

 

struct BitfieldType {

{

 

 

 

 

short myShort_1 : 1;

DDS_Short myShort_1 : 1;

 

 

 

unsigned short myUnsignedShort_1:

DDS_UnsignedShort myUnsignedShort_1

 

 

 

1;

: 1;

 

 

 

 

long myLong_1: 1;

DDS_Long myLong_1 : 1;

 

 

 

unsigned long myUnsignedLong_1 :1;

DDS_UnsignedLong myUnsignedLong_1 :

 

bitfield

char myChar_1 : 1;

1;

 

 

wchar myWChar_1 : 1;

DDS_Char myChar_1 : 1;

 

 

 

 

 

 

octet myOctet_1 : 1;

DDS_Wchar myWChar_1 : 1;

 

(see

Note

short : 0;

DDS_Octet myOctet_1 : 1;

 

12 below)

long myLong_5 : 5;

DDS_Short : 0;

 

long myLong_30 : 30;

DDS_Long myLong_5 : 5;

 

 

 

 

 

 

short myShort_6 : 6;

DDS_Long myLong_30 : 30;

 

 

 

short myShort_3and4 : 3+4;

DDS_Short myShort_6 : 6;

 

 

 

short myShort;

DDS_Short myShort_3and4 : 3+4;

 

 

 

short myShort_8 : 8;

DDS_Short myShort;

 

 

 

long myLong_32: 32;

DDS_Short myShort_8 : 8;

 

 

 

};

DDS_Long myLong_32 : 32;

 

 

 

 

} BitfieldType;

 

 

 

 

 

 

 

struct

 

struct PrimitiveStruct {

typedef struct PrimitiveStruct

 

 

 

 

 

 

{

 

 

 

 

char char_member;

 

 

(see

Note

char char_member;

 

};

 

} PrimitiveStruct;

 

10 below)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

typedef struct PrimitiveUnion

 

union

 

union PrimitiveUnion switch (long){

{

 

 

 

 

case 1:

DDS_Long _d;

 

(see Note 3

short short_member;

struct {

 

default:

DDS_Short short_member;

 

and

Note

 

long long_member;

DDS_Long long_member;

 

10 below)

};

} _u;

 

 

 

 

} PrimitiveUnion;

 

 

 

 

 

typedef

typedef short TypedefShort;

typedef DDS_Short TypedefShort;

 

 

 

 

 

 

3-42

 

 

 

 

 

Creating User Data Types with IDL

Table 3.5 Specifying Data Types in IDL for C and C++

 

 

 

 

 

 

 

 

 

 

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

struct OneDArrayStruct {

typedef struct OneDArrayStruct

 

 

 

 

 

{

 

 

 

 

 

 

 

short short_array[2];

 

 

 

 

 

 

 

DDS_Short short_array[2];

 

 

 

array

of

};

 

 

 

} OneDArrayStruct;

 

 

 

 

above

 

struct TwoDArrayStruct {

 

 

 

 

 

 

types

 

typedef struct TwoDArrayStruct

 

 

 

 

short short_array[1][2];

 

 

 

 

 

{

 

 

 

 

 

 

 

};

 

 

 

 

 

 

 

DDS_Short short_array[1][2];

 

 

 

 

 

 

 

 

 

 

 

 

} TwoDArrayStruct;

 

 

 

 

 

 

 

 

 

 

 

 

bounded

 

typedef struct SequenceStruct

 

 

 

sequence of

 

 

 

 

 

{

 

 

 

 

 

above

 

 

 

 

 

 

 

 

struct SequenceStruct {

DDSShortSeq short_sequence;

 

 

 

types

 

sequence<short,4> short_sequence;

} SequenceStruct;

 

 

 

 

 

 

};

Note: Sequences of primitive types have been

 

(see

Note

 

 

 

predefined by Connext.

 

 

 

 

11 below)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

unbounded

 

typedef struct SequenceStruct

 

 

 

 

{

 

 

 

 

 

sequence of

 

 

 

 

 

 

 

DDSShortSeq short_sequence;

 

 

 

above

 

struct SequenceStruct {

} SequenceStruct;

 

 

 

 

types

 

sequence<short> short_sequence;

Note: rtiddsgen will supply a default bound.

 

 

 

};

 

(see

Note

 

You can specify that bound with the “-sequenc-

 

 

eSize”

command-line

option;

see

 

11 below)

 

 

 

Section 3.6.1.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

array

of

struct ArraysOfSequences{

typedef struct ArraysOfSequences

 

 

 

sequence<short,4>

{

 

 

 

 

 

sequences

sequences_array[2];

DDS_ShortSeq sequences_array[2];

 

 

 

 

 

};

} ArraysOfSequences;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

typedef DDS_Short ShortArray[2];

 

 

 

 

 

 

DDS_SEQUENCE_NO_GET(ShortArraySeq,

 

 

 

 

 

 

 

ShortArray);

 

 

 

sequence of

typedef short ShortArray[2];

typedef struct SequenceOfArrays

 

 

 

arrays

 

 

 

 

 

 

struct SequenceofArrays {

{

 

 

 

 

 

 

 

 

 

 

 

 

(see

Note

sequence<ShortArray,2>

ShortArraySeq arrays_sequence;

 

 

 

arrays_sequence;

} SequenceOfArrays;

 

 

 

 

11 below)

};

DDS_SEQUENCE_NO_GET is a Connext

 

 

 

 

 

 

 

 

macro that defines a new sequence type for a

 

 

 

 

user data type. In this case, the user data type is

 

 

 

 

ShortArray.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

typedef sequence<short,4>

typedef DDS_ShortSeq ShortSequence;

 

 

 

sequence of

 

 

 

 

 

 

sequences

ShortSequence;

DDS_SEQUENCE(ShortSequenceSeq,

 

 

 

 

 

 

 

 

 

struct SequencesOfSequences{

 

ShortSequence);

 

 

 

 

 

 

 

 

 

 

 

(see Note 4

sequence<ShortSequence,2>

typedef struct SequencesOfSequences{

 

 

 

sequences_sequence;

 

 

 

and

Note

ShortSequenceSeq

 

 

 

 

};

 

 

 

 

11 below)

sequences_sequence;

 

 

 

 

 

 

 

 

 

 

 

 

} SequencesOfSequences;

 

 

 

 

 

 

 

 

 

 

 

bounded

struct PrimitiveStruct {

typedef struct PrimitiveStruct {

 

 

 

char* string_member;

 

 

 

 

string<20> string_member;

 

 

 

 

string

 

 

/* maximum length = (20) */

 

 

};

 

 

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3-43

 

 

 

Creating User Data Types with IDL

Table 3.5 Specifying Data Types in IDL for C and C++

 

 

 

 

 

 

 

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

 

 

 

 

 

typedef struct PrimitiveStruct {

 

 

 

char* string_member;

 

unbounded

struct PrimitiveStruct {

/* maximum length = (255) */

 

string string_member;

} PrimitiveStruct;

 

string

};

Note: rtiddsgen will supply a default bound.

 

 

 

 

 

 

You can specify that bound with the -string-

 

 

 

Size command-line option, see Section 3.6.1.

 

 

 

 

 

 

 

typedef struct PrimitiveStruct {

 

bounded

struct PrimitiveStruct {

DDS_Wchar * wstring_member;

 

wstring<20> wstring_member;

/* maximum length = (20)

 

wstring

 

};

*/

 

 

 

 

 

 

 

} PrimitiveStruct;

 

 

 

 

 

 

 

typedef struct PrimitiveStruct {

 

 

struct PrimitiveStruct {

DDS_Wchar * wstring_member;

 

unbounded

/* maximum length = (255) */

 

wstring

wstring wstring_member;

 

};

 

 

 

 

} PrimitiveStruct;

 

 

 

 

 

 

Note: rtiddsgen will supply a default bound.

 

 

 

 

 

 

 

With the -namespace option (only available

 

 

 

for C++):

 

 

 

namespace PackageName{

 

 

module PackageName {

typedef struct Foo {

 

module

struct Foo {

DDS_Long field;

 

long field;

} Foo;

 

 

};

};

 

 

 

};

Without the -namespace option:

 

 

 

typedef struct PackageName_Foo {

 

 

 

DDS_Long field;

 

 

 

} PackageName_Foo;

 

 

 

 

 

3-44

 

 

 

 

Creating User Data Types with IDL

Table 3.5 Specifying Data Types in IDL for C and C++

 

 

 

 

 

 

 

 

 

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

 

 

 

 

 

 

 

C++:

class MyValueType {

 

 

 

 

public:

 

 

 

 

 

 

MyValueType2 * member;

 

 

 

 

};

 

 

 

 

 

 

class MyValueType {

 

 

 

 

public:

 

 

 

 

valuetype MyValueType {

 

MyValueType2

member;

 

 

 

};

 

 

 

 

public MyValueType2 * member;

 

 

 

 

 

 

 

 

 

 

 

};

 

class MyValueType : public MyBa-

 

 

 

 

 

valuetype

 

 

seValueType

 

 

 

valuetype MyValueType {

 

{

 

 

 

 

 

public:

 

 

 

 

public MyValueType2 member;

 

 

 

 

(see Note 9

 

MyValueType2 * member;

 

};

 

 

 

};

 

 

 

and Note

 

 

 

 

 

 

 

 

 

 

 

 

C:

 

 

 

 

10 below)

 

typedef struct MyValueType {

 

 

valuetype MyValueType: MyBaseValueType

 

MyValueType2 * member;

 

 

{

 

} MyValueType;

 

 

 

 

public MyValueType2 * member;

 

 

 

 

 

 

};

 

typedef struct MyValueType {

 

 

 

 

MyValueType2

member;

 

 

 

 

} MyValueType;

 

 

 

 

 

 

typedef struct MyValueType

 

 

 

 

{

 

 

 

 

 

 

MyBaseValueType parent;

 

 

 

 

MyValueType2 * member;

 

 

 

 

} MyValueType;

 

 

 

 

 

 

 

 

 

Table 3.6 Specifying Data Types in IDL for C++/CLI

 

 

 

 

 

 

 

 

 

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

 

 

 

char

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

(see Note 1

char char_member;

System::Char char_member;

 

below)

};

};

 

 

 

 

 

 

 

 

wchar

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

wchar wchar_member;

System::Char wchar_member;

 

 

};

};

 

 

 

 

 

 

 

 

 

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

octet

octet octet_member;

System::Byte octet_member;

 

 

};

};

 

 

 

 

 

 

 

 

short

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

short short_member;

System::Int16 short_member;

 

 

};

};

 

 

 

 

 

 

 

 

 

 

 

unsigned

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

unsigned short

 

System::UInt16 unsigned_short_member;

 

short

unsigned_short_member;

 

};

 

 

 

 

 

};

 

 

 

 

 

 

 

 

 

 

 

 

 

 

long

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

long long_member;

System::Int32 long_member;

 

 

};

};

 

 

 

 

 

 

 

 

unsigned

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

unsigned long unsigned_long_member;

System::UInt32 unsigned_long_member;

 

long

 

};

};

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3-45

 

 

 

 

Creating User Data Types with IDL

Table 3.6 Specifying Data Types in IDL for C++/CLI

 

 

 

 

 

 

 

IDL Type

Sample Entry in IDL File

Sample Output Generated by rtiddsgen

 

 

 

 

 

 

 

 

 

 

 

long long

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

long long long_long_member;

System::Int64 long_long_member;

 

 

 

};

};

 

 

 

 

 

 

 

unsigned

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

unsigned long long

System::UInt64

 

long long

unsigned_long_long_member;

unsigned_long_long_member;

 

 

 

};

};

 

 

 

 

 

 

 

float

 

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

 

float float_member;

System::Single float_member;

 

 

 

};

};

 

 

 

 

 

 

 

 

 

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

double

double double_member;

System::Double double_member;

 

 

 

};

} PrimitiveStruct;

 

 

 

 

 

 

 

long

dou-

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

ble

 

 

 

long double long_double_member;

DDS::LongDouble long_double_member;

 

(see Note 2

 

};

} PrimitiveStruct;

 

below)

 

 

 

 

 

 

 

struct PrimitiveStruct {

public ref class PrimitiveStruct {

 

boolean

boolean boolean_member;

System::Boolean boolean_member;

 

 

 

};

};

 

 

 

 

 

 

 

 

 

 

public enum class

 

 

 

enum PrimitiveEnum {

PrimitiveEnum : System::Int32 {

 

 

 

ENUM1,

ENUM1,

 

 

 

ENUM2,

ENUM2,

 

 

 

ENUM3

ENUM3

 

enum