1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//! The MAVLink wire protocol for the pamoja SDK.
//!
//! MAVLink is the language drones speak: PX4 and ArduPilot autopilots and MAVSDK ground
//! stations all exchange MAVLink frames, so talking to a vehicle means putting exactly the
//! right bytes on the wire and trusting the bytes that come back. This crate is that byte
//! layer, hand-written from the [MAVLink specification](https://mavlink.io) and pinned to
//! its reference values rather than guessed from memory:
//!
//! - [`crc16_mcrf4xx`] - the CRC-16/MCRF4XX every frame carries, the checksum that lets a
//! receiver reject a frame mangled in transit, anchored to the catalogue check value.
//! - [`Frame`] - the v1 and v2 frame on the wire, which both [assembles](Frame::encode_v2)
//! a frame to send and [parses](Frame::parse) one received, verifying the checksum and
//! the per-message [`message_crc_extra`] seed so a corrupt or mismatched frame never
//! reaches the application.
//! - [`Parser`] - a streaming parser that turns the bytes a link delivers into whole
//! frames, resynchronizing on noise so a serial port or UDP socket just works.
//! - [`signing`] - MAVLink 2 message signing: the SHA-256 signature and the monotonic
//! timestamp that let a ground station trust a command came from the vehicle it expects
//! and was not replayed.
//! - [`dialect`] - a broad, typed slice of the common dialect (HEARTBEAT, the command,
//! parameter, and mission protocols, and core telemetry), plus message shapes as data:
//! a [`MessageDescriptor`](dialect::MessageDescriptor) gives any message's bytes named
//! fields, and a [builder](dialect::MessageDescriptorBuilder) describes one this crate
//! does not type, so a vendor or private dialect is usable at runtime.
//! - [`protocol`] - the mission, command, and offboard exchanges as pure, allocation-free
//! state machines: the rules of order, matching, and retransmission that turn single
//! messages into a real conversation with an autopilot, with no IO of their own. Each
//! machine also takes a [`Frame`] at a time and hands back the frame to send, so a
//! caller holding a link writes no decoding or dispatch of its own.
//!
//! The protocol core is `no_std` and allocation-free, so the same framing runs on a
//! microcontroller flight controller. The default `std` feature adds the async layer: the
//! byte-stream link seam and an in-process software-in-the-loop autopilot ([`link`]), the
//! [`vehicle`] device model that presents an autopilot as a pamoja `Device`, and the real
//! [`drivers`] (UDP, TCP, and serial behind the `serial` feature) that carry MAVLink to a real
//! or simulated autopilot.
//!
//! # Examples
//!
//! ```
//! use pamoja_mavlink::dialect::{Heartbeat, Message};
//! use pamoja_mavlink::{Frame, Header};
//!
//! // Announce this node as an onboard controller.
//! let heartbeat = Heartbeat {
//! custom_mode: 0,
//! type_: 18, // MAV_TYPE_ONBOARD_CONTROLLER
//! autopilot: 0,
//! base_mode: 0,
//! system_status: 4, // MAV_STATE_ACTIVE
//! mavlink_version: 3,
//! };
//!
//! // Encode it into a v2 frame, then read it back the way a peer would.
//! let mut payload = [0u8; 255];
//! let len = heartbeat.encode(&mut payload);
//! let frame = Frame::encode_v2(Header::new(1, 1, 0), Heartbeat::ID, &payload[..len], Heartbeat::CRC_EXTRA)?;
//!
//! let received = Frame::parse(frame.as_bytes(), Heartbeat::CRC_EXTRA)?;
//! let decoded = Heartbeat::decode(received.payload())?;
//! assert_eq!(decoded.system_status, 4);
//! # Ok::<(), pamoja_mavlink::MavlinkError>(())
//! ```
extern crate alloc;
pub use ;
pub use ;
pub use ;
pub use Parser;
pub use ;
pub use ;
pub use ;
pub use SerialLink;