5namespace robust_frame {
7constexpr size_t kMinUnescapedSize = 2;
9constexpr uint8_t kFrameHeader = 0xAA;
10constexpr uint8_t kFrameFooter = 0x55;
11constexpr uint8_t kEscapeChar = 0xDB;
12constexpr uint8_t kXorEscape = 0x20;
14constexpr bool CheckXorOperator() {
15 return ((kFrameHeader ^ kXorEscape) != kFrameHeader && (kFrameHeader ^ kXorEscape) != kFrameFooter && (kFrameHeader ^ kXorEscape) != kEscapeChar) &&
16 ((kFrameFooter ^ kXorEscape) != kFrameHeader && (kFrameFooter ^ kXorEscape) != kFrameFooter && (kFrameFooter ^ kXorEscape) != kEscapeChar) &&
17 ((kEscapeChar ^ kXorEscape) != kFrameHeader && (kEscapeChar ^ kXorEscape) != kFrameFooter && (kEscapeChar ^ kXorEscape) != kEscapeChar);
20static_assert(CheckXorOperator(),
"XOR operator 0x20 is not safe");
24 : max_payload_size_(max_payload_size + 1), callback_(callback), user_data_(user_data), buffer_(new uint8_t[max_payload_size_]) {
33 case State::kSyncHeader: {
34 if (
byte == kFrameHeader) {
36 state_ = State::kCollectPayload;
40 case State::kCollectPayload: {
41 if (
byte == kFrameFooter) {
42 if (buffer_len_ >= kMinUnescapedSize &&
crc8::Calculate(buffer_,
static_cast<size_t>(buffer_len_ - 1)) == buffer_[buffer_len_ - 1]) {
44 callback_(buffer_, user_data_);
48 }
else if (
byte == kEscapeChar) {
49 state_ = State::kUnescape;
50 }
else if (
byte == kFrameHeader || buffer_len_ == max_payload_size_) {
53 }
else if (buffer_len_ < max_payload_size_) {
54 buffer_[buffer_len_++] = byte;
60 case State::kUnescape: {
61 const uint8_t unescaped =
byte ^ kXorEscape;
62 if (unescaped != kFrameHeader && unescaped != kFrameFooter && unescaped != kEscapeChar) {
65 }
else if (buffer_len_ < max_payload_size_) {
66 buffer_[buffer_len_++] = unescaped;
67 state_ = State::kCollectPayload;
81 state_ = State::kSyncHeader;
void(*)(const uint8_t *data, void *user_data) FrameCallback
帧解析回调函数类型。
~Parser()
析构函数,释放内部动态分配的缓冲区。
Parser(const size_t max_payload_size, FrameCallback callback, void *user_data)
构造函数,根据最大载荷长度动态分配内部缓冲区。
void Feed(const uint8_t byte)
处理单个字节的核心状态机。
uint8_t Calculate(const uint8_t *data, const size_t size)
计算数据的 CRC-8 校验值(SAE J1850 标准)。