Review date: 2026-05-08
Primary references:
- MAVLink packet serialization: https://mavlink.io/en/guide/serialization.html
- MAVLink routing: https://mavlink.io/en/guide/routing.html
- MAVLink 2 overview: https://mavlink.io/en/guide/mavlink_2.html
- MAVLink 2 signing: https://mavlink.io/en/guide/message_signing.html
- MAVLink XML schema guide: https://mavlink.io/en/guide/xml_schema.html
1.0 Support Posture
XMAVLink's 1.0 compatibility target is MAVLink 2 first. MAVLink 1 remains supported for basic frame parsing, packing, and routing while that support stays cheap to maintain, but MAVLink 1-only work should not displace MAVLink 2 correctness. If a future gap requires significant MAVLink 1-specific investment, prefer an explicit support reduction over slowing MAVLink 2 work.
Supported runtime scope:
- MAVLink 2 unsigned frames without incompatible flags.
- MAVLink 2 signed-frame boundary parsing and signature trailer
representation. Configured inbound signed frames are authenticated before
unpacking and routed with replay protection, and unsigned outbound MAVLink 2
frames are signed on signing-enabled connections. Applications can configure
timestamp load/save callbacks for local signing timestamp persistence. Inbound
SETUP_SIGNINGframes are delivered locally but not forwarded between MAVLink connections. - MAVLink 1 frames for existing users and legacy links.
- Serial,
udpin,udpout, and outbound TCP (tcpout) transports. - Generated dialect modules from trusted MAVLink XML build inputs.
Known non-goals for 1.0 unless separately implemented:
- Automatic
SETUP_SIGNINGkey provisioning. - TCP server (
tcpin) transport. - Treating untrusted XML dialect files as safe input.
- Full
mavgenfeature parity for XML validation, WIP filtering, and every generated helper surface.
Checklist
| Area | Status | Notes |
|---|---|---|
| MAVLink 2 frame shape | Supported | Parses and emits the v2 header, 24-bit message id, payload, checksum, and compatible flags. Unsupported incompatible flags are discarded. |
| MAVLink 2 signing | Supported with provisioning caveat | Signed-frame boundaries and the 13-byte signature trailer are parsed and represented. Configured inbound signed frames are verified before unpacking and routed with per-connection replay checks. Unsigned MAVLink 2 inbound frames are rejected by default while signing is enabled unless explicitly accepted. Unsigned outbound MAVLink 2 frames are signed on signing-enabled connections with per-connection timestamp increments. Optional timestamp load/save callbacks let applications persist local signing timestamps. Inbound SETUP_SIGNING frames are local-only; XMAVLink does not automate key provisioning. See MAVLINK2_SIGNING.md. |
| MAVLink 2 payload truncation | Supported | Outbound payloads trim trailing zero bytes while preserving a non-empty all-zero payload's first byte; inbound v2 payloads are padded back to known dialect length before unpacking. |
| MAVLink 2 future extension bytes | Supported | Generated v2 unpack clauses now ignore trailing extension bytes that are unknown to the local dialect. This preserves extension-field forward compatibility. |
| MAVLink 2 extension CRC behavior | Supported | CRC_EXTRA generation excludes extension fields, matching the serialization guide. |
| MAVLink 2 extension field packing defaults | Supported | Omitted known extension fields are packed as zero-equivalent values for v2 messages while remaining omitted from v1 payloads. |
| MAVLink 1 frame shape | Supported | Existing parser/packer handles v1 framing, checksum, and 8-bit message ids. New MAVLink 1-only expansion is not a priority for 1.0. |
| CRC_EXTRA calculation | Supported | Field ordering is size-stable for base fields, arrays are ordered by element size, and extension fields are excluded. |
| Field ordering | Supported | Base fields are stably sorted by native type size; extension fields remain in XML declaration order. |
| Unknown message handling | Partial | Unknown known-shape frames are forwarded as broadcast when the message id is not present in the dialect. Unknown messages cannot expose target fields because the payload cannot be decoded. |
| Compatible flags | Supported | MAVLink 2 compatible flags are retained and otherwise ignored. |
| Incompatible flags | Supported | Unknown incompatible flags are discarded as required. Signing's known 13-byte trailer is consumed when present so stream boundaries stay aligned. |
| Routing unchanged packets | Supported with signing caveat | Forwarding generally uses the original raw frame bytes. Unsigned MAVLink 2 frames sent over signing-enabled connections are signed for that outbound link; already signed MAVLink 2 frames are forwarded unchanged. |
| Target inference | Supported | Generated metadata classifies broadcast, system, component, and system-component targets from target_system and target_component fields. |
| Route reset after reboot | Supported | Routing tracks SYSTEM_TIME.time_boot_ms per source system/component and clears learned routes for that system when the same source reports a lower boot time. |
| XML includes | Supported with limits | Includes are recursive and deterministic. Missing includes, empty includes, include cycles, conflicting include paths, excessive include depth/count, and oversized XML files return explicit errors. |
| Enum merging | Partial | Matching enum names are merged and sorted by value. Duplicate enum entries and duplicate resolved values are rejected. |
| Duplicate message ids | Supported validation | Duplicate message ids are rejected across the combined dialect, including included XML files. |
XML bitmask="true" | Supported | Enum-level bitmask declarations are parsed and used before heuristic bitmask detection. |
| XML identifiers and source generation safety | Partial | XML is treated as trusted build input. The parser validates generated identifiers, rejects reserved enum/message/field names, and escapes generated docs/descriptions before source generation. |
| Generated Common dialect | Supported within above scope | lib/common.ex is regenerated from config/common.xml and should be treated as build output. |
Changes Made In This Pass
- Generated MAVLink 2 unpackers now accept extra trailing bytes after all locally known fields and ignore them as future extension fields.
- Generated unpack specs now match the actual
unpack/3runtime API and include anunpack/3fallback. - Generated modules now compile for XML dialects with no enums or units.
- Enum-level
bitmask="true"is parsed and reflected in generated field types, packing, and unpacking. - Generated MAVLink 2 packers use zero-equivalent defaults for omitted known extension fields.
- MAVLink 2 signed frames now parse the 13-byte signature trailer into frame metadata.
- Low-level MAVLink 2 frame signing can set the signed incompatibility flag, recalculate checksum bytes, and append a generated signature trailer for an already packed frame.
- Low-level MAVLink 2 signing validation can verify signed frames and reject replayed or too-old timestamps.
- Inbound router and connection signing policy can verify signed MAVLink 2 frames before unpacking, track replay state per connection, and reject unsigned MAVLink 2 frames by default while signing is enabled.
- Outbound router signing can sign unsigned MAVLink 2 frames on signing-enabled connections while leaving MAVLink 1 frames unsigned.
- Signing policy can load and save local signing timestamps through application callbacks, and rejects state-advancing frames when configured persistence fails.
- Inbound
SETUP_SIGNINGframes are delivered locally but not forwarded between MAVLink connections by generic routing. - Learned routes are cleared for a remote system when the same
system/component reports a lower
SYSTEM_TIME.time_boot_ms, preventing stale targeted forwarding after reboot. - Unsupported signed MAVLink 2 frames consume the 13-byte signature trailer when present, preventing TCP/serial stream buffers from treating signature bytes as a new frame prefix.
- MAVLink 2 packing now preserves a truly empty payload as length zero.
- Core MAVLink integer types were tightened for the signed 32-bit minimum and unsigned 64-bit zero value.
Follow-Up Issues
- #53: Continue aligning XML parser/generator validation with
mavgen.
These follow-ups should be prioritized by MAVLink 2 impact first. None of the reviewed gaps require new MAVLink 1-only work before 1.0.