Program Listing for File interface.hpp
↰ Return to documentation for file (include/mavconn/interface.hpp
)
//
// libmavconn
// Copyright 2013,2014,2015,2016,2021 Vladimir Ermakov, All rights reserved.
//
// This file is part of the mavros package and subject to the license terms
// in the top-level LICENSE file of the mavros repository.
// https://github.com/mavlink/mavros/tree/master/LICENSE.md
//
#pragma once
#ifndef MAVCONN__INTERFACE_HPP_
#define MAVCONN__INTERFACE_HPP_
#include <atomic>
#include <cassert>
#include <chrono>
#include <deque>
#include <functional>
#include <memory>
#include <mutex>
#include <sstream>
#include <stdexcept>
#include <string>
#include <system_error>
#include <thread>
#include <unordered_map>
#include <vector>
#include <mavconn/mavlink_dialect.hpp>
namespace mavconn
{
using steady_clock = std::chrono::steady_clock;
using lock_guard = std::lock_guard<std::recursive_mutex>;
static constexpr auto MAV_COMP_ID_UDP_BRIDGE = 240;
enum class Framing : uint8_t
{
incomplete = mavlink::MAVLINK_FRAMING_INCOMPLETE,
ok = mavlink::MAVLINK_FRAMING_OK,
bad_crc = mavlink::MAVLINK_FRAMING_BAD_CRC,
bad_signature = mavlink::MAVLINK_FRAMING_BAD_SIGNATURE,
};
enum class Protocol : uint8_t
{
V10 = 1,
V20 = 2
};
class DeviceError : public std::runtime_error
{
public:
template<typename T>
DeviceError(const char * module, T msg)
: std::runtime_error(make_message(module, msg))
{
}
template<typename T>
static std::string make_message(const char * module, T msg)
{
std::ostringstream ss;
ss << "DeviceError:" << module << ":" << msg_to_string(msg);
return ss.str();
}
static std::string msg_to_string(const char * description)
{
return description;
}
static std::string msg_to_string(int errnum)
{
return ::strerror(errnum);
}
static std::string msg_to_string(std::system_error & err)
{
return err.what();
}
};
class MAVConnInterface
{
private:
MAVConnInterface(const MAVConnInterface &) = delete;
public:
using ReceivedCb = std::function<void (const mavlink::mavlink_message_t * message,
const Framing framing)>;
using ClosedCb = std::function<void (void)>;
using Ptr = std::shared_ptr<MAVConnInterface>;
using ConstPtr = std::shared_ptr<MAVConnInterface const>;
using WeakPtr = std::weak_ptr<MAVConnInterface>;
struct IOStat
{
size_t tx_total_bytes;
size_t rx_total_bytes;
float tx_speed;
float rx_speed;
};
explicit MAVConnInterface(uint8_t system_id = 1, uint8_t component_id = MAV_COMP_ID_UDP_BRIDGE);
virtual void connect(
const ReceivedCb & cb_handle_message,
const ClosedCb & cb_handle_closed_port = ClosedCb()) = 0;
virtual void close() = 0;
virtual void send_message(const mavlink::mavlink_message_t * message) = 0;
virtual void send_message(const mavlink::Message & message)
{
send_message(message, this->comp_id);
}
virtual void send_message(const mavlink::Message & message, const uint8_t src_compid) = 0;
virtual void send_bytes(const uint8_t * bytes, size_t length) = 0;
void send_message_ignore_drop(const mavlink::mavlink_message_t * message);
void send_message_ignore_drop(const mavlink::Message & message)
{
send_message_ignore_drop(message, this->comp_id);
}
void send_message_ignore_drop(const mavlink::Message & message, const uint8_t src_compid);
ReceivedCb message_received_cb;
ClosedCb port_closed_cb;
virtual mavlink::mavlink_status_t get_status();
virtual IOStat get_iostat();
virtual bool is_open() = 0;
inline uint8_t get_system_id()
{
return sys_id;
}
inline void set_system_id(uint8_t sysid)
{
sys_id = sysid;
}
inline uint8_t get_component_id()
{
return comp_id;
}
inline void set_component_id(uint8_t compid)
{
comp_id = compid;
}
void set_protocol_version(Protocol pver);
Protocol get_protocol_version();
static Ptr open_url(
std::string url,
uint8_t system_id = 1, uint8_t component_id = MAV_COMP_ID_UDP_BRIDGE,
const ReceivedCb & cb_handle_message = ReceivedCb(),
const ClosedCb & cb_handle_closed_port = ClosedCb()
);
static Ptr open_url_no_connect(
std::string url,
uint8_t system_id = 1,
uint8_t component_id = MAV_COMP_ID_UDP_BRIDGE);
static std::vector<std::string> get_known_dialects();
protected:
uint8_t sys_id;
uint8_t comp_id;
static constexpr size_t MAX_PACKET_SIZE = MAVLINK_MAX_PACKET_LEN + 16;
static constexpr size_t MAX_TXQ_SIZE = 1000;
static std::unordered_map<mavlink::msgid_t, const mavlink::mavlink_msg_entry_t *> message_entries;
size_t conn_id;
inline mavlink::mavlink_status_t * get_status_p()
{
return &m_parse_status;
}
inline mavlink::mavlink_message_t * get_buffer_p()
{
return &m_buffer;
}
void parse_buffer(const char * pfx, uint8_t * buf, const size_t bufsize, size_t bytes_received);
void iostat_tx_add(size_t bytes);
void iostat_rx_add(size_t bytes);
void log_recv(const char * pfx, mavlink::mavlink_message_t & msg, Framing framing);
void log_send(const char * pfx, const mavlink::mavlink_message_t * msg);
void log_send_obj(const char * pfx, const mavlink::Message & msg);
private:
friend const mavlink::mavlink_msg_entry_t * mavlink::mavlink_get_msg_entry(uint32_t msgid);
mavlink::mavlink_status_t m_parse_status;
mavlink::mavlink_message_t m_buffer;
mavlink::mavlink_status_t m_mavlink_status;
std::atomic<size_t> tx_total_bytes, rx_total_bytes;
std::recursive_mutex iostat_mutex;
size_t last_tx_total_bytes, last_rx_total_bytes;
std::chrono::time_point<steady_clock> last_iostat;
static std::atomic<size_t> conn_id_counter;
static std::once_flag init_flag;
static void init_msg_entry();
};
} // namespace mavconn
#endif // MAVCONN__INTERFACE_HPP_