目录
- Messages Module
- Type定义
- RTPS消息结构
- RTPS消息头
- 子消息结构
- RTPS消息接收者
- SubmessageElements
- RTPS Header
- RTPS Submessages
Messages Module
RTPS Writer和RTPS Reader之间的交换数据的消息。
Type定义
Type | Purpose |
---|---|
ProtocolId_t | |
SubmessageFlag | sub msg flag |
SubmessageKind | 枚举值用于标识是什么类型的sub msg,有这些:DATA, GAP, HEARTBEAT, ACKNACK, PAD, INFO_TS, INFO_REPLY, INFO_DST, INFO_SRC, DATA_FRAG, NACK_FRAG, HEARTBEAT_FRAG |
Time_t | 时间戳,至少到ns,TIME_ZERO,TIME_INVALID TIME_INFINITE |
Count_t | 保存递增的计数,用于识别重复消息 |
ParameterId_t | 用于在参数列表中唯一标识参数的类型。主要在Discovery中广泛使用,主要用于定义QoS参数。一些被保留用于协议定义的参数,另一些可以用于供应商定义的参数。 |
FragmentNumber_t | 用于保存帧序号? |
GroupDigest_t | 用于保存唯一标识属于同一参与者的一组实体的摘要值的类型。 |
RTPS消息结构
RTPS协议发送的每一条消息都有一个固定的长度。这个长度不是由RTPS协议明确发送的,而是作为传输底层的一部分,RTPS消息是通过这种方式发送的。在面向数据包的传输(例如UDP/IP)的情况下,消息的长度已经由传输头部提供。面向流的传输(例如TCP)则需要在消息前面插入长度,以便识别RTPS消息的边界
RTPS消息头
消息头标识这条消息属于RTPS协议,标识了协议版本和供应商,具体包含以下内容:
字段 | 类型 | 含义 | 抓包中对应的字段 |
---|---|---|---|
protocol | ProtocolId_t | 表示这个rtps消息 | Magic: RTPS |
version | ProtocolVersion_t | 标识rtps协议的版本号 | Protocol version: 2.2 |
vendorId | VendorId_t | RTPS协议实现的供应商标识 | vendorID: 01.15(eProsima - Fast-RTPS) |
guidPrefix | GuidPrefix_t | GUIDs中使用的默认的prefix?TODO要确认 |
- guidPrefix定义了一个默认前缀,可以用来重构消息中包含的子消息的全局唯一标识符(GUIDs)。guidPrefix允许子消息只包含GUID的EntityId部分,因此可以避免在每个GUID上重复相同的前缀,从而节省空间。
子消息结构
每个RTPS消息都是由一个或多个子消息组成。
所有的子消息都是由 一个SubmessageHeader+0个或多个消息元素 组成。子消息头部用于标识子消息的种类和该子消息内的可选元素。
子消息头结构:
字段 | 类型 | 含义 |
---|---|---|
submessageId | SubmessageKind | 标识了Submessage.的消息类型,消息类型在下面列出 |
flags | SubmessageFlag[8] | 标识用于编码子消息的字节顺序,子消息中的可选元素的存在,并可能修改子消息的解释。有8个可能的标志。第一个标志(索引0)标识用于编码子消息的字节顺序。其余的标志会根据子消息的种类有不同的解释,并分别为每个子消息进行描述。 |
submessageLength | ushort | 表示子消息的长度。由于RTPS消息由子消息的连结组成,所以子消息的长度可用于跳转到下一个子消息。 |
RTPS消息接收者
一个消息中的子消息的解释和含义可能取决于该消息中之前的子消息。因此,消息的接收者必须维护同一消息中先前反序列化的子消息的状态。这种状态被建模为每次处理新消息时复位的RTPS接收器的状态,并为每个子消息的解释提供上下文。
对每一条新的message,Receiver的状态被重置和初始化
name | 初始值 |
---|---|
sourceVersion | PROTOCOLVERSION |
sourceVendorId | VENDORID_UNKNOWN |
sourceGuidPrefix | GUIDPREFIX_UNKNOWN |
destGuidPrefix | |
UnicastReplyLocatorList | |
multicastReplyLocatorList | |
haveTimestamp | False |
timestamp | TIME_INVALID |
messageLength |
Message Receiver必须遵守以下规则:
- 如果Submessage的消息头不能被读取,则其他消息体无效
- submessageLength为下一个Submessage的起始位置,或指示子消息扩展到消息的结束。如果这个字段是无效的,那么这条消息无效。
- 具有未知SubmessageId的子消息必须被忽略,并且必须要解析继续下一个子消息。也就是说,不在SubmessageKind范围内的消息id必须要被忽略。未知vendorId的供应商的SubmessageIds也必须被忽略,并且必须解析继续到下一个子消息。
- Submessage的接收者应忽略位置的flag
- 一个有效的submessageLength字段必须要被用于发小下一条Submessage, 即使Submessage有明确的id
- 一个已知但无效的子消息会使消息的其余部分失效。
子消息何时被视为无效:
- 它可以改变接收者的状态;这个状态影响了消息中后续子消息的解释方式。8.3.7节讨论了每个子消息如何改变状态。在此协议版本中,只有标题和子消息InfoSource,InfoReply,InfoDestination和InfoTimestamp改变了接收者的状态。
- 它可以影响目标Endpoint的行为,这适用于基本的RTPS消息:Data,DataFrag,HeartBeat,AckNack,Gap, HeartbeatFrag, NackFrag.
SubmessageElements
每个RTPS消息包含可变数量的RTPS子消息。每个RTPS子消息反过来又是由一组预定义的原子构建块构成,这些构建块被称为子消息元素。RTPS 2.4定义了以下子消息元素:GuidPrefix, EntityId, SequenceNumber, SequenceNumberSet, FragmentNumber, FragmentNumberSet, VendorId, ProtocolVersion, LocatorList, Timestamp, Count, SerializedData, ParameterList和GroupDigest。
- GuidPrefix和EntityId
- VendorId
- ProtocolVersion
- SequenceNumber
- SequenceNumberSet
- FragmentNumber
- FragmentNumberSet
- Timestamp
- ParameterList
- Count
- LocatorList
- SerializedData
- SerializedDataFragment
- GroupDigest
RTPS Header
每一条 RTPS Message必须以一个 Header开头.