RULES 8.3.4.1 (Message Receiver)
================================
* If the full Submessage header cannot be read, the rest of the Message is considered invalid.
* If submessageLength field is invalid, the rest of the Message is invalid.
* A Submessage with an unknown SubmessageId must be ignored and parsing must continue with the next Submessage.
* The receiver of a Submessage should ignore unknown flags. 
* A valid submessageLength field must always be used to find the next Submessage.
* A known but invalid Submessage invalidates the rest of the Message.

RULES 8.4.2
===========

GENERAL
-------
* All communications must take place using RTPS Messages
* All implementations must implement the RTPS Message Receiver
* The timing characteristics of all implementations must be tunable
* Implementations must implement the Simple Participant and Endpoint Discovery Protocols

WRITER
------
* Writers must not send data out-of-order
* Writers must include in-line QoS values if requested by a Reader
* Writers must send periodic HEARTBEAT Messages (reliable only)
* Writers must eventually respond to a negative acknowledgment (reliable only)
* Sending Heartbeats and Gaps with Writer Group Information (Writer belonging to a Group)

READER
------
A best-effort Reader is completely passive as it only receives data and does not send messages itself. 
Therefore, the requirements below only apply to reliable Readers.
* Readers must respond eventually after receiving a HEARTBEAT with final flag not set
* Readers must respond eventually after receiving a HEARTBEAT that indicates a sample is missing
* Once acknowledged, always acknowledged
* Readers can only send an ACKNACK Message in response to a HEARTBEAT Message

RELIABILITY
===========
* Best Effort Writer can only be matched with Best Effort Reader
* Stateless Reader can only be Best Effort (maintains absolutely no state, does not handle duplicate and out-of-order changes)

STATELESS WRITER
================
Note that the processing of this message uses the reply locators in the RTPS Receiver. 
This is the only source of information for the StatelessWriter to determine where to send the reply to. 
Proper functioning of the protocol requires that the RTPS Reader inserts an InfoReply Submessage ahead of the AckNack such that these fields are properly set.

Writer Liveness Protocol
========================
ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER
ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER

OPTIONAL 8.4.14
===============
Optional features may not be supported by all RTPS implementations.

* LARGE DATA (Fragmented Data)

--------------------------------------------

ENTITYID_UKNOWN also for Built-In?
Ignore Participant/Topic/Publication/Subscription (handle argument of Sampleinfo)



ENDIANNESS
==========
You have to see what datatypes PSM maps to each element. 
If the datatype is bigger than a byte, byte swaping has to occur.
The elements of an array are in order (but the elements themselves may need to be swapped if bigger than a Byte)

ENDPOINT FIFO PACKET FORMAT
===========================

31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------+---------------+---------------+---------------+
|   OPCODE    |     FLAGS     |         SRC_UDP_PORT          |
+-------------+---------------+---------------+---------------+
|                       SRC_IPv4_ADDR                         |
+-------------------------------------------------------------+
|                        SRC_ENTITYID                         |
+-------------------------------------------------------------+
|                                                             |
+                                                             +
|                       SRC_GUIDPREFIX                        |
+                                                             +
|                                                             |
+-------------------------------------------------------------+
|     DEST_ENTITYID [only for Builtin Destinations]           |
+-------------------------------------------------------------+
|                                                             |
+         Sequence Number [only for DATA Submessage]          +
|                                                             |
+-------------------------------------------------------------+
|                                                             |
+                          Timestamp                          +
|      [only for DATA Submessage and User Destinations]       |
+-------------------------------------------------------------+
|                                                             |
~                PAYLOAD (SUBMESSAGE CONTENT)                 ~
|                                                             |
+-------------------------------------------------------------+

HEARTBEAT PAYLOAD
-----------------
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
|                                                             |
+                          FirstSN                            +
|                                                             |
+-------------------------------------------------------------+
|                                                             |
+                           LastSN                            +
|                                                             |
+-------------------------------------------------------------+
|                            Count                            |
+-------------------------------------------------------------+

ACKNACK PAYLOAD
---------------
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
|                                                             |
+                     ReaderSNState.BASE                      +
|                                                             |
+-------------------------------------------------------------+
|                    ReaderSNState.NumBits                    |
+-------------------------------------------------------------+
|                    [ReaderSNState.Bitmap] x 0-8             |
+-------------------------------------------------------------+
|                            Count                            |
+-------------------------------------------------------------+

GAP PAYLOAD
-----------
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
|                                                             |
+                          GapStart                            +
|                                                             |
+-------------------------------------------------------------+
|                                                             |
+                        GapList.BASE                         +
|                                                             |
+-------------------------------------------------------------+
|                       GapList.NumBits                       |
+-------------------------------------------------------------+
|                     [GapList.Bitmap] x 0-8                  |
+-------------------------------------------------------------+
|                           UNUSED                            |
+-------------------------------------------------------------+

ENDPOINT_ID
===========

0...MAX_ENDPOINTS
READERS...WRITERS

BUILT-IN ENDPOINTS
==================

2.2.5 Built-In Topics
The QoS of the built-in Subscriber and DataReader objects is given by the following table:
HISTORY:    kind = KEEP_LAST, depth = 1

Since the Built-In Endpoints have a history depth of 1, we can safely reduce the processing complexity of ACKNACK and 
HEARTBEAT messages (and even ignore GAP messages).

PARTICICPANT DATA
=================
  31............24..............16..............8...............0
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  +-------------------------------------------------------------+
00|                                                             |
  +                                                             +
01|                          GUIDPREFIX                         |
  +                                                             +
02|                                                             |
  +-------------------------------------------------------------+
03|                      META_IPv4_ADDRESS                      |
  +-------------------------------------------------------------+
04|                    DEFAULT_IPv4_ADDRESS                     |
  +-------------------------------------------------------------+
05|       META_UDP_PORT         |        DEFAULT_UDP_PORT       |
  +-------------------------------------------------------------+
06|                                                             |
  +                         SPDP_SEQ_NR                         +
07|                                                             |
  +-------------------------------------------------------------+
08|                                                             |
  +                       LEASE_DURATION                        +
09|                                                             |
  +-------------------------------------------------------------+
10|                                                             |
  +                       LEASE_DEADLINE                        +
11|                                                             |
  +-------------------------------------------------------------+
12|                           UNUSED                    |P|S|M|Q|
  +-------------------------------------------------------------+
13|                                                             |
  +                       ACKNACK_RES_TIME                      +
14|                                                             |
  +-------------------------------------------------------------+
15|                                                             |
  +                     HEARTBEAT_RES_TIME                      +
16|                                                             |
  +-------------------------------------------------------------+
17|                                                             |
  +                     PUBLICATION_SEQ_NR                      +
18|                                                             |
  +-------------------------------------------------------------+
19|                                                             |
  +                    SUBSCRIPTION_SEQ_NR                      +
20|                                                             |
  +-------------------------------------------------------------+
21|                                                             |
  +                       MESSAGE_SEQ_NR                        +
22|                                                             |
  +-------------------------------------------------------------+

ENDPOINT DATA
=============
  31............24..............16..............8...............0
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  +-------------------------------------------------------------+
00|                          ENTITYID                           |
  +-------------------------------------------------------------+
01|                                                             |
  +                                                             +
02|                          GUIDPREFIX                         |
  +                                                             +
03|                                                             |
  +-------------------------------------------------------------+

ENDPOINT MATCH FRAME
====================
  31............24..............16..............8...............0
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  +-------------------------------------------------------------+
00|                           OPCODE                            |
  +-------------------------------------------------------------+
01|                                                             |
  +                                                             +
02|                         GUIDPREFIX                          |
  +                                                             +
03|                                                             |
  +-------------------------------------------------------------+
04|                          ENTITYID                           |
  +-------------------------------------------------------------+
05|                        IPv4_ADDRESS                         |
  +-------------------------------------------------------------+
06|         UDP_PORT            |            UNUSED           |Q|
  +-------------------------------------------------------------+

ENDPOINT UNMATCH FRAME
======================
  31............24..............16..............8...............0
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  +-------------------------------------------------------------+
00|                           OPCODE                            |
  +-------------------------------------------------------------+
01|                                                             |
  +                                                             +
02|                         GUIDPREFIX                          |
  +                                                             +
03|                                                             |
  +-------------------------------------------------------------+
04|                          ENTITYID                           |
  +-------------------------------------------------------------+

ENDPOINT LIVELINESS UPDATE
==========================
  31............24..............16..............8...............0
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  +-------------------------------------------------------------+
00|                           OPCODE                            |
  +-------------------------------------------------------------+
01|                                                             |
  +                                                             +
02|                         GUIDPREFIX                          |
  +                                                             +
03|                                                             |
  +-------------------------------------------------------------+

LOCAL ENDPOINT BUFFER
=====================
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
|                                                             |
+                                                             +
|                          GUIDPREFIX                         |
+                                                             +
|                                                             |
+-------------------------------------------------------------+
|                          ENTITYID                           |
+-------------------------------------------------------------+
|                        IPv4_ADDRESS                         |
+-------------------------------------------------------------+
|         UDP_PORT            |          EXTRA_FLAGS          |
+-------------------------------------------------------------+
|                          LIFESPAN                           |
+                                                             +
|                       (READER_ONLY)                         |
+-------------------------------------------------------------+

OUTPUT DATA
===========
  31............24..............16..............8...............0
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01|                       SRC_IPv4_ADDRESS                      |
  +-------------------------------------------------------------+
02|                       DEST_IPv4_ADDRESS                     |
  +-------------------------------------------------------------+
03|        SRC_UDP_PORT         |         DEST_UDP_PORT         |
  +-------------------------------------------------------------+
04|                                                             |
  ~                        RTPS_MESSAGE                         ~
  |                                                             |
  +-------------------------------------------------------------+


TOPIC KEYS
==========
Nominally the key is part of the serialized data of a data submessage.
Using the key hash benefits implementations by providing a faster alternative than deserializing the full key from the received data-object.

MISC
====

8.2.9 Relation to DDS Entities
How exactly a DDS Entity interacts with the HistoryCache however, is implementation specific and not
formally modeled by the RTPS protocol. Instead, the Behavior Module of the RTPS protocol only specifies how
CacheChange changes are transferred from the HistoryCache of the RTPS Writer to the HistoryCache of
each matching RTPS Reader.

8.2.9.1
When using strict reliable communication, a change can
only be removed when it has been acknowledged by all readers the change was sent to and which are still
active and alive.

8.2.9.2
Each matching Writer will attempt to transfer all relevant samples from its HistoryCache to the HistoryCache of the Reader.

8.4.3
It is also not able to drop out-of-order samples on the Reader side as this
requires keeping track of the largest sequence number received from each remote Writer.
--> Suggests there is multiple writers

8.5.4.2
For the purpose of interoperability, it is sufficient that an
implementation provides the required built-in Endpoints and reliable communication that satisfies the general
requirements listed in 8.4.2.

8.5.4.4
An implementation of the protocol need not necessarily send all information contained in the DataTypes. If any
information is not present, the implementation can assume the default values, as defined by the PSM. 

8.7.2.2.6
In order to implement the DDS_BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS policy,
implementations must include an InfoTimestamp Submessage with every update from a Writer.

9.4.2.11
The ParameterList may contain multiple Parameters with the same value for the parameterId. 
This is used to provide a collection of values for that kind of Parameter.

DDS_Advanced_Tutorial_2006_00-T1-2_Pardo.pdf (P.16)

INVALIDATION
============

RTPS HEADER (8.3.6.3)
-----------
* The Message has less than the required number of octets to contain a full Header
* Its protocol value does not match the value of PROTOCOL_RTPS
* The major protocol version is larger than the major protocol version supported by the implementation

ACKNACK (8.3.7.1.3)
-------
* submessageLength in the Submessage header is too small
* readerSNState is invalid

DATA (8.3.7.2.3)
----
* submessageLength in the Submessage header is too small
* writerSN.value is not strictly positive (1, 2, ...) or is SEQUENCENUMBER_UNKNOWN
* inlineQos is invalid

DATA FRAG (8.3.7.3.3)
---------
* submessageLength in the Submessage header is too small
* writerSN.value is not strictly positive (1, 2, ...) or is SEQUENCENUMBER_UNKNOWN
* fragmentStartingNum.value is not strictly positive (1, 2, ...) or exceeds the total number of fragments
* fragmentSize exceeds dataSize
* The size of serializedData exceeds (fragmentsInSubmessage * fragmentSize)
* inlineQos is invalid

GAP (8.3.7.4.3)
---
* submessageLength in the Submessage header is too small
* gapStart is zero or negative
* gapList is invalid
* (If GroupInfoFlag is set) gapStartGSN.value is zero or negative
* (If GroupInfoFlag is set) gapEndGSN.value is zero or negative
* (If GroupInfoFlag is set) gapEndGSN.value < gapStartGSN.value-1

HEARTBEAT (8.3.7.5.3)
---------
* submessageLength in the Submessage header is too small
* firstSN.value is zero or negative
* lastSN.value is negative
* lastSN.value < firstSN.value - 1
* (If GroupInfoFlag is set) currentGSN.value is zero or negative
* (If GroupInfoFlag is set) firstGSN.value is zero or negative
* (If GroupInfoFlag is set) lastGSN.value is negative
* (If GroupInfoFlag is set) lastGSN.value < firstGSN.value - 1
* (If GroupInfoFlag is set) currentGSN.value < firstGSN.value
* (If GroupInfoFlag is set) currentGSN.value < lastGSN.value

HEARTBEAT FRAG (8.3.7.6.3)
--------------
* submessageLength in the Submessage header is too small
* writerSN.value is zero or negative
* lastFragmentNum.value is zero or negative

INFO DESTINATION (8.3.7.7.3)
----------------
* submessageLength in the Submessage header is too small

INFO REPLY (8.3.7.8.3)
----------
* submessageLength in the Submessage header is too small

INFO SOURCE (8.3.7.9.3)
-----------
* submessageLength in the Submessage header is too small

INFO TIMESTAMP (8.3.7.10.3)
--------------
* submessageLength in the Submessage header is too small

NACK FRAG (8.3.7.11.3)
---------
* submessageLength in the Submessage header is too small
* writerSN.value is zero or negative
* fragmentNumberState is invalid

PAD (8.3.7.12.3)
---
ALWAYS VALID

NumberSet (9.4.2.6)
---------
* bitmapBase <= 0
* numBits < 0 or numBits > 256
* M/=(numBits+31)/32 longs in Submessage

Parameter List (8.3.5.9)
--------------
* There shall be no more than 2^16 possible values of the ParameterId_t parameterId
* A range of 2^15 values is reserved for protocol-defined parameters
* A range of 2^15 values is reserved for vendor-defined parameters
* The maximum length of any parameter is limited to 2^16 octets