QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
RTCMMAVLinkPacket.cc
Go to the documentation of this file.
1#include "RTCMMAVLinkPacket.h"
2
3#include <algorithm>
4#include <utility>
5
6uint8_t RTCMMAVLinkPacket::_makeFlags(bool fragmented, uint8_t fragmentId, uint8_t sequenceId)
7{
8 uint8_t flags = static_cast<uint8_t>((sequenceId & 0x1FU) << 3);
9 if (fragmented) {
10 flags |= 0x01U;
11 flags |= static_cast<uint8_t>((fragmentId & 0x03U) << 1);
12 }
13 return flags;
14}
15
16RTCMMAVLinkPacket::PackResult RTCMMAVLinkPacket::pack(QByteArrayView data, uint8_t sequenceId)
17{
18 PackResult result;
19 result.nextSequenceId = sequenceId;
20
21 if (data.isEmpty()) {
22 return result;
23 }
24
25 // Oversized frames require stream reconstruction, not wrapped fragment IDs.
26 const bool fragmented = data.size() > kFragmentLen && data.size() <= kMaxAssembledLen;
27 uint8_t fragmentId = 0;
28 qsizetype start = 0;
29 while (start < data.size()) {
30 const qsizetype length = (std::min) (data.size() - start, kFragmentLen);
31 GPSRTCMPacket packet;
32 packet.flags = _makeFlags(fragmented, fragmentId, result.nextSequenceId);
33 packet.data = data.mid(start, length).toByteArray();
34 result.packets.append(std::move(packet));
35 if (fragmented) {
36 ++fragmentId;
37 } else {
38 ++result.nextSequenceId;
39 }
40 start += length;
41 }
42
43 // Full fragments need a terminator unless all four are present.
44 if (fragmented) {
45 if ((data.size() % kFragmentLen) == 0 && fragmentId < kMaxFragments) {
46 result.packets.append(GPSRTCMPacket{_makeFlags(true, fragmentId, result.nextSequenceId), {}});
47 }
48 ++result.nextSequenceId;
49 }
50 return result;
51}
static constexpr qsizetype kMaxAssembledLen
static PackResult pack(QByteArrayView data, uint8_t sequenceId)
static constexpr qsizetype kMaxFragments
static constexpr qsizetype kFragmentLen
QList< GPSRTCMPacket > packets