13 #include <unordered_map>
15 #ifndef _UGCS_VSM_MAVLINK_DECODER_H_
16 #define _UGCS_VSM_MAVLINK_DECODER_H_
61 uint64_t no_handler = 0;
63 uint64_t bad_checksum = 0;
65 uint64_t bad_length = 0;
69 uint64_t unknown_id = 0;
71 uint64_t bytes_received = 0;
74 uint64_t stx_syncs = 0;
80 packet_buf(ugcs::vsm::
Io_buffer::Create())
101 this->handler = handler;
107 data_handler = handler;
116 data_handler(buffer);
118 packet_buf = packet_buf->Concatenate(buffer);
124 size_t buffer_len = packet_buf->Get_length();
126 std::lock_guard<std::mutex> stats_lock(stats_mutex);
129 size_t len_skipped = 0;
130 if (buffer_len < mavlink::MAVLINK_1_MIN_FRAME_LEN) {
132 next_read_len = mavlink::MAVLINK_1_MIN_FRAME_LEN - buffer_len;
136 data =
static_cast<const uint8_t*
>(packet_buf->Get_data());
137 for (; len_skipped < buffer_len; len_skipped++, data++) {
143 packet_buf = packet_buf->Slice(1);
151 packet_buf = packet_buf->Slice(1);
157 packet_buf = packet_buf->Slice(len_skipped);
164 wrapper_len = mavlink::MAVLINK_1_HEADER_LEN - 1 + 2;
166 wrapper_len = mavlink::MAVLINK_2_HEADER_LEN - 1 + 2;
168 buffer_len = packet_buf->Get_length();
169 if (buffer_len == 0) {
171 next_read_len = wrapper_len;
174 data =
static_cast<const uint8_t*
>(packet_buf->Get_data());
175 packet_len = wrapper_len +
static_cast<size_t>(*data);
176 if (packet_len > buffer_len) {
178 next_read_len = packet_len - buffer_len;
181 if (Decode_packet(packet_buf)) {
183 packet_buf = packet_buf->Slice(packet_len);
200 return next_read_len;
208 const Mavlink_decoder::Stats
211 std::lock_guard<std::mutex> lock(stats_mutex);
212 return stats[system_id];
216 const Mavlink_decoder::Stats
219 std::lock_guard<std::mutex> lock(stats_mutex);
227 auto data =
static_cast<const uint8_t*
>(buffer->Get_data());
228 uint16_t payload_len =
data[0];
230 uint8_t component_id;
238 component_id =
data[5];
240 static_cast<int>(
data[6]) +
241 (static_cast<int>(
data[7]) << 8) +
242 (static_cast<int>(
data[8]) << 16);
243 header_len = mavlink::MAVLINK_2_HEADER_LEN - 1;
247 component_id =
data[3];
249 header_len = mavlink::MAVLINK_1_HEADER_LEN - 1;
252 mavlink::Checksum sum(
data, header_len);
259 std::lock_guard<std::mutex> stats_lock(stats_mutex);
265 sum.Accumulate(
data + header_len, payload_len);
267 uint16_t sum_calc = sum.Accumulate(crc_byte_len_pair.first);
270 auto sum_recv =
reinterpret_cast<const mavlink::Uint16*
>(
data + header_len + payload_len);
272 bool cksum_ok = sum_calc == *sum_recv;
273 bool length_ok = crc_byte_len_pair.second == payload_len;
275 std::unique_lock<std::mutex> stats_lock(stats_mutex);
276 if (cksum_ok && (length_ok || state ==
State::VER2)) {
281 stats[system_id].handled++;
284 handler(
Io_buffer::Create(*buffer, header_len, payload_len), msg_id, system_id, component_id, seq);
286 stats[system_id].no_handler++;
288 LOG_DEBUG(
"Mavlink message %d handler not registered.", msg_id);
293 stats[system_id].bad_length++;
295 LOG_DEBUG(
"Mavlink payload length mismatch, recv=%d wanted=%d.",
296 payload_len, crc_byte_len_pair.second);
315 std::unordered_map<int, Stats> stats;
316 std::mutex stats_mutex;
321 size_t next_read_len = mavlink::MAVLINK_1_MIN_FRAME_LEN;
#define LOG_DEBUG(msg,...)
Write debug message to the application log.
Definition: log.h:323
TValue data[size]
Values array itself.
Definition: mavlink.h:192
Starting byte of Mavlink packet.
Definition: mavlink.h:32
MAVLink protocol messages.
Starting byte of Mavlink v2 packet.
Definition: mavlink.h:34
#define DEFINE_CALLBACK_BUILDER(__name, __types, __values)
Define callback builder function.
Definition: callback.h:42
static Ptr Create(Args &&...args)
Create an instance.
Definition: io_buffer.h:34
const Mavlink_decoder::Stats Get_common_stats()
Get read-only access to common statistics.
Definition: mavlink_decoder.h:217
uint32_t MESSAGE_ID_TYPE
Message id implementation type capable to hold a message id value from any extension (i...
Definition: mavlink.h:353
std::pair< uint32_t, uint16_t > Extra_byte_length_pair
A pair of values representing CRC extra byte and length of the Mavlink message payload.
Definition: mavlink.h:348
size_t Get_next_read_size() const
Get the exact number of bytes which should be read by underlying I/O subsystem and fed to the decoder...
Definition: mavlink_decoder.h:198
Generic callback which can be used to define and create an instance of an abstract callable operation...
void Disable()
Should be called prior to intention to delete the instance.
Definition: mavlink_decoder.h:89
Callback_proxy< void, Io_buffer::Ptr, mavlink::MESSAGE_ID_TYPE, uint8_t, uint8_t, uint32_t > Handler
Handler type of the received Mavlink message.
Definition: mavlink_decoder.h:42
Helper class for proxying callback invocation.
Definition: callback.h:699
Special value representing any Mavlink system id.
Definition: mavlink.h:41
T Get() const
Get the value of underlying type.
Definition: endian.h:344
System_id value denoting an unknown system, or all systems depending on context.
Definition: mavlink.h:38
Generic I/O buffer.
Definition: io_buffer.h:33
Mavlink_decoder()
Default constructor.
Definition: mavlink_decoder.h:79
Decodes Mavlink 1.0 messages from byte stream.
Definition: mavlink_decoder.h:22
Callback_proxy< void, Io_buffer::Ptr > Raw_data_handler
Handler for the raw data going through the decoder.
Definition: mavlink_decoder.h:45
const Mavlink_decoder::Stats Get_stats(int system_id)
Get read-only access to statistics.
Definition: mavlink_decoder.h:209
std::shared_ptr< Io_buffer > Ptr
Pointer type.
Definition: io_buffer.h:34
static const Extension & Get()
Get the extension instance.
Definition: mavlink.h:369
void Decode(Io_buffer::Ptr buffer)
Decode buffer from the wire.
Definition: mavlink_decoder.h:112
void Register_handler(Handler handler)
Register handler for successfully decoded Mavlink messages.
Definition: mavlink_decoder.h:99