libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::Topic::Server Class Reference

将字节流解析成 packet 并发布到已注册 topic 的状态机 / State machine that parses byte streams into packets and publishes them into registered topics More...

#include <server.hpp>

Collaboration diagram for LibXR::Topic::Server:
[legend]

Public Types

enum class  Status : uint8_t { WAIT_START , WAIT_TOPIC , WAIT_DATA_CRC }
 parser 当前所在阶段 / Current stage of the parser More...
 

Public Member Functions

 Server (size_t buffer_length)
 构造 parser 并分配内部暂存队列 / Construct the parser and allocate its internal staging queue
 
void Register (TopicHandle topic)
 注册一个可接收 packet 的 topic / Register one topic that may receive parsed packets
 
size_t ParseData (ConstRawData data)
 在普通上下文里喂入一批新字节 / Feed one new byte batch in normal context
 
size_t ParseDataFromCallback (ConstRawData data, bool in_isr)
 在回调/ISR 路径里喂入一批新字节 / Feed one new byte batch in callback/ISR path
 

Private Types

enum class  ParseResult : uint8_t { NEED_MORE , DROPPED , DELIVERED }
 一次 payload 阶段处理结果 / Result of one payload-stage handling step More...
 

Private Member Functions

size_t ParseDataRaw (ConstRawData data, bool from_callback, bool in_isr)
 ParseData*() 的共享实现 / Shared implementation behind ParseData*()
 
bool SyncToPacketStart ()
 把输入流同步到下一条 packet 起点 / Synchronize the input stream to the next packet start
 
bool ReadHeader ()
 在已对齐前缀后继续读取并校验完整头部 / Read and validate the full header after the prefix is aligned
 
ParseResult ReadPayload (bool from_callback, bool in_isr)
 读取当前包的 payload 和尾 CRC,并在成功时发布 / Read the payload and trailing CRC of the current packet and publish it on success
 
void ResetParser ()
 清空当前包的解析上下文并回到找起点状态 / Clear the current packet parsing context and return to the start-search state
 

Private Attributes

Status status_ = Status::WAIT_START
 当前 parser 阶段。Current parser stage.
 
uint32_t data_len_
 当前包头声明的 payload 长度。Payload length declared by the current header.
 
RBTree< uint32_t > topic_map_
 
QueueBase queue_
 输入字节 FIFO。Input byte FIFO.
 
RawData parse_buff_
 
TopicHandle current_topic_
 当前包命中的目标 topic。Target topic matched by the current packet.
 
MicrosecondTimestamp current_timestamp_
 

Detailed Description

将字节流解析成 packet 并发布到已注册 topic 的状态机 / State machine that parses byte streams into packets and publishes them into registered topics

把字节流解析成 packet 并投递到 topic 的 parser / Parser that turns byte streams into packets and delivers them into topics

Note
当前 Server 自己不维护 raw topic/cache 语义;它只依赖注册 topic 的: payload_sizepayload_alignment 和名字 CRC 键。 The current Server does not restore old raw topic/cache semantics by itself; it relies only on each registered topic's payload_size, payload_alignment, and name CRC key.
当前兼容规则: 收到的 packet payload 短于 topic 固定大小时,仅保证前缀部分有效,后半段保持未定义; 长于 topic 固定大小时,仅保留前缀部分,其余字节直接截断。 Current compatibility rule: when an incoming packet payload is shorter than the topic's fixed size, only the leading prefix is guaranteed valid and the remaining tail stays unspecified; when it is longer, only the prefix matching the topic size is kept and the rest is truncated.

Definition at line 26 of file server.hpp.

Member Enumeration Documentation

◆ ParseResult

enum class LibXR::Topic::Server::ParseResult : uint8_t
strongprivate

一次 payload 阶段处理结果 / Result of one payload-stage handling step

Enumerator
NEED_MORE 

当前包还没收全。Current packet is still incomplete.

DROPPED 

当前包被丢弃。Current packet is dropped.

DELIVERED 

当前包已发布。Current packet is delivered.

Definition at line 87 of file server.hpp.

88 {
89 NEED_MORE,
90 DROPPED,
92 };
@ DROPPED
当前包被丢弃。Current packet is dropped.
@ NEED_MORE
当前包还没收全。Current packet is still incomplete.
@ DELIVERED
当前包已发布。Current packet is delivered.

◆ Status

enum class LibXR::Topic::Server::Status : uint8_t
strong

parser 当前所在阶段 / Current stage of the parser

Enumerator
WAIT_START 

正在找下一包前缀。Searching for the next packet prefix.

WAIT_TOPIC 

已读到前缀,正在等完整头。Prefix received; waiting for the full header.

WAIT_DATA_CRC 

头已接受,正在等 payload 和尾 CRC。Header accepted; waiting for payload plus trailing CRC.

Definition at line 33 of file server.hpp.

34 {
40 };
@ WAIT_START
正在找下一包前缀。Searching for the next packet prefix.

Constructor & Destructor Documentation

◆ Server()

Topic::Server::Server ( size_t buffer_length)

构造 parser 并分配内部暂存队列 / Construct the parser and allocate its internal staging queue

Parameters
buffer_length内部字节队列和暂存缓冲区大小 / Size of the internal byte queue and staging buffer

Definition at line 12 of file server.cpp.

13 : topic_map_([](const uint32_t& a, const uint32_t& b) { return (a > b) - (a < b); }),
14 queue_(1, buffer_length)
15{
16 ASSERT(buffer_length > PACK_BASE_SIZE);
17 parse_buff_.size_ = buffer_length;
19 new (std::align_val_t(LibXR::CACHE_LINE_SIZE)) uint8_t[parse_buff_.size_];
20}
size_t size_
数据字节数 / Data size in bytes
void * addr_
数据起始地址 / Data start address
RBTree< uint32_t > topic_map_
Definition server.hpp:139
QueueBase queue_
输入字节 FIFO。Input byte FIFO.
Definition server.hpp:141
constexpr size_t CACHE_LINE_SIZE
兼容旧代码的缓存行别名 / Backward-compatible cache-line alias for existing code
Definition libxr_def.hpp:66

Member Function Documentation

◆ ParseData()

size_t Topic::Server::ParseData ( ConstRawData data)

在普通上下文里喂入一批新字节 / Feed one new byte batch in normal context

Parameters
data新收到的原始字节 / Newly received raw bytes
Returns
成功解析并发布的包数量 / Number of packets parsed and published

Definition at line 35 of file server.cpp.

36{
37 return ParseDataRaw(data, false, false);
38}
size_t ParseDataRaw(ConstRawData data, bool from_callback, bool in_isr)
ParseData*() 的共享实现 / Shared implementation behind ParseData*()
Definition server.cpp:45

◆ ParseDataFromCallback()

size_t Topic::Server::ParseDataFromCallback ( ConstRawData data,
bool in_isr )

在回调/ISR 路径里喂入一批新字节 / Feed one new byte batch in callback/ISR path

Parameters
data新收到的原始字节 / Newly received raw bytes
in_isr当前是否位于 ISR / Whether the current path is in ISR context
Returns
成功解析并发布的包数量 / Number of packets parsed and published

Definition at line 40 of file server.cpp.

41{
42 return ParseDataRaw(data, true, in_isr);
43}

◆ ParseDataRaw()

size_t Topic::Server::ParseDataRaw ( ConstRawData data,
bool from_callback,
bool in_isr )
private

ParseData*() 的共享实现 / Shared implementation behind ParseData*()

Parameters
data新收到的原始字节 / Newly received raw bytes
from_callback是否来自回调路径 / Whether the current parse comes from callback path
in_isr当前是否位于 ISR / Whether the current path is in ISR context
Returns
成功解析并发布的包数量 / Number of packets parsed and published

Definition at line 45 of file server.cpp.

46{
47 size_t count = 0;
48
49 (void)queue_.PushBatchBytes(data.addr_, data.size_);
50
51 while (true)
52 {
54 {
55 return count;
56 }
57
59 {
60 return count;
61 }
62
64 {
65 switch (ReadPayload(from_callback, in_isr))
66 {
68 return count;
70 continue;
72 count++;
73 continue;
74 }
75 }
76 }
77}
size_t size_
数据字节数 / Data size in bytes
const void * addr_
数据起始地址 / Data start address
ErrorCode PushBatchBytes(const void *data, size_t size)
按字节批量入队多个元素。
bool ReadHeader()
在已对齐前缀后继续读取并校验完整头部 / Read and validate the full header after the prefix is aligned
Definition server.cpp:97
bool SyncToPacketStart()
把输入流同步到下一条 packet 起点 / Synchronize the input stream to the next packet start
Definition server.cpp:79
Status status_
当前 parser 阶段。Current parser stage.
Definition server.hpp:136
ParseResult ReadPayload(bool from_callback, bool in_isr)
读取当前包的 payload 和尾 CRC,并在成功时发布 / Read the payload and trailing CRC of the current packet and publish i...
Definition server.cpp:146

◆ ReadHeader()

bool Topic::Server::ReadHeader ( )
private

在已对齐前缀后继续读取并校验完整头部 / Read and validate the full header after the prefix is aligned

Returns
头部有效返回 true,否则返回 false / Returns true when the header is valid, otherwise false

Definition at line 97 of file server.cpp.

98{
99 if (queue_.Size() < sizeof(PackedDataHeader))
100 {
101 return false;
102 }
103
104 queue_.PopBatchBytes(parse_buff_.addr_, sizeof(PackedDataHeader));
105 if (!CRC8::Verify(parse_buff_.addr_, sizeof(PackedDataHeader)))
106 {
107 ResetParser();
108 return true;
109 }
110
111 auto* header = reinterpret_cast<PackedDataHeader*>(parse_buff_.addr_);
112 if (header->version != PACKET_VERSION)
113 {
114 ResetParser();
115 return true;
116 }
117
118 auto* node = topic_map_.Search<TopicHandle>(header->topic_name_crc32);
119 if (node == nullptr)
120 {
121 ResetParser();
122 return true;
123 }
124
125 data_len_ = header->GetDataLen();
126 current_timestamp_ = header->GetTimestamp();
127 current_topic_ = *node;
128 const auto target_size = current_topic_->data_.payload_size;
129
130 if (target_size + PACK_BASE_SIZE > parse_buff_.size_)
131 {
132 ResetParser();
133 return true;
134 }
135
136 if (data_len_ + PACK_BASE_SIZE > queue_.length_)
137 {
138 ResetParser();
139 return true;
140 }
141
143 return true;
144}
static bool Verify(const void *raw, size_t len)
验证数据的 CRC8 校验码 / Verifies the CRC8 checksum of the given data
Definition crc.hpp:78
ErrorCode PopBatchBytes(void *data, size_t size)
按字节批量出队多个元素。
size_t Size() const
获取当前已存储元素个数。
size_t length_
队列最大容量。 Maximum queue capacity.
Data data_
存储的数据 (Stored data).
Definition rbt.hpp:98
Node< Data > * Search(const Key &key)
搜索红黑树中的节点 (Search for a node in the Red-Black Tree).
Definition rbt.hpp:120
void ResetParser()
清空当前包的解析上下文并回到找起点状态 / Clear the current packet parsing context and return to the start-search state
Definition server.cpp:196
TopicHandle current_topic_
当前包命中的目标 topic。Target topic matched by the current packet.
Definition server.hpp:144
MicrosecondTimestamp current_timestamp_
Definition server.hpp:146
uint32_t data_len_
当前包头声明的 payload 长度。Payload length declared by the current header.
Definition server.hpp:137
RBTree< uint32_t >::Node< Block > * TopicHandle
指向一个 topic 运行时状态块的句柄 / Handle pointing to one topic runtime state block
Definition topic.hpp:125

◆ ReadPayload()

Topic::Server::ParseResult Topic::Server::ReadPayload ( bool from_callback,
bool in_isr )
private

读取当前包的 payload 和尾 CRC,并在成功时发布 / Read the payload and trailing CRC of the current packet and publish it on success

Parameters
from_callback是否来自回调路径 / Whether the current parse comes from callback path
in_isr当前是否位于 ISR / Whether the current path is in ISR context
Returns
当前 payload 阶段的处理结果 / Result of the current payload stage

Definition at line 146 of file server.cpp.

147{
148 if (queue_.Size() < data_len_ + sizeof(uint8_t))
149 {
151 }
152
153 auto* payload_addr =
154 reinterpret_cast<uint8_t*>(parse_buff_.addr_) + sizeof(PackedDataHeader);
155 queue_.PopBatchBytes(payload_addr, data_len_ + sizeof(uint8_t));
156
158 data_len_ + sizeof(PackedDataHeader) + sizeof(uint8_t)))
159 {
160 ResetParser();
162 }
163
164 const auto target_size = current_topic_->data_.payload_size;
165 void* publish_addr = payload_addr;
166 if (reinterpret_cast<uintptr_t>(payload_addr) %
167 current_topic_->data_.payload_alignment !=
168 0)
169 {
170 publish_addr = parse_buff_.addr_;
171 if (data_len_ >= target_size)
172 {
173 LibXR::Memory::FastMove(publish_addr, payload_addr, target_size);
174 }
175 else
176 {
177 LibXR::Memory::FastMove(publish_addr, payload_addr, data_len_);
178 }
179 }
180
181 auto topic = Topic(current_topic_);
182 if (from_callback)
183 {
184 topic.PublishBytesFromServerCallback(publish_addr, target_size, current_timestamp_,
185 in_isr);
186 }
187 else
188 {
189 topic.PublishBytesFromServer(publish_addr, target_size, current_timestamp_);
190 }
191
192 ResetParser();
194}
static void FastMove(void *dst, const void *src, size_t size)
内存搬移 / Memory move
Topic()
构造一个空 topic 视图 / Construct one empty topic view
Definition topic.cpp:114

◆ Register()

void Topic::Server::Register ( TopicHandle topic)

注册一个可接收 packet 的 topic / Register one topic that may receive parsed packets

Parameters
topic目标 topic 句柄 / Target topic handle
Note
注册时会断言该 topic 的 payload_size + PACK_BASE_SIZE 能放进本 server 的 暂存缓冲区。 Registration asserts that the topic's payload_size + PACK_BASE_SIZE fits in this server's staging buffer.
server 的内部暂存缓冲区在构造时固定按 CACHE_LINE_SIZE 对齐分配;注册时还会 断言该 topic 的 payload_alignment <= CACHE_LINE_SIZE。 The server's internal staging buffer is allocated once at CACHE_LINE_SIZE alignment during construction; registration also asserts that the topic's payload_alignment <= CACHE_LINE_SIZE.

Definition at line 22 of file server.cpp.

23{
24 ASSERT(topic != nullptr);
25 ASSERT(topic->data_.payload_size != 0);
26 ASSERT(topic->data_.payload_alignment != 0);
27 ASSERT(topic->data_.payload_alignment <= LibXR::CACHE_LINE_SIZE);
28
29 ASSERT(topic->data_.payload_size + PACK_BASE_SIZE <= parse_buff_.size_);
30
31 auto* node = new RBTree<uint32_t>::Node<TopicHandle>(topic);
32 topic_map_.Insert(*node, topic->key);
33}
红黑树实现,支持泛型键和值,并提供线程安全操作 (Red-Black Tree implementation supporting generic keys and values with thread...
Definition rbt.hpp:23
void Insert(BaseNode &node, KeyType &&key)
在树中插入新节点 (Insert a new node into the tree).
Definition rbt.hpp:235

◆ ResetParser()

void Topic::Server::ResetParser ( )
private

清空当前包的解析上下文并回到找起点状态 / Clear the current packet parsing context and return to the start-search state

Definition at line 196 of file server.cpp.

197{
199 data_len_ = 0;
200 current_topic_ = nullptr;
202}
微秒时间戳 / Microsecond timestamp

◆ SyncToPacketStart()

bool Topic::Server::SyncToPacketStart ( )
private

把输入流同步到下一条 packet 起点 / Synchronize the input stream to the next packet start

Returns
若已找到起始字节则返回 true,否则返回 false / Returns true when a packet start byte is found, otherwise false

Definition at line 79 of file server.cpp.

80{
81 auto queue_size = queue_.Size();
82 for (uint32_t i = 0; i < queue_size; i++)
83 {
84 uint8_t prefix = 0;
85 queue_.PeekBytes(&prefix);
86 if (prefix == PACKET_PREFIX)
87 {
89 return true;
90 }
92 }
93
94 return false;
95}
ErrorCode PopBytes(void *data=nullptr)
按字节出队一个元素;传空指针时仅丢弃队头。
ErrorCode PeekBytes(void *data)
按字节查看队头元素但不出队。

Field Documentation

◆ current_timestamp_

MicrosecondTimestamp LibXR::Topic::Server::current_timestamp_
private

当前包头里的时间戳。Timestamp carried by the current packet header.

Definition at line 146 of file server.hpp.

◆ current_topic_

TopicHandle LibXR::Topic::Server::current_topic_
private
Initial value:
=
nullptr

当前包命中的目标 topic。Target topic matched by the current packet.

Definition at line 144 of file server.hpp.

◆ data_len_

uint32_t LibXR::Topic::Server::data_len_
private
Initial value:
=
0

当前包头声明的 payload 长度。Payload length declared by the current header.

Definition at line 137 of file server.hpp.

◆ parse_buff_

RawData LibXR::Topic::Server::parse_buff_
private

当前包头和 payload 的暂存缓冲区。Staging buffer holding the current header and payload.

Definition at line 142 of file server.hpp.

◆ queue_

QueueBase LibXR::Topic::Server::queue_
private

输入字节 FIFO。Input byte FIFO.

Definition at line 141 of file server.hpp.

◆ status_

Status LibXR::Topic::Server::status_ = Status::WAIT_START
private

当前 parser 阶段。Current parser stage.

Definition at line 136 of file server.hpp.

◆ topic_map_

RBTree<uint32_t> LibXR::Topic::Server::topic_map_
private

从 topic 名称 CRC32 到 topic 句柄的映射。Map from topic-name CRC32 to topic handle.

Definition at line 139 of file server.hpp.


The documentation for this class was generated from the following files: