QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
RTCMParser.cc
Go to the documentation of this file.
1#include "RTCMParser.h"
2
7
9{
10 _state = State::WaitingForPreamble;
11 _messageLength = 0;
12 _bytesRead = 0;
13 _lengthBytesRead = 0;
14 _crcBytesRead = 0;
15}
16
17bool RTCMParser::addByte(uint8_t byte)
18{
19 switch (_state) {
20 case State::WaitingForPreamble:
21 if (byte == kPreamble) {
22 _buffer[0] = byte;
23 _bytesRead = 1;
24 _state = State::ReadingLength;
25 _lengthBytesRead = 0;
26 }
27 break;
28
29 case State::ReadingLength:
30 _lengthBytes[_lengthBytesRead++] = byte;
31 _buffer[_bytesRead++] = byte;
32 if (_lengthBytesRead == 2) {
33 _messageLength = ((_lengthBytes[0] & 0x03) << 8) | _lengthBytes[1];
34 if (_messageLength > 0 && _messageLength <= kMaxPayloadLength) {
35 _state = State::ReadingMessage;
36 } else {
37 reset();
38 }
39 }
40 break;
41
42 case State::ReadingMessage:
43 if (_bytesRead < kHeaderSize + kMaxPayloadLength) {
44 _buffer[_bytesRead++] = byte;
45 } else {
46 // Buffer overflow — corrupt or oversized message; discard and
47 // re-process this byte, which may itself be a fresh preamble.
48 reset();
49 return addByte(byte);
50 }
51 if (_bytesRead >= _messageLength + kHeaderSize) {
52 _state = State::ReadingCRC;
53 _crcBytesRead = 0;
54 }
55 break;
56
57 case State::ReadingCRC:
58 _crcBytes[_crcBytesRead++] = byte;
59 if (_crcBytesRead == kCrcSize) {
60 return true;
61 }
62 break;
63 }
64 return false;
65}
66
67uint16_t RTCMParser::messageId() const
68{
69 if (_messageLength >= 2) {
70 return ((_buffer[3] << 4) | (_buffer[4] >> 4)) & 0xFFF;
71 }
72 return 0;
73}
74
75uint32_t RTCMParser::crc24q(const uint8_t* data, size_t len)
76{
77 static constexpr uint32_t kPoly = 0x1864CFB;
78 uint32_t crc = 0;
79 for (size_t i = 0; i < len; i++) {
80 crc ^= static_cast<uint32_t>(data[i]) << 16;
81 for (int j = 0; j < 8; j++) {
82 crc <<= 1;
83 if (crc & 0x1000000) {
84 crc ^= kPoly;
85 }
86 }
87 }
88 return crc & 0xFFFFFF;
89}
90
92{
93 if (_messageLength == 0 || _bytesRead < kHeaderSize + _messageLength) {
94 return false;
95 }
96
97 const uint32_t computed = crc24q(_buffer, kHeaderSize + _messageLength);
98 const uint32_t received = (static_cast<uint32_t>(_crcBytes[0]) << 16) | (static_cast<uint32_t>(_crcBytes[1]) << 8) |
99 static_cast<uint32_t>(_crcBytes[2]);
100 return computed == received;
101}
102
103QByteArray RTCMParser::currentFrame() const
104{
105 QByteArray frame(reinterpret_cast<const char*>(_buffer), kHeaderSize + _messageLength);
106 frame.append(reinterpret_cast<const char*>(_crcBytes), kCrcSize);
107 return frame;
108}
void reset()
Definition RTCMParser.cc:8
bool validateCrc() const
Definition RTCMParser.cc:91
static uint32_t crc24q(const uint8_t *data, size_t len)
Definition RTCMParser.cc:75
static constexpr int kCrcSize
Definition RTCMParser.h:31
QByteArray currentFrame() const
static constexpr int kHeaderSize
Definition RTCMParser.h:32
uint16_t messageId() const
Definition RTCMParser.cc:67
bool addByte(uint8_t byte)
Definition RTCMParser.cc:17
static constexpr uint8_t kPreamble
Definition RTCMParser.h:12