VR-Link JAVA API Documentation
 All Classes Namespaces Files Functions Variables Enumerator Pages
8.2 - Working with Non-Standard PDUs

Table of Contents

Many VR-Link users need to use PDUs that are not part of the DIS standard, and thus not implemented in VR-Link.

However, VR-Link can work with user-defined PDUs just like it treats PDUs that are implemented in VR-Link.

There are two ways to work with user-defined PDUs:

Using DtUnknownPdu is sometimes easier for simple PDUs that can be represented by C-style structures. In essence, the DtUnknownPdu just serves as a wrapper around such a structure. Deriving your own DtPdu class requires some extra work up front, but it is easier to use in your application, especially if it is a variable-length PDU, or one that has several variants.

8.2.1 Using DtUnknownPdu

You can use a DtUnknownPdu (defined in unknownPdu.h) to represent a PDU for which there is no PDU class. This includes new or experimental PDUs that you develop.

To send a PDU using the DtUnknownPdu class:

  1. Fill a buffer with the exact bytes you want to send on the network (probably by filling in a C-structure). Make sure this structure includes the DIS PDU header whose structure is defined in pduHeader.h (in ./include/packets).

    By using our "Net" types, such as DtNetInt32 (defined in vlNetTypes.h), you insure platform independence. When you are on little endian machines, byte swapping is performed when assigning to a Net type, and when a Net type is implicitly cast to a native type.

    Note
    When VR-Link sets the network byte order of data, it tries to use operating system calls to byte-swap. On some operating systems, these calls may be atomic processor instructions or NO-OPs.
  2. Pass this network representation to the DtUnknownPdu from-network-representation constructor.
  3. Send the PDU using DtExerciseConn::sendStamped().

For example, suppose you create a Test PDU with two fields called a and b, and choose PDU kind number 220 to represent this PDU:

// Define the structure of your network representation
typedef struct NetTestPdu
{
DtNetPduHeader header;
DtNetInt32 a;
DtNetInt32 b;
} NetTestPdu;
// Create an instance of the structure and fill in the net
// representation
NetTestPdu aNetPdu;
aNetPdu.header.version = 5;
aNetPdu.header.DtExercise = 1;
aNetPdu.header.DtLength = sizeof(NetTestPdu);
aNetPdu.header.DtKind = 220
...
aNetPdu.a = 10;
aNetPdu.b = 11;
// Create a DtUnknownPdu from this network representation
DtUnknownPdu pdu((DtNetPduHeader*) &aNetPdu);
// Send the PDU as you normally would
exConn.sendStamped(pdu);

On the receiving side, DtUnknownPdu does not have addCallback() or removeCallback() functions, since a DtUnknownPdu does not know what PDU kind you are interested in. But you can still register callbacks with the DtExerciseConn on a particular PDU kind, in our case 220. Note the cast of the integer 220 to a DtPduKind enum here.

exConn.addPduCallback(DtPduKind(220), testCallback, NULL);

Since 220 is not a PDU kind that VR-Link knows about, when it receives a packet of that kind, it creates a DtUnknownPdu and passes that to your callback function. You can cast the DtPdu* to a DtUnknownPdu* within your callback if you want to, but it is not necessary, since the only useful thing you can do with a DtUnknownPdu is get its network representation, which is done through a DtPdu member function.

void testCallback(DtPdu* pdu, void *usr)
{
// Get the PDU's network representation, and cast it to a
// NetTestPdu structure, so that you can access the data
NetTestPdu* aNetPdu = pdu->packet();
int a = aNetPdu->a;
int b = aNetPdu->b;
}

8.2.2 Deriving Classes from DtPdu

VR-Link's DtExerciseConn::send() and DtExerciseConn::sendStamped() functions can send any type of PDU, as long as the object passed to it is of a type derived from DtPdu. So, to send user-defined PDUs, you can write a derived class, after which you can immediately use your derived class with these functions.

When DtExerciseConn receives a packet from the network, it creates an object of the appropriate class derived from DtPdu, based on the PDU type in the packet. For instance, a DtEntityStatePdu is created if a packet representing an Entity State PDU is received. For this reason, VR-Link needs to know that your derived class exists. Registration of your class with VR-Link is usually done in your PDU class's addCallback() function.

The testPdu example creates a variable length PDU. The TestPdu class represents a hypothetical variable-length "Test PDU" – one that has three fields: an integer named "a", a variable-length array of integers named "b" whose cardinality is the value of "a", and a float called c. The code for this example is in ./examples/extend/testPdu. The class documentation contains a complete description of the example.

[<< Working with PDUs] [Home] [Top of Page] [Configuring Your Connection to the DIS Network >>]


Document ID: Generated on Tue Aug 10 00:12:31 EDT 2021 from SVN revision 232765
Copyright © 2005-2021 MAK Technologies. All Rights Reserved (www.mak.com)