From a1cc93101155db1588d1b7ba8a8e0f303f68564b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Nov 2025 18:50:08 +0000 Subject: [PATCH 1/7] Initial plan From 5ca1e637923ece7ec9f83c76557df56b4c5ce06c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Nov 2025 18:57:32 +0000 Subject: [PATCH 2/7] Add frame_formats.proto with comprehensive framing definitions Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com> --- docs/framing.md | 135 +++++- examples/frame_formats.proto | 840 +++++++++++++++++++++++++++++++++++ 2 files changed, 954 insertions(+), 21 deletions(-) create mode 100644 examples/frame_formats.proto diff --git a/docs/framing.md b/docs/framing.md index 6bc89d55..557d1e83 100644 --- a/docs/framing.md +++ b/docs/framing.md @@ -2,6 +2,32 @@ Framing wraps messages with headers and checksums so receivers can identify message boundaries and verify integrity. +## Frame Format Definitions + +All supported frame formats are defined in [`examples/frame_formats.proto`](../examples/frame_formats.proto). This file provides: + +- Protocol Buffer definitions for each frame format +- Detailed documentation of use cases and tradeoffs +- Enumeration of all frame format types +- Configuration message for runtime format selection + +## Frame Format Overview + +| Format | Header | Footer | Length Field | Use Case | +|--------|--------|--------|--------------|----------| +| NoFormat | 0 | 0 | None | Trusted links, nested protocols | +| MsgIdFrame | 1 | 2 | None | Minimal framing with CRC | +| MsgIdFrameNoCrc | 1 | 0 | None | Minimal framing, trusted link | +| BasicFrame | 2 | 2 | None | Standard reliable communication | +| BasicFrameNoCrc | 2 | 0 | None | Sync recovery, no CRC | +| TinyFrame | 1 | 2 | None | Low overhead with CRC | +| TinyFrameNoCrc | 1 | 0 | None | Minimal overhead | +| *Len8 variants | +1 | same | 8-bit | Variable length up to 255 bytes | +| *Len16 variants | +2 | same | 16-bit | Variable length up to 64KB | +| UBX | 6 | 2 | 16-bit | u-blox GPS compatibility | +| MavlinkV1 | 6 | 2 | 8-bit | Legacy drone communication | +| MavlinkV2 | 10 | 2-15 | 8-bit | Modern drone communication | + ## No Frame Format For trusted point-to-point links where you control both ends, you can skip framing entirely. Messages are sent as raw bytes with no header or checksum. @@ -62,6 +88,47 @@ Total bytes = 2 (header) + payload size + 2 (checksum) For a message with 5 bytes of data: 2 + 5 + 2 = 9 bytes total +## MSG ID Frame Variants + +Minimal framing with just message ID and optional CRC: + +**MsgIdFrame**: `[MSG_ID (1)] [PAYLOAD] [CRC (2)]` +- 3 bytes overhead +- For synchronized links with error detection + +**MsgIdFrameNoCrc**: `[MSG_ID (1)] [PAYLOAD]` +- 1 byte overhead +- For trusted, synchronized links + +## Tiny Frame Variants + +Low overhead framing for constrained environments: + +**TinyFrame**: `[START (1)] [MSG_ID (1)] [PAYLOAD] [CRC (2)]` +- 4 bytes overhead +- Battery-powered devices, high message rates + +**TinyFrameNoCrc**: `[START (1)] [MSG_ID (1)] [PAYLOAD]` +- 2 bytes overhead +- Minimal overhead with sync recovery + +## Length-Prefixed Variants + +All frame formats have variants with explicit length fields: + +**8-bit length (Len8)**: Supports payloads up to 255 bytes +- Adds 1 byte to header +- Use for variable-length messages + +**16-bit length (Len16)**: Supports payloads up to 65,535 bytes +- Adds 2 bytes to header (little-endian) +- Use for large data transfers, firmware updates + +Example: `BasicFrameLen16` +``` +[START (1)] [MSG_ID (1)] [LEN_LO (1)] [LEN_HI (1)] [PAYLOAD] [CRC (2)] +``` + ## Parser State Machine The parser implements a state machine to handle partial data and recover from corruption: @@ -109,29 +176,48 @@ for each byte in (message_id + payload): checksum = [sum1, sum2] ``` -## Custom Frame Formats +## Industry Standard Protocols + +### UBX Format -The architecture supports alternative frame formats. Planned implementations: +u-blox proprietary binary protocol for GPS/GNSS receivers: + +``` +[SYNC1 (0xB5)] [SYNC2 (0x62)] [CLASS (1)] [ID (1)] [LEN (2)] [PAYLOAD] [CK_A] [CK_B] +``` -**UBX Format** -- Used by u-blox GPS receivers -- 2-byte sync sequence (0xB5, 0x62) -- Class + ID message identification -- Little-endian 2-byte length field +- 8 bytes overhead +- Class + ID for message routing - Fletcher-8 checksum +- Use for u-blox GPS integration + +### MAVLink v1 -**Mavlink v1** -- Used by ArduPilot and PX4 -- 0xFE start byte -- Sequence counter -- System ID and Component ID -- CRC-16 checksum +Legacy drone communication protocol: + +``` +[STX (0xFE)] [LEN (1)] [SEQ (1)] [SYS (1)] [COMP (1)] [MSG (1)] [PAYLOAD] [CRC (2)] +``` + +- 8 bytes overhead +- Sequence counter for packet loss detection +- System ID and Component ID for multi-vehicle networks +- CRC-16/X.25 checksum +- Use for ArduPilot/PX4 compatibility + +### MAVLink v2 + +Modern drone communication with extended features: + +``` +[STX (0xFD)] [LEN (1)] [INCOMPAT (1)] [COMPAT (1)] [SEQ (1)] [SYS (1)] [COMP (1)] [MSG_ID (3)] [PAYLOAD] [CRC (2)] [SIGNATURE (13, optional)] +``` -**Mavlink v2** -- 0xFD start byte -- Incompatibility flags -- Compatibility flags -- Optional signature for authentication +- 12-25 bytes overhead +- 24-bit message ID (16.7M message types) +- Incompatibility/compatibility flags for version negotiation +- Optional 13-byte signature for authentication +- Use for secure drone communication ## Framing Compatibility @@ -139,8 +225,15 @@ The architecture supports alternative frame formats. Planned implementations: |--------------|---|-----|------------|--------| | No Header (No Framing) | Yes | Yes | Yes | Yes | | Basic Frame Format | Yes | Yes | Yes | Yes | -| UBX | Planned | Planned | Planned | Planned | -| Mavlink v1 | Planned | Planned | Planned | Planned | -| Mavlink v2 | Planned | Planned | Planned | Planned | +| MSG ID Frames | Defined | Defined | Defined | Defined | +| Tiny Frames | Defined | Defined | Defined | Defined | +| Length-Prefixed | Defined | Defined | Defined | Defined | +| UBX | Defined | Defined | Defined | Defined | +| Mavlink v1 | Defined | Defined | Defined | Defined | +| Mavlink v2 | Defined | Defined | Defined | Defined | + +**Legend:** +- **Yes**: Fully implemented runtime support +- **Defined**: Frame format defined in proto, implementation pending All frame formats are binary compatible across languages. A frame created in Python can be parsed in C and vice versa. diff --git a/examples/frame_formats.proto b/examples/frame_formats.proto new file mode 100644 index 00000000..baf3fcd5 --- /dev/null +++ b/examples/frame_formats.proto @@ -0,0 +1,840 @@ +// Frame Format Definitions for struct-frame +// +// This file defines various message framing formats that can be used for +// reliable communication over serial links, network sockets, or any byte stream. +// +// Each frame format provides different tradeoffs between: +// - Overhead (header/footer bytes) +// - Error detection (CRC/checksum) +// - Message boundary detection +// - Length-prefixed vs fixed-length messages +// +// Use Case Summary: +// ================ +// NoFormat: Direct point-to-point trusted links, shared memory, nested protocols +// MsgIdFrame: Minimal framing with error detection +// MsgIdFrameNoCrc: Minimal framing for trusted links +// BasicFrame: Standard reliable communication with sync recovery +// BasicFrameNoCrc: Reduced overhead when CRC handled elsewhere +// TinyFrame: Low overhead for constrained environments +// TinyFrameNoCrc: Minimal overhead for trusted constrained links +// *WithLength variants: Variable length messages, streaming data +// UBX: u-blox GPS receiver compatibility +// MavlinkV1: ArduPilot/PX4 legacy drone communication +// MavlinkV2: Modern ArduPilot/PX4 drone communication with authentication + +package frame_formats; + +// ============================================================================ +// Frame Format Enumeration +// ============================================================================ + +// Enumeration of all supported frame format types. +// Used to identify and configure the framing protocol. +enum FrameFormatType { + // No framing - raw message bytes only + NO_FORMAT = 0; + + // Message ID + Message + 2-byte CRC + MSG_ID_FRAME = 1; + + // Message ID + Message (no CRC) + MSG_ID_FRAME_NO_CRC = 2; + + // 2-byte header + Message ID + Message + 2-byte CRC + BASIC_FRAME = 3; + + // 2-byte header + Message ID + Message (no CRC) + BASIC_FRAME_NO_CRC = 4; + + // 1-byte header + Message ID + Message + 2-byte CRC + TINY_FRAME = 5; + + // 1-byte header + Message ID + Message (no CRC) + TINY_FRAME_NO_CRC = 6; + + // Message ID + 1-byte length + Message + 2-byte CRC + MSG_ID_FRAME_LEN8 = 7; + + // Message ID + 1-byte length + Message (no CRC) + MSG_ID_FRAME_LEN8_NO_CRC = 8; + + // Message ID + 2-byte length + Message + 2-byte CRC + MSG_ID_FRAME_LEN16 = 9; + + // Message ID + 2-byte length + Message (no CRC) + MSG_ID_FRAME_LEN16_NO_CRC = 10; + + // 2-byte header + Message ID + 1-byte length + Message + 2-byte CRC + BASIC_FRAME_LEN8 = 11; + + // 2-byte header + Message ID + 1-byte length + Message (no CRC) + BASIC_FRAME_LEN8_NO_CRC = 12; + + // 2-byte header + Message ID + 2-byte length + Message + 2-byte CRC + BASIC_FRAME_LEN16 = 13; + + // 2-byte header + Message ID + 2-byte length + Message (no CRC) + BASIC_FRAME_LEN16_NO_CRC = 14; + + // 1-byte header + Message ID + 1-byte length + Message + 2-byte CRC + TINY_FRAME_LEN8 = 15; + + // 1-byte header + Message ID + 1-byte length + Message (no CRC) + TINY_FRAME_LEN8_NO_CRC = 16; + + // 1-byte header + Message ID + 2-byte length + Message + 2-byte CRC + TINY_FRAME_LEN16 = 17; + + // 1-byte header + Message ID + 2-byte length + Message (no CRC) + TINY_FRAME_LEN16_NO_CRC = 18; + + // u-blox UBX protocol format + UBX = 19; + + // MAVLink v1 protocol format + MAVLINK_V1 = 20; + + // MAVLink v2 protocol format + MAVLINK_V2 = 21; +} + +// ============================================================================ +// NO FORMAT (Raw Message) +// ============================================================================ +// +// Format: [MSG] +// +// No framing at all - messages are sent as raw bytes with no header, footer, +// or checksum. Message boundaries must be determined by external means. +// +// Use Cases: +// - Direct function calls between components in same process +// - Shared memory communication between processes +// - When another protocol layer already provides framing +// - Testing and debugging message payloads +// - Maximum throughput when reliability is guaranteed +// +// Limitations: +// - No message boundary detection +// - No error detection or correction +// - Message type must be known externally +// - Cannot recover from lost bytes +// +// Header Length: 0 bytes +// Footer Length: 0 bytes +// Overhead: 0 bytes + +message NoFormat { + option msgid = 1; + + // Reserved byte for compatibility (not used in actual frame) + // NoFormat has no actual framing - this field is just for struct-frame compatibility + uint8 reserved = 1; +} + +// ============================================================================ +// MSG ID FRAME (Minimal with CRC) +// ============================================================================ +// +// Format: [MSG_ID (1 byte)] [MSG (N bytes)] [CRC (2 bytes)] +// +// Minimal framing with message identification and error detection. +// No start byte synchronization - relies on message length being known. +// +// Use Cases: +// - Point-to-point links where framing is synchronized +// - Protocol layers that already handle synchronization +// - Low overhead requirements with error detection +// - Applications where message size is fixed and known +// +// Limitations: +// - No automatic synchronization recovery +// - Requires known message sizes +// - Cannot detect lost start of frame +// +// Header Length: 1 byte (MSG_ID) +// Footer Length: 2 bytes (Fletcher-16 CRC) +// Overhead: 3 bytes total + +message MsgIdFrame { + option msgid = 2; + + // Message identifier (0-255) + uint8 msg_id = 1; + + // Fletcher-16 checksum byte 1 + uint8 crc_byte1 = 2; + + // Fletcher-16 checksum byte 2 + uint8 crc_byte2 = 3; +} + +// ============================================================================ +// MSG ID FRAME NO CRC +// ============================================================================ +// +// Format: [MSG_ID (1 byte)] [MSG (N bytes)] +// +// Minimal framing with message identification but no error checking. +// For use on trusted links or when CRC is handled at another layer. +// +// Use Cases: +// - Trusted point-to-point connections +// - When transport layer provides error checking (TCP, ECC memory) +// - Maximum efficiency when corruption is not a concern +// - Debug/development environments +// +// Limitations: +// - No error detection +// - No synchronization support +// - Corrupted messages will not be detected +// +// Header Length: 1 byte (MSG_ID) +// Footer Length: 0 bytes +// Overhead: 1 byte total + +message MsgIdFrameNoCrc { + option msgid = 3; + + // Message identifier (0-255) + uint8 msg_id = 1; +} + +// ============================================================================ +// BASIC FRAME (Standard with Sync and CRC) +// ============================================================================ +// +// Format: [START (1 byte)] [MSG_ID (1 byte)] [MSG (N bytes)] [CRC (2 bytes)] +// +// Standard frame format with start byte for synchronization and CRC for +// error detection. Allows recovery from corrupted frames. +// +// Default start byte: 0x90 +// +// Use Cases: +// - Serial communication (UART, RS-232, RS-485) +// - Wireless links (LoRa, Bluetooth, WiFi) +// - Any byte stream where synchronization is needed +// - General purpose reliable messaging +// +// Advantages: +// - Automatic frame synchronization +// - Recovery from corruption/lost bytes +// - Error detection for data integrity +// - Well-balanced overhead vs reliability +// +// Header Length: 2 bytes (START + MSG_ID) +// Footer Length: 2 bytes (Fletcher-16 CRC) +// Overhead: 4 bytes total + +message BasicFrame { + option msgid = 4; + + // Synchronization start byte (default 0x90) + uint8 start_byte = 1; + + // Message identifier (0-255) + uint8 msg_id = 2; + + // Fletcher-16 checksum byte 1 + uint8 crc_byte1 = 3; + + // Fletcher-16 checksum byte 2 + uint8 crc_byte2 = 4; +} + +// ============================================================================ +// BASIC FRAME NO CRC +// ============================================================================ +// +// Format: [START (1 byte)] [MSG_ID (1 byte)] [MSG (N bytes)] +// +// Frame format with synchronization but no error checking. +// For use when error detection is handled elsewhere. +// +// Use Cases: +// - Links with hardware error correction +// - When performance is critical and errors are rare +// - Layered protocols where outer layer has CRC +// - Development/debugging scenarios +// +// Header Length: 2 bytes (START + MSG_ID) +// Footer Length: 0 bytes +// Overhead: 2 bytes total + +message BasicFrameNoCrc { + option msgid = 5; + + // Synchronization start byte (default 0x90) + uint8 start_byte = 1; + + // Message identifier (0-255) + uint8 msg_id = 2; +} + +// ============================================================================ +// TINY FRAME (Minimal Header with CRC) +// ============================================================================ +// +// Format: [START (1 byte)] [MSG_ID (1 byte)] [MSG (N bytes)] [CRC (2 bytes)] +// +// Compact frame format using single start byte combined with message ID. +// Provides synchronization and error detection with minimal overhead. +// +// Note: In this implementation, TINY_FRAME is structurally identical to +// BASIC_FRAME but may use a different start byte scheme in future versions. +// +// Use Cases: +// - Bandwidth-constrained links +// - Battery-powered devices +// - High message rate applications +// - Embedded systems with limited memory +// +// Header Length: 1 byte (combined START/MSG_ID or START alone) +// Footer Length: 2 bytes (Fletcher-16 CRC) +// Overhead: 3 bytes total + +message TinyFrame { + option msgid = 6; + + // Start byte / sync marker + uint8 start_byte = 1; + + // Message identifier (0-255) + uint8 msg_id = 2; + + // Fletcher-16 checksum byte 1 + uint8 crc_byte1 = 3; + + // Fletcher-16 checksum byte 2 + uint8 crc_byte2 = 4; +} + +// ============================================================================ +// TINY FRAME NO CRC +// ============================================================================ +// +// Format: [START (1 byte)] [MSG_ID (1 byte)] [MSG (N bytes)] +// +// Minimal frame format with sync but no error detection. +// Absolute minimum overhead for reliable links. +// +// Use Cases: +// - Point-to-point wired connections +// - Time-critical applications +// - When payload includes its own integrity check +// - Extremely constrained bandwidth scenarios +// +// Header Length: 1 byte (combined START/MSG_ID or START alone) +// Footer Length: 0 bytes +// Overhead: 1 byte total + +message TinyFrameNoCrc { + option msgid = 7; + + // Start byte / sync marker + uint8 start_byte = 1; + + // Message identifier (0-255) + uint8 msg_id = 2; +} + +// ============================================================================ +// LENGTH-PREFIXED VARIANTS (8-bit length field) +// ============================================================================ +// +// These variants add a 1-byte length field after the header. +// Supports message payloads up to 255 bytes. +// Enables variable-length messages without predefined size tables. + +// Format: [MSG_ID (1 byte)] [LEN (1 byte)] [MSG (LEN bytes)] [CRC (2 bytes)] +// +// Use Cases: +// - Variable-length messages +// - Dynamic payload sizes +// - Streaming data with packet boundaries +// - When message size table is not available at receiver +// +// Header Length: 2 bytes (MSG_ID + LEN) +// Footer Length: 2 bytes (Fletcher-16 CRC) +// Overhead: 4 bytes total + +message MsgIdFrameLen8 { + option msgid = 8; + + // Message identifier (0-255) + uint8 msg_id = 1; + + // Payload length (0-255 bytes) + uint8 length = 2; + + // Fletcher-16 checksum byte 1 + uint8 crc_byte1 = 3; + + // Fletcher-16 checksum byte 2 + uint8 crc_byte2 = 4; +} + +// Format: [MSG_ID (1 byte)] [LEN (1 byte)] [MSG (LEN bytes)] + +message MsgIdFrameLen8NoCrc { + option msgid = 9; + + // Message identifier (0-255) + uint8 msg_id = 1; + + // Payload length (0-255 bytes) + uint8 length = 2; +} + +// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (1 byte)] [MSG (LEN bytes)] [CRC (2 bytes)] +// +// Header Length: 3 bytes (START + MSG_ID + LEN) +// Footer Length: 2 bytes (Fletcher-16 CRC) +// Overhead: 5 bytes total + +message BasicFrameLen8 { + option msgid = 10; + + // Synchronization start byte + uint8 start_byte = 1; + + // Message identifier (0-255) + uint8 msg_id = 2; + + // Payload length (0-255 bytes) + uint8 length = 3; + + // Fletcher-16 checksum byte 1 + uint8 crc_byte1 = 4; + + // Fletcher-16 checksum byte 2 + uint8 crc_byte2 = 5; +} + +// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (1 byte)] [MSG (LEN bytes)] + +message BasicFrameLen8NoCrc { + option msgid = 11; + + // Synchronization start byte + uint8 start_byte = 1; + + // Message identifier (0-255) + uint8 msg_id = 2; + + // Payload length (0-255 bytes) + uint8 length = 3; +} + +// Format: [START (1 byte)] [LEN (1 byte)] [MSG_ID (1 byte)] [MSG (LEN bytes)] [CRC (2 bytes)] +// +// Header Length: 2 bytes (START + LEN) +// Footer Length: 2 bytes (Fletcher-16 CRC) +// Overhead: 4 bytes total + +message TinyFrameLen8 { + option msgid = 12; + + // Start byte / sync marker + uint8 start_byte = 1; + + // Message identifier (0-255) + uint8 msg_id = 2; + + // Payload length (0-255 bytes) + uint8 length = 3; + + // Fletcher-16 checksum byte 1 + uint8 crc_byte1 = 4; + + // Fletcher-16 checksum byte 2 + uint8 crc_byte2 = 5; +} + +// Format: [START (1 byte)] [LEN (1 byte)] [MSG_ID (1 byte)] [MSG (LEN bytes)] + +message TinyFrameLen8NoCrc { + option msgid = 13; + + // Start byte / sync marker + uint8 start_byte = 1; + + // Message identifier (0-255) + uint8 msg_id = 2; + + // Payload length (0-255 bytes) + uint8 length = 3; +} + +// ============================================================================ +// LENGTH-PREFIXED VARIANTS (16-bit length field) +// ============================================================================ +// +// These variants add a 2-byte length field after the header. +// Supports message payloads up to 65535 bytes. +// For large data transfers and streaming applications. + +// Format: [MSG_ID (1 byte)] [LEN (2 bytes)] [MSG (LEN bytes)] [CRC (2 bytes)] +// +// Use Cases: +// - Large payload messages (up to 64KB) +// - File transfer protocols +// - Firmware update protocols +// - Bulk data streaming +// +// Header Length: 3 bytes (MSG_ID + LEN16) +// Footer Length: 2 bytes (Fletcher-16 CRC) +// Overhead: 5 bytes total + +message MsgIdFrameLen16 { + option msgid = 14; + + // Message identifier (0-255) + uint8 msg_id = 1; + + // Payload length (0-65535 bytes), little-endian + uint16 length = 2; + + // Fletcher-16 checksum byte 1 + uint8 crc_byte1 = 3; + + // Fletcher-16 checksum byte 2 + uint8 crc_byte2 = 4; +} + +// Format: [MSG_ID (1 byte)] [LEN (2 bytes)] [MSG (LEN bytes)] + +message MsgIdFrameLen16NoCrc { + option msgid = 15; + + // Message identifier (0-255) + uint8 msg_id = 1; + + // Payload length (0-65535 bytes), little-endian + uint16 length = 2; +} + +// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (2 bytes)] [MSG (LEN bytes)] [CRC (2 bytes)] +// +// Header Length: 4 bytes (START + MSG_ID + LEN16) +// Footer Length: 2 bytes (Fletcher-16 CRC) +// Overhead: 6 bytes total + +message BasicFrameLen16 { + option msgid = 16; + + // Synchronization start byte + uint8 start_byte = 1; + + // Message identifier (0-255) + uint8 msg_id = 2; + + // Payload length (0-65535 bytes), little-endian + uint16 length = 3; + + // Fletcher-16 checksum byte 1 + uint8 crc_byte1 = 4; + + // Fletcher-16 checksum byte 2 + uint8 crc_byte2 = 5; +} + +// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (2 bytes)] [MSG (LEN bytes)] + +message BasicFrameLen16NoCrc { + option msgid = 17; + + // Synchronization start byte + uint8 start_byte = 1; + + // Message identifier (0-255) + uint8 msg_id = 2; + + // Payload length (0-65535 bytes), little-endian + uint16 length = 3; +} + +// Format: [START (1 byte)] [LEN (2 bytes)] [MSG_ID (1 byte)] [MSG (LEN bytes)] [CRC (2 bytes)] +// +// Header Length: 3 bytes (START + LEN16) +// Footer Length: 2 bytes (Fletcher-16 CRC) +// Overhead: 5 bytes total + +message TinyFrameLen16 { + option msgid = 18; + + // Start byte / sync marker + uint8 start_byte = 1; + + // Message identifier (0-255) + uint8 msg_id = 2; + + // Payload length (0-65535 bytes), little-endian + uint16 length = 3; + + // Fletcher-16 checksum byte 1 + uint8 crc_byte1 = 4; + + // Fletcher-16 checksum byte 2 + uint8 crc_byte2 = 5; +} + +// Format: [START (1 byte)] [LEN (2 bytes)] [MSG_ID (1 byte)] [MSG (LEN bytes)] + +message TinyFrameLen16NoCrc { + option msgid = 19; + + // Start byte / sync marker + uint8 start_byte = 1; + + // Message identifier (0-255) + uint8 msg_id = 2; + + // Payload length (0-65535 bytes), little-endian + uint16 length = 3; +} + +// ============================================================================ +// UBX FRAME FORMAT +// ============================================================================ +// +// u-blox proprietary binary protocol used by GPS/GNSS receivers. +// +// Format: [SYNC1 (1 byte)] [SYNC2 (1 byte)] [CLASS (1 byte)] [ID (1 byte)] +// [LEN_LO (1 byte)] [LEN_HI (1 byte)] [PAYLOAD (LEN bytes)] +// [CK_A (1 byte)] [CK_B (1 byte)] +// +// SYNC1: 0xB5 (μ in ISO 8859-1) +// SYNC2: 0x62 ('b') +// CLASS: Message class +// ID: Message ID within class +// LEN: 16-bit payload length, little-endian +// PAYLOAD: Variable length message data +// CK_A, CK_B: Fletcher-8 checksum over CLASS, ID, LEN, and PAYLOAD +// +// Use Cases: +// - u-blox GPS receiver communication +// - GNSS data logging and configuration +// - Position/navigation applications +// - Timing and synchronization systems +// +// Header Length: 6 bytes (SYNC1 + SYNC2 + CLASS + ID + LEN) +// Footer Length: 2 bytes (Fletcher-8 checksum) +// Overhead: 8 bytes total +// Max Payload: 65535 bytes + +message UbxFrame { + option msgid = 20; + + // Sync byte 1 (always 0xB5) + uint8 sync1 = 1; + + // Sync byte 2 (always 0x62) + uint8 sync2 = 2; + + // Message class (e.g., NAV=0x01, RXM=0x02, INF=0x04, ACK=0x05, etc.) + uint8 msg_class = 3; + + // Message ID within class + uint8 msg_id = 4; + + // Payload length low byte (little-endian) + uint8 length_lo = 5; + + // Payload length high byte (little-endian) + uint8 length_hi = 6; + + // Fletcher-8 checksum A + uint8 ck_a = 7; + + // Fletcher-8 checksum B + uint8 ck_b = 8; +} + +// ============================================================================ +// MAVLINK V1 FRAME FORMAT +// ============================================================================ +// +// MAVLink Micro Air Vehicle Link protocol version 1.0 +// Used by ArduPilot, PX4, and other drone/UAV flight controllers. +// +// Format: [STX (1 byte)] [LEN (1 byte)] [SEQ (1 byte)] [SYS (1 byte)] +// [COMP (1 byte)] [MSG (1 byte)] [PAYLOAD (LEN bytes)] [CRC (2 bytes)] +// +// STX: Start of frame (0xFE) +// LEN: Payload length (0-255) +// SEQ: Sequence number (0-255, wrapping) +// SYS: System ID (1-255) +// COMP: Component ID (1-255) +// MSG: Message ID (0-255) +// PAYLOAD: Message data +// CRC: X.25 CRC-16 checksum +// +// Use Cases: +// - Drone/UAV communication +// - Ground control station links +// - Autopilot telemetry +// - MAVLink 1.0 compatible devices +// +// Header Length: 6 bytes (STX + LEN + SEQ + SYS + COMP + MSG) +// Footer Length: 2 bytes (CRC-16) +// Overhead: 8 bytes total +// Max Payload: 255 bytes + +message MavlinkV1Frame { + option msgid = 21; + + // Start of frame marker (always 0xFE) + uint8 stx = 1; + + // Payload length (0-255 bytes) + uint8 length = 2; + + // Packet sequence number (0-255, wrapping counter) + uint8 sequence = 3; + + // System ID (identifies the vehicle/GCS, 1-255) + uint8 system_id = 4; + + // Component ID (identifies component on system, 1-255) + uint8 component_id = 5; + + // Message ID (0-255) + uint8 msg_id = 6; + + // CRC-16/X.25 checksum low byte + uint8 crc_lo = 7; + + // CRC-16/X.25 checksum high byte + uint8 crc_hi = 8; +} + +// ============================================================================ +// MAVLINK V2 FRAME FORMAT +// ============================================================================ +// +// MAVLink Micro Air Vehicle Link protocol version 2.0 +// Extended version with more message IDs and optional message signing. +// +// Format: [STX (1 byte)] [LEN (1 byte)] [INCOMPAT (1 byte)] [COMPAT (1 byte)] +// [SEQ (1 byte)] [SYS (1 byte)] [COMP (1 byte)] [MSG_ID (3 bytes)] +// [PAYLOAD (LEN bytes)] [CRC (2 bytes)] [SIGNATURE (13 bytes, optional)] +// +// STX: Start of frame (0xFD) +// LEN: Payload length (0-255) +// INCOMPAT: Incompatibility flags (must understand to parse) +// COMPAT: Compatibility flags (can ignore if unknown) +// SEQ: Sequence number (0-255) +// SYS: System ID (1-255) +// COMP: Component ID (1-255) +// MSG_ID: 24-bit message ID (0-16777215) +// PAYLOAD: Message data +// CRC: CRC-16 checksum +// SIGNATURE: Optional 13-byte message signature for authentication +// +// Incompatibility Flags: +// 0x01 - MAVLINK_IFLAG_SIGNED - Message is signed +// +// Use Cases: +// - Modern drone/UAV communication +// - Extended message ID space (16.7M messages) +// - Authenticated communication +// - High-security applications +// +// Header Length: 10 bytes (STX + LEN + INCOMPAT + COMPAT + SEQ + SYS + COMP + MSG_ID) +// Footer Length: 2 bytes CRC + optional 13 bytes signature +// Overhead: 12-25 bytes total +// Max Payload: 255 bytes + +message MavlinkV2Frame { + option msgid = 22; + + // Start of frame marker (always 0xFD) + uint8 stx = 1; + + // Payload length (0-255 bytes) + uint8 length = 2; + + // Incompatibility flags (must be understood to parse message) + // Bit 0 (0x01): MAVLINK_IFLAG_SIGNED - message is signed + uint8 incompat_flags = 3; + + // Compatibility flags (can be ignored if unknown) + uint8 compat_flags = 4; + + // Packet sequence number (0-255, wrapping counter) + uint8 sequence = 5; + + // System ID (identifies the vehicle/GCS, 1-255) + uint8 system_id = 6; + + // Component ID (identifies component on system, 1-255) + uint8 component_id = 7; + + // 24-bit message ID, byte 0 (low byte) + uint8 msg_id_0 = 8; + + // 24-bit message ID, byte 1 (middle byte) + uint8 msg_id_1 = 9; + + // 24-bit message ID, byte 2 (high byte) + uint8 msg_id_2 = 10; + + // CRC-16 checksum low byte + uint8 crc_lo = 11; + + // CRC-16 checksum high byte + uint8 crc_hi = 12; +} + +// MAVLink v2 signature for authenticated messages +// Appended after CRC when MAVLINK_IFLAG_SIGNED is set +message MavlinkV2Signature { + option msgid = 23; + + // Link ID (identifies the communication link) + uint8 link_id = 1; + + // Timestamp (48-bit Unix epoch in 10us units, bytes 0-5) + uint8 timestamp_0 = 2; + uint8 timestamp_1 = 3; + uint8 timestamp_2 = 4; + uint8 timestamp_3 = 5; + uint8 timestamp_4 = 6; + uint8 timestamp_5 = 7; + + // SHA-256 signature (first 6 bytes) + uint8 signature_0 = 8; + uint8 signature_1 = 9; + uint8 signature_2 = 10; + uint8 signature_3 = 11; + uint8 signature_4 = 12; + uint8 signature_5 = 13; +} + +// ============================================================================ +// FRAME FORMAT CONFIGURATION +// ============================================================================ +// +// Configuration message to select and configure frame format at runtime + +message FrameFormatConfig { + option msgid = 24; + + // Selected frame format type + FrameFormatType format_type = 1; + + // Start byte(s) for formats that use them (0x90 default) + uint8 start_byte = 2; + + // Secondary start byte for UBX and similar (0x62 default for UBX) + uint8 start_byte_2 = 3; + + // Enable CRC checking (for formats that support optional CRC) + bool crc_enabled = 4; + + // Enable message signing (MAVLink v2 only) + bool signing_enabled = 5; +} From d91f8dd60e319a1f0c2c218792d2708a53413b99 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Nov 2025 19:00:24 +0000 Subject: [PATCH 3/7] Fix frame format documentation inconsistencies Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com> --- docs/framing.md | 4 ++-- examples/frame_formats.proto | 42 ++++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/docs/framing.md b/docs/framing.md index 557d1e83..c44f2ed4 100644 --- a/docs/framing.md +++ b/docs/framing.md @@ -20,8 +20,8 @@ All supported frame formats are defined in [`examples/frame_formats.proto`](../e | MsgIdFrameNoCrc | 1 | 0 | None | Minimal framing, trusted link | | BasicFrame | 2 | 2 | None | Standard reliable communication | | BasicFrameNoCrc | 2 | 0 | None | Sync recovery, no CRC | -| TinyFrame | 1 | 2 | None | Low overhead with CRC | -| TinyFrameNoCrc | 1 | 0 | None | Minimal overhead | +| TinyFrame | 2 | 2 | None | Constrained environments | +| TinyFrameNoCrc | 2 | 0 | None | Minimal overhead | | *Len8 variants | +1 | same | 8-bit | Variable length up to 255 bytes | | *Len16 variants | +2 | same | 16-bit | Variable length up to 64KB | | UBX | 6 | 2 | 16-bit | u-blox GPS compatibility | diff --git a/examples/frame_formats.proto b/examples/frame_formats.proto index baf3fcd5..11b75eaa 100644 --- a/examples/frame_formats.proto +++ b/examples/frame_formats.proto @@ -279,11 +279,9 @@ message BasicFrameNoCrc { // // Format: [START (1 byte)] [MSG_ID (1 byte)] [MSG (N bytes)] [CRC (2 bytes)] // -// Compact frame format using single start byte combined with message ID. -// Provides synchronization and error detection with minimal overhead. -// -// Note: In this implementation, TINY_FRAME is structurally identical to -// BASIC_FRAME but may use a different start byte scheme in future versions. +// Compact frame format with synchronization and error detection. +// Structurally similar to BasicFrame but intended for constrained environments +// where a smaller start byte vocabulary may be used. // // Use Cases: // - Bandwidth-constrained links @@ -291,9 +289,9 @@ message BasicFrameNoCrc { // - High message rate applications // - Embedded systems with limited memory // -// Header Length: 1 byte (combined START/MSG_ID or START alone) +// Header Length: 2 bytes (START + MSG_ID) // Footer Length: 2 bytes (Fletcher-16 CRC) -// Overhead: 3 bytes total +// Overhead: 4 bytes total message TinyFrame { option msgid = 6; @@ -318,7 +316,7 @@ message TinyFrame { // Format: [START (1 byte)] [MSG_ID (1 byte)] [MSG (N bytes)] // // Minimal frame format with sync but no error detection. -// Absolute minimum overhead for reliable links. +// Minimum overhead for reliable links with synchronization support. // // Use Cases: // - Point-to-point wired connections @@ -326,9 +324,9 @@ message TinyFrame { // - When payload includes its own integrity check // - Extremely constrained bandwidth scenarios // -// Header Length: 1 byte (combined START/MSG_ID or START alone) +// Header Length: 2 bytes (START + MSG_ID) // Footer Length: 0 bytes -// Overhead: 1 byte total +// Overhead: 2 bytes total message TinyFrameNoCrc { option msgid = 7; @@ -428,11 +426,11 @@ message BasicFrameLen8NoCrc { uint8 length = 3; } -// Format: [START (1 byte)] [LEN (1 byte)] [MSG_ID (1 byte)] [MSG (LEN bytes)] [CRC (2 bytes)] +// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (1 byte)] [MSG (LEN bytes)] [CRC (2 bytes)] // -// Header Length: 2 bytes (START + LEN) +// Header Length: 3 bytes (START + MSG_ID + LEN) // Footer Length: 2 bytes (Fletcher-16 CRC) -// Overhead: 4 bytes total +// Overhead: 5 bytes total message TinyFrameLen8 { option msgid = 12; @@ -453,7 +451,11 @@ message TinyFrameLen8 { uint8 crc_byte2 = 5; } -// Format: [START (1 byte)] [LEN (1 byte)] [MSG_ID (1 byte)] [MSG (LEN bytes)] +// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (1 byte)] [MSG (LEN bytes)] +// +// Header Length: 3 bytes (START + MSG_ID + LEN) +// Footer Length: 0 bytes +// Overhead: 3 bytes total message TinyFrameLen8NoCrc { option msgid = 13; @@ -556,11 +558,11 @@ message BasicFrameLen16NoCrc { uint16 length = 3; } -// Format: [START (1 byte)] [LEN (2 bytes)] [MSG_ID (1 byte)] [MSG (LEN bytes)] [CRC (2 bytes)] +// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (2 bytes)] [MSG (LEN bytes)] [CRC (2 bytes)] // -// Header Length: 3 bytes (START + LEN16) +// Header Length: 4 bytes (START + MSG_ID + LEN16) // Footer Length: 2 bytes (Fletcher-16 CRC) -// Overhead: 5 bytes total +// Overhead: 6 bytes total message TinyFrameLen16 { option msgid = 18; @@ -581,7 +583,11 @@ message TinyFrameLen16 { uint8 crc_byte2 = 5; } -// Format: [START (1 byte)] [LEN (2 bytes)] [MSG_ID (1 byte)] [MSG (LEN bytes)] +// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (2 bytes)] [MSG (LEN bytes)] +// +// Header Length: 4 bytes (START + MSG_ID + LEN16) +// Footer Length: 0 bytes +// Overhead: 4 bytes total message TinyFrameLen16NoCrc { option msgid = 19; From 3fd035fba9930a9ba20fa393d09e87fe36c38f60 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Nov 2025 19:13:44 +0000 Subject: [PATCH 4/7] Address PR feedback: simplify proto, add BasicMessage, improve table format Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com> --- docs/framing.md | 56 ++- examples/frame_formats.proto | 770 +++++------------------------------ 2 files changed, 151 insertions(+), 675 deletions(-) diff --git a/docs/framing.md b/docs/framing.md index c44f2ed4..1430f9e9 100644 --- a/docs/framing.md +++ b/docs/framing.md @@ -7,26 +7,40 @@ Framing wraps messages with headers and checksums so receivers can identify mess All supported frame formats are defined in [`examples/frame_formats.proto`](../examples/frame_formats.proto). This file provides: - Protocol Buffer definitions for each frame format -- Detailed documentation of use cases and tradeoffs - Enumeration of all frame format types - Configuration message for runtime format selection -## Frame Format Overview - -| Format | Header | Footer | Length Field | Use Case | -|--------|--------|--------|--------------|----------| -| NoFormat | 0 | 0 | None | Trusted links, nested protocols | -| MsgIdFrame | 1 | 2 | None | Minimal framing with CRC | -| MsgIdFrameNoCrc | 1 | 0 | None | Minimal framing, trusted link | -| BasicFrame | 2 | 2 | None | Standard reliable communication | -| BasicFrameNoCrc | 2 | 0 | None | Sync recovery, no CRC | -| TinyFrame | 2 | 2 | None | Constrained environments | -| TinyFrameNoCrc | 2 | 0 | None | Minimal overhead | -| *Len8 variants | +1 | same | 8-bit | Variable length up to 255 bytes | -| *Len16 variants | +2 | same | 16-bit | Variable length up to 64KB | -| UBX | 6 | 2 | 16-bit | u-blox GPS compatibility | -| MavlinkV1 | 6 | 2 | 8-bit | Legacy drone communication | -| MavlinkV2 | 10 | 2-15 | 8-bit | Modern drone communication | +## Recommended Frame Formats + +| Format | Preamble | Header | CRC | Length | Total Overhead | Use Case | +|--------|----------|--------|-----|--------|----------------|----------| +| NoFormat | 0 | 0 | 0 | None | 0 | Trusted links, nested protocols | +| BasicFrame | 1 | 2 | 2 | None | 4 | Standard reliable communication | +| BasicFrameLen8 | 1 | 3 | 2 | 8-bit | 5 | Variable length messages | + +## All Frame Formats + +| Format | Preamble | Header | CRC | Length | Total Overhead | Use Case | +|--------|----------|--------|-----|--------|----------------|----------| +| NoFormat | 0 | 0 | 0 | None | 0 | Trusted links, nested protocols | +| MsgIdFrame | 0 | 1 | 2 | None | 3 | Minimal framing with CRC | +| MsgIdFrameNoCrc | 0 | 1 | 0 | None | 1 | Minimal framing, trusted link | +| MsgIdFrameLen8 | 0 | 2 | 2 | 8-bit | 4 | Variable length, minimal | +| MsgIdFrameLen8NoCrc | 0 | 2 | 0 | 8-bit | 2 | Variable length, no CRC | +| MsgIdFrameLen16 | 0 | 3 | 2 | 16-bit | 5 | Large payloads, minimal | +| MsgIdFrameLen16NoCrc | 0 | 3 | 0 | 16-bit | 3 | Large payloads, no CRC | +| BasicFrame | 1 | 2 | 2 | None | 4 | Standard reliable communication | +| BasicFrameNoCrc | 1 | 2 | 0 | None | 2 | Sync recovery, no CRC | +| BasicFrameLen8 | 1 | 3 | 2 | 8-bit | 5 | Variable length messages | +| BasicFrameLen8NoCrc | 1 | 3 | 0 | 8-bit | 3 | Variable length, no CRC | +| BasicFrameLen16 | 1 | 4 | 2 | 16-bit | 6 | Large payload messages | +| BasicFrameLen16NoCrc | 1 | 4 | 0 | 16-bit | 4 | Large payloads, no CRC | +| TinyFrame | 1 | 2 | 2 | None | 4 | Constrained environments | +| TinyFrameNoCrc | 1 | 2 | 0 | None | 2 | Minimal overhead | +| TinyFrameLen8 | 1 | 3 | 2 | 8-bit | 5 | Variable length, constrained | +| TinyFrameLen8NoCrc | 1 | 3 | 0 | 8-bit | 3 | Variable, minimal overhead | +| TinyFrameLen16 | 1 | 4 | 2 | 16-bit | 6 | Large payloads, constrained | +| TinyFrameLen16NoCrc | 1 | 4 | 0 | 16-bit | 4 | Large, minimal overhead | ## No Frame Format @@ -176,7 +190,13 @@ for each byte in (message_id + payload): checksum = [sum1, sum2] ``` -## Industry Standard Protocols +## Third Party Protocols + +| Format | Preamble | Header | CRC | Length | Total Overhead | Use Case | +|--------|----------|--------|-----|--------|----------------|----------| +| UBX | 2 | 6 | 2 | 16-bit | 8 | u-blox GPS compatibility | +| MavlinkV1 | 1 | 6 | 2 | 8-bit | 8 | Legacy drone communication | +| MavlinkV2 | 1 | 10 | 2-15 | 8-bit | 12-25 | Modern drone communication | ### UBX Format diff --git a/examples/frame_formats.proto b/examples/frame_formats.proto index 11b75eaa..dc306f9f 100644 --- a/examples/frame_formats.proto +++ b/examples/frame_formats.proto @@ -1,817 +1,285 @@ // Frame Format Definitions for struct-frame -// -// This file defines various message framing formats that can be used for -// reliable communication over serial links, network sockets, or any byte stream. -// -// Each frame format provides different tradeoffs between: -// - Overhead (header/footer bytes) -// - Error detection (CRC/checksum) -// - Message boundary detection -// - Length-prefixed vs fixed-length messages -// -// Use Case Summary: -// ================ -// NoFormat: Direct point-to-point trusted links, shared memory, nested protocols -// MsgIdFrame: Minimal framing with error detection -// MsgIdFrameNoCrc: Minimal framing for trusted links -// BasicFrame: Standard reliable communication with sync recovery -// BasicFrameNoCrc: Reduced overhead when CRC handled elsewhere -// TinyFrame: Low overhead for constrained environments -// TinyFrameNoCrc: Minimal overhead for trusted constrained links -// *WithLength variants: Variable length messages, streaming data -// UBX: u-blox GPS receiver compatibility -// MavlinkV1: ArduPilot/PX4 legacy drone communication -// MavlinkV2: Modern ArduPilot/PX4 drone communication with authentication +// Defines message framing formats for communication over serial, network, or byte streams. package frame_formats; -// ============================================================================ -// Frame Format Enumeration -// ============================================================================ - -// Enumeration of all supported frame format types. -// Used to identify and configure the framing protocol. +// Frame format type enumeration enum FrameFormatType { - // No framing - raw message bytes only NO_FORMAT = 0; - - // Message ID + Message + 2-byte CRC MSG_ID_FRAME = 1; - - // Message ID + Message (no CRC) MSG_ID_FRAME_NO_CRC = 2; - - // 2-byte header + Message ID + Message + 2-byte CRC BASIC_FRAME = 3; - - // 2-byte header + Message ID + Message (no CRC) BASIC_FRAME_NO_CRC = 4; - - // 1-byte header + Message ID + Message + 2-byte CRC TINY_FRAME = 5; - - // 1-byte header + Message ID + Message (no CRC) TINY_FRAME_NO_CRC = 6; - - // Message ID + 1-byte length + Message + 2-byte CRC MSG_ID_FRAME_LEN8 = 7; - - // Message ID + 1-byte length + Message (no CRC) MSG_ID_FRAME_LEN8_NO_CRC = 8; - - // Message ID + 2-byte length + Message + 2-byte CRC MSG_ID_FRAME_LEN16 = 9; - - // Message ID + 2-byte length + Message (no CRC) MSG_ID_FRAME_LEN16_NO_CRC = 10; - - // 2-byte header + Message ID + 1-byte length + Message + 2-byte CRC BASIC_FRAME_LEN8 = 11; - - // 2-byte header + Message ID + 1-byte length + Message (no CRC) BASIC_FRAME_LEN8_NO_CRC = 12; - - // 2-byte header + Message ID + 2-byte length + Message + 2-byte CRC BASIC_FRAME_LEN16 = 13; - - // 2-byte header + Message ID + 2-byte length + Message (no CRC) BASIC_FRAME_LEN16_NO_CRC = 14; - - // 1-byte header + Message ID + 1-byte length + Message + 2-byte CRC TINY_FRAME_LEN8 = 15; - - // 1-byte header + Message ID + 1-byte length + Message (no CRC) TINY_FRAME_LEN8_NO_CRC = 16; - - // 1-byte header + Message ID + 2-byte length + Message + 2-byte CRC TINY_FRAME_LEN16 = 17; - - // 1-byte header + Message ID + 2-byte length + Message (no CRC) TINY_FRAME_LEN16_NO_CRC = 18; - - // u-blox UBX protocol format UBX = 19; - - // MAVLink v1 protocol format MAVLINK_V1 = 20; - - // MAVLink v2 protocol format MAVLINK_V2 = 21; } +// Basic message payload included in all frame formats +message BasicMessage { + uint8 msg_id = 1; +} + // ============================================================================ -// NO FORMAT (Raw Message) -// ============================================================================ -// +// NO FORMAT - Raw message, no framing // Format: [MSG] -// -// No framing at all - messages are sent as raw bytes with no header, footer, -// or checksum. Message boundaries must be determined by external means. -// -// Use Cases: -// - Direct function calls between components in same process -// - Shared memory communication between processes -// - When another protocol layer already provides framing -// - Testing and debugging message payloads -// - Maximum throughput when reliability is guaranteed -// -// Limitations: -// - No message boundary detection -// - No error detection or correction -// - Message type must be known externally -// - Cannot recover from lost bytes -// -// Header Length: 0 bytes -// Footer Length: 0 bytes // Overhead: 0 bytes - message NoFormat { - option msgid = 1; - - // Reserved byte for compatibility (not used in actual frame) - // NoFormat has no actual framing - this field is just for struct-frame compatibility - uint8 reserved = 1; + BasicMessage payload = 1; } // ============================================================================ -// MSG ID FRAME (Minimal with CRC) -// ============================================================================ -// -// Format: [MSG_ID (1 byte)] [MSG (N bytes)] [CRC (2 bytes)] -// -// Minimal framing with message identification and error detection. -// No start byte synchronization - relies on message length being known. -// -// Use Cases: -// - Point-to-point links where framing is synchronized -// - Protocol layers that already handle synchronization -// - Low overhead requirements with error detection -// - Applications where message size is fixed and known -// -// Limitations: -// - No automatic synchronization recovery -// - Requires known message sizes -// - Cannot detect lost start of frame -// -// Header Length: 1 byte (MSG_ID) -// Footer Length: 2 bytes (Fletcher-16 CRC) -// Overhead: 3 bytes total - +// MSG ID FRAME - Minimal framing with CRC +// Format: [MSG_ID] [MSG] [CRC1] [CRC2] +// Overhead: 3 bytes message MsgIdFrame { - option msgid = 2; - - // Message identifier (0-255) - uint8 msg_id = 1; - - // Fletcher-16 checksum byte 1 + BasicMessage payload = 1; uint8 crc_byte1 = 2; - - // Fletcher-16 checksum byte 2 uint8 crc_byte2 = 3; } -// ============================================================================ // MSG ID FRAME NO CRC -// ============================================================================ -// -// Format: [MSG_ID (1 byte)] [MSG (N bytes)] -// -// Minimal framing with message identification but no error checking. -// For use on trusted links or when CRC is handled at another layer. -// -// Use Cases: -// - Trusted point-to-point connections -// - When transport layer provides error checking (TCP, ECC memory) -// - Maximum efficiency when corruption is not a concern -// - Debug/development environments -// -// Limitations: -// - No error detection -// - No synchronization support -// - Corrupted messages will not be detected -// -// Header Length: 1 byte (MSG_ID) -// Footer Length: 0 bytes -// Overhead: 1 byte total - +// Format: [MSG_ID] [MSG] +// Overhead: 1 byte message MsgIdFrameNoCrc { - option msgid = 3; - - // Message identifier (0-255) - uint8 msg_id = 1; + BasicMessage payload = 1; } // ============================================================================ -// BASIC FRAME (Standard with Sync and CRC) -// ============================================================================ -// -// Format: [START (1 byte)] [MSG_ID (1 byte)] [MSG (N bytes)] [CRC (2 bytes)] -// -// Standard frame format with start byte for synchronization and CRC for -// error detection. Allows recovery from corrupted frames. -// -// Default start byte: 0x90 -// -// Use Cases: -// - Serial communication (UART, RS-232, RS-485) -// - Wireless links (LoRa, Bluetooth, WiFi) -// - Any byte stream where synchronization is needed -// - General purpose reliable messaging -// -// Advantages: -// - Automatic frame synchronization -// - Recovery from corruption/lost bytes -// - Error detection for data integrity -// - Well-balanced overhead vs reliability -// -// Header Length: 2 bytes (START + MSG_ID) -// Footer Length: 2 bytes (Fletcher-16 CRC) -// Overhead: 4 bytes total - +// BASIC FRAME - Standard framing with sync and CRC (Recommended) +// Format: [START=0x90] [MSG_ID] [MSG] [CRC1] [CRC2] +// Overhead: 4 bytes message BasicFrame { - option msgid = 4; - - // Synchronization start byte (default 0x90) - uint8 start_byte = 1; - - // Message identifier (0-255) - uint8 msg_id = 2; - - // Fletcher-16 checksum byte 1 + uint8 start_byte = 1 [(hex) = 0x90]; + BasicMessage payload = 2; uint8 crc_byte1 = 3; - - // Fletcher-16 checksum byte 2 uint8 crc_byte2 = 4; } -// ============================================================================ // BASIC FRAME NO CRC -// ============================================================================ -// -// Format: [START (1 byte)] [MSG_ID (1 byte)] [MSG (N bytes)] -// -// Frame format with synchronization but no error checking. -// For use when error detection is handled elsewhere. -// -// Use Cases: -// - Links with hardware error correction -// - When performance is critical and errors are rare -// - Layered protocols where outer layer has CRC -// - Development/debugging scenarios -// -// Header Length: 2 bytes (START + MSG_ID) -// Footer Length: 0 bytes -// Overhead: 2 bytes total - +// Format: [START=0x90] [MSG_ID] [MSG] +// Overhead: 2 bytes message BasicFrameNoCrc { - option msgid = 5; - - // Synchronization start byte (default 0x90) - uint8 start_byte = 1; - - // Message identifier (0-255) - uint8 msg_id = 2; + uint8 start_byte = 1 [(hex) = 0x90]; + BasicMessage payload = 2; } // ============================================================================ -// TINY FRAME (Minimal Header with CRC) -// ============================================================================ -// -// Format: [START (1 byte)] [MSG_ID (1 byte)] [MSG (N bytes)] [CRC (2 bytes)] -// -// Compact frame format with synchronization and error detection. -// Structurally similar to BasicFrame but intended for constrained environments -// where a smaller start byte vocabulary may be used. -// -// Use Cases: -// - Bandwidth-constrained links -// - Battery-powered devices -// - High message rate applications -// - Embedded systems with limited memory -// -// Header Length: 2 bytes (START + MSG_ID) -// Footer Length: 2 bytes (Fletcher-16 CRC) -// Overhead: 4 bytes total - +// TINY FRAME - Compact framing for constrained environments +// Format: [START] [MSG_ID] [MSG] [CRC1] [CRC2] +// Overhead: 4 bytes message TinyFrame { - option msgid = 6; - - // Start byte / sync marker - uint8 start_byte = 1; - - // Message identifier (0-255) - uint8 msg_id = 2; - - // Fletcher-16 checksum byte 1 + uint8 start_byte = 1 [(hex) = 0x90]; + BasicMessage payload = 2; uint8 crc_byte1 = 3; - - // Fletcher-16 checksum byte 2 uint8 crc_byte2 = 4; } -// ============================================================================ // TINY FRAME NO CRC -// ============================================================================ -// -// Format: [START (1 byte)] [MSG_ID (1 byte)] [MSG (N bytes)] -// -// Minimal frame format with sync but no error detection. -// Minimum overhead for reliable links with synchronization support. -// -// Use Cases: -// - Point-to-point wired connections -// - Time-critical applications -// - When payload includes its own integrity check -// - Extremely constrained bandwidth scenarios -// -// Header Length: 2 bytes (START + MSG_ID) -// Footer Length: 0 bytes -// Overhead: 2 bytes total - +// Format: [START] [MSG_ID] [MSG] +// Overhead: 2 bytes message TinyFrameNoCrc { - option msgid = 7; - - // Start byte / sync marker - uint8 start_byte = 1; - - // Message identifier (0-255) - uint8 msg_id = 2; + uint8 start_byte = 1 [(hex) = 0x90]; + BasicMessage payload = 2; } // ============================================================================ -// LENGTH-PREFIXED VARIANTS (8-bit length field) +// LENGTH-PREFIXED VARIANTS (8-bit length, up to 255 bytes) // ============================================================================ -// -// These variants add a 1-byte length field after the header. -// Supports message payloads up to 255 bytes. -// Enables variable-length messages without predefined size tables. - -// Format: [MSG_ID (1 byte)] [LEN (1 byte)] [MSG (LEN bytes)] [CRC (2 bytes)] -// -// Use Cases: -// - Variable-length messages -// - Dynamic payload sizes -// - Streaming data with packet boundaries -// - When message size table is not available at receiver -// -// Header Length: 2 bytes (MSG_ID + LEN) -// Footer Length: 2 bytes (Fletcher-16 CRC) -// Overhead: 4 bytes total +// MSG ID FRAME LEN8 +// Format: [MSG_ID] [LEN] [MSG] [CRC1] [CRC2] +// Overhead: 4 bytes message MsgIdFrameLen8 { - option msgid = 8; - - // Message identifier (0-255) - uint8 msg_id = 1; - - // Payload length (0-255 bytes) + BasicMessage payload = 1; uint8 length = 2; - - // Fletcher-16 checksum byte 1 uint8 crc_byte1 = 3; - - // Fletcher-16 checksum byte 2 uint8 crc_byte2 = 4; } -// Format: [MSG_ID (1 byte)] [LEN (1 byte)] [MSG (LEN bytes)] - +// MSG ID FRAME LEN8 NO CRC +// Format: [MSG_ID] [LEN] [MSG] +// Overhead: 2 bytes message MsgIdFrameLen8NoCrc { - option msgid = 9; - - // Message identifier (0-255) - uint8 msg_id = 1; - - // Payload length (0-255 bytes) + BasicMessage payload = 1; uint8 length = 2; } -// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (1 byte)] [MSG (LEN bytes)] [CRC (2 bytes)] -// -// Header Length: 3 bytes (START + MSG_ID + LEN) -// Footer Length: 2 bytes (Fletcher-16 CRC) -// Overhead: 5 bytes total - +// BASIC FRAME LEN8 (Recommended for variable length) +// Format: [START=0x90] [MSG_ID] [LEN] [MSG] [CRC1] [CRC2] +// Overhead: 5 bytes message BasicFrameLen8 { - option msgid = 10; - - // Synchronization start byte - uint8 start_byte = 1; - - // Message identifier (0-255) - uint8 msg_id = 2; - - // Payload length (0-255 bytes) + uint8 start_byte = 1 [(hex) = 0x90]; + BasicMessage payload = 2; uint8 length = 3; - - // Fletcher-16 checksum byte 1 uint8 crc_byte1 = 4; - - // Fletcher-16 checksum byte 2 uint8 crc_byte2 = 5; } -// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (1 byte)] [MSG (LEN bytes)] - +// BASIC FRAME LEN8 NO CRC +// Format: [START=0x90] [MSG_ID] [LEN] [MSG] +// Overhead: 3 bytes message BasicFrameLen8NoCrc { - option msgid = 11; - - // Synchronization start byte - uint8 start_byte = 1; - - // Message identifier (0-255) - uint8 msg_id = 2; - - // Payload length (0-255 bytes) + uint8 start_byte = 1 [(hex) = 0x90]; + BasicMessage payload = 2; uint8 length = 3; } -// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (1 byte)] [MSG (LEN bytes)] [CRC (2 bytes)] -// -// Header Length: 3 bytes (START + MSG_ID + LEN) -// Footer Length: 2 bytes (Fletcher-16 CRC) -// Overhead: 5 bytes total - +// TINY FRAME LEN8 +// Format: [START] [MSG_ID] [LEN] [MSG] [CRC1] [CRC2] +// Overhead: 5 bytes message TinyFrameLen8 { - option msgid = 12; - - // Start byte / sync marker - uint8 start_byte = 1; - - // Message identifier (0-255) - uint8 msg_id = 2; - - // Payload length (0-255 bytes) + uint8 start_byte = 1 [(hex) = 0x90]; + BasicMessage payload = 2; uint8 length = 3; - - // Fletcher-16 checksum byte 1 uint8 crc_byte1 = 4; - - // Fletcher-16 checksum byte 2 uint8 crc_byte2 = 5; } -// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (1 byte)] [MSG (LEN bytes)] -// -// Header Length: 3 bytes (START + MSG_ID + LEN) -// Footer Length: 0 bytes -// Overhead: 3 bytes total - +// TINY FRAME LEN8 NO CRC +// Format: [START] [MSG_ID] [LEN] [MSG] +// Overhead: 3 bytes message TinyFrameLen8NoCrc { - option msgid = 13; - - // Start byte / sync marker - uint8 start_byte = 1; - - // Message identifier (0-255) - uint8 msg_id = 2; - - // Payload length (0-255 bytes) + uint8 start_byte = 1 [(hex) = 0x90]; + BasicMessage payload = 2; uint8 length = 3; } // ============================================================================ -// LENGTH-PREFIXED VARIANTS (16-bit length field) +// LENGTH-PREFIXED VARIANTS (16-bit length, up to 65535 bytes) // ============================================================================ -// -// These variants add a 2-byte length field after the header. -// Supports message payloads up to 65535 bytes. -// For large data transfers and streaming applications. - -// Format: [MSG_ID (1 byte)] [LEN (2 bytes)] [MSG (LEN bytes)] [CRC (2 bytes)] -// -// Use Cases: -// - Large payload messages (up to 64KB) -// - File transfer protocols -// - Firmware update protocols -// - Bulk data streaming -// -// Header Length: 3 bytes (MSG_ID + LEN16) -// Footer Length: 2 bytes (Fletcher-16 CRC) -// Overhead: 5 bytes total +// MSG ID FRAME LEN16 +// Format: [MSG_ID] [LEN_LO] [LEN_HI] [MSG] [CRC1] [CRC2] +// Overhead: 5 bytes message MsgIdFrameLen16 { - option msgid = 14; - - // Message identifier (0-255) - uint8 msg_id = 1; - - // Payload length (0-65535 bytes), little-endian + BasicMessage payload = 1; uint16 length = 2; - - // Fletcher-16 checksum byte 1 uint8 crc_byte1 = 3; - - // Fletcher-16 checksum byte 2 uint8 crc_byte2 = 4; } -// Format: [MSG_ID (1 byte)] [LEN (2 bytes)] [MSG (LEN bytes)] - +// MSG ID FRAME LEN16 NO CRC +// Format: [MSG_ID] [LEN_LO] [LEN_HI] [MSG] +// Overhead: 3 bytes message MsgIdFrameLen16NoCrc { - option msgid = 15; - - // Message identifier (0-255) - uint8 msg_id = 1; - - // Payload length (0-65535 bytes), little-endian + BasicMessage payload = 1; uint16 length = 2; } -// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (2 bytes)] [MSG (LEN bytes)] [CRC (2 bytes)] -// -// Header Length: 4 bytes (START + MSG_ID + LEN16) -// Footer Length: 2 bytes (Fletcher-16 CRC) -// Overhead: 6 bytes total - +// BASIC FRAME LEN16 +// Format: [START=0x90] [MSG_ID] [LEN_LO] [LEN_HI] [MSG] [CRC1] [CRC2] +// Overhead: 6 bytes message BasicFrameLen16 { - option msgid = 16; - - // Synchronization start byte - uint8 start_byte = 1; - - // Message identifier (0-255) - uint8 msg_id = 2; - - // Payload length (0-65535 bytes), little-endian + uint8 start_byte = 1 [(hex) = 0x90]; + BasicMessage payload = 2; uint16 length = 3; - - // Fletcher-16 checksum byte 1 uint8 crc_byte1 = 4; - - // Fletcher-16 checksum byte 2 uint8 crc_byte2 = 5; } -// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (2 bytes)] [MSG (LEN bytes)] - +// BASIC FRAME LEN16 NO CRC +// Format: [START=0x90] [MSG_ID] [LEN_LO] [LEN_HI] [MSG] +// Overhead: 4 bytes message BasicFrameLen16NoCrc { - option msgid = 17; - - // Synchronization start byte - uint8 start_byte = 1; - - // Message identifier (0-255) - uint8 msg_id = 2; - - // Payload length (0-65535 bytes), little-endian + uint8 start_byte = 1 [(hex) = 0x90]; + BasicMessage payload = 2; uint16 length = 3; } -// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (2 bytes)] [MSG (LEN bytes)] [CRC (2 bytes)] -// -// Header Length: 4 bytes (START + MSG_ID + LEN16) -// Footer Length: 2 bytes (Fletcher-16 CRC) -// Overhead: 6 bytes total - +// TINY FRAME LEN16 +// Format: [START] [MSG_ID] [LEN_LO] [LEN_HI] [MSG] [CRC1] [CRC2] +// Overhead: 6 bytes message TinyFrameLen16 { - option msgid = 18; - - // Start byte / sync marker - uint8 start_byte = 1; - - // Message identifier (0-255) - uint8 msg_id = 2; - - // Payload length (0-65535 bytes), little-endian + uint8 start_byte = 1 [(hex) = 0x90]; + BasicMessage payload = 2; uint16 length = 3; - - // Fletcher-16 checksum byte 1 uint8 crc_byte1 = 4; - - // Fletcher-16 checksum byte 2 uint8 crc_byte2 = 5; } -// Format: [START (1 byte)] [MSG_ID (1 byte)] [LEN (2 bytes)] [MSG (LEN bytes)] -// -// Header Length: 4 bytes (START + MSG_ID + LEN16) -// Footer Length: 0 bytes -// Overhead: 4 bytes total - +// TINY FRAME LEN16 NO CRC +// Format: [START] [MSG_ID] [LEN_LO] [LEN_HI] [MSG] +// Overhead: 4 bytes message TinyFrameLen16NoCrc { - option msgid = 19; - - // Start byte / sync marker - uint8 start_byte = 1; - - // Message identifier (0-255) - uint8 msg_id = 2; - - // Payload length (0-65535 bytes), little-endian + uint8 start_byte = 1 [(hex) = 0x90]; + BasicMessage payload = 2; uint16 length = 3; } // ============================================================================ -// UBX FRAME FORMAT +// THIRD PARTY PROTOCOLS // ============================================================================ -// -// u-blox proprietary binary protocol used by GPS/GNSS receivers. -// -// Format: [SYNC1 (1 byte)] [SYNC2 (1 byte)] [CLASS (1 byte)] [ID (1 byte)] -// [LEN_LO (1 byte)] [LEN_HI (1 byte)] [PAYLOAD (LEN bytes)] -// [CK_A (1 byte)] [CK_B (1 byte)] -// -// SYNC1: 0xB5 (μ in ISO 8859-1) -// SYNC2: 0x62 ('b') -// CLASS: Message class -// ID: Message ID within class -// LEN: 16-bit payload length, little-endian -// PAYLOAD: Variable length message data -// CK_A, CK_B: Fletcher-8 checksum over CLASS, ID, LEN, and PAYLOAD -// -// Use Cases: -// - u-blox GPS receiver communication -// - GNSS data logging and configuration -// - Position/navigation applications -// - Timing and synchronization systems -// -// Header Length: 6 bytes (SYNC1 + SYNC2 + CLASS + ID + LEN) -// Footer Length: 2 bytes (Fletcher-8 checksum) -// Overhead: 8 bytes total -// Max Payload: 65535 bytes +// UBX FRAME - u-blox GPS/GNSS protocol +// Format: [SYNC1=0xB5] [SYNC2=0x62] [CLASS] [ID] [LEN_LO] [LEN_HI] [MSG] [CK_A] [CK_B] +// Overhead: 8 bytes message UbxFrame { - option msgid = 20; - - // Sync byte 1 (always 0xB5) - uint8 sync1 = 1; - - // Sync byte 2 (always 0x62) - uint8 sync2 = 2; - - // Message class (e.g., NAV=0x01, RXM=0x02, INF=0x04, ACK=0x05, etc.) + uint8 sync1 = 1 [(hex) = 0xB5]; + uint8 sync2 = 2 [(hex) = 0x62]; uint8 msg_class = 3; - - // Message ID within class - uint8 msg_id = 4; - - // Payload length low byte (little-endian) + BasicMessage payload = 4; uint8 length_lo = 5; - - // Payload length high byte (little-endian) uint8 length_hi = 6; - - // Fletcher-8 checksum A uint8 ck_a = 7; - - // Fletcher-8 checksum B uint8 ck_b = 8; } -// ============================================================================ -// MAVLINK V1 FRAME FORMAT -// ============================================================================ -// -// MAVLink Micro Air Vehicle Link protocol version 1.0 -// Used by ArduPilot, PX4, and other drone/UAV flight controllers. -// -// Format: [STX (1 byte)] [LEN (1 byte)] [SEQ (1 byte)] [SYS (1 byte)] -// [COMP (1 byte)] [MSG (1 byte)] [PAYLOAD (LEN bytes)] [CRC (2 bytes)] -// -// STX: Start of frame (0xFE) -// LEN: Payload length (0-255) -// SEQ: Sequence number (0-255, wrapping) -// SYS: System ID (1-255) -// COMP: Component ID (1-255) -// MSG: Message ID (0-255) -// PAYLOAD: Message data -// CRC: X.25 CRC-16 checksum -// -// Use Cases: -// - Drone/UAV communication -// - Ground control station links -// - Autopilot telemetry -// - MAVLink 1.0 compatible devices -// -// Header Length: 6 bytes (STX + LEN + SEQ + SYS + COMP + MSG) -// Footer Length: 2 bytes (CRC-16) -// Overhead: 8 bytes total -// Max Payload: 255 bytes - +// MAVLINK V1 FRAME - Legacy drone protocol +// Format: [STX=0xFE] [LEN] [SEQ] [SYS] [COMP] [MSG] [PAYLOAD] [CRC_LO] [CRC_HI] +// Overhead: 8 bytes message MavlinkV1Frame { - option msgid = 21; - - // Start of frame marker (always 0xFE) - uint8 stx = 1; - - // Payload length (0-255 bytes) + uint8 stx = 1 [(hex) = 0xFE]; uint8 length = 2; - - // Packet sequence number (0-255, wrapping counter) uint8 sequence = 3; - - // System ID (identifies the vehicle/GCS, 1-255) uint8 system_id = 4; - - // Component ID (identifies component on system, 1-255) uint8 component_id = 5; - - // Message ID (0-255) - uint8 msg_id = 6; - - // CRC-16/X.25 checksum low byte + BasicMessage payload = 6; uint8 crc_lo = 7; - - // CRC-16/X.25 checksum high byte uint8 crc_hi = 8; } -// ============================================================================ -// MAVLINK V2 FRAME FORMAT -// ============================================================================ -// -// MAVLink Micro Air Vehicle Link protocol version 2.0 -// Extended version with more message IDs and optional message signing. -// -// Format: [STX (1 byte)] [LEN (1 byte)] [INCOMPAT (1 byte)] [COMPAT (1 byte)] -// [SEQ (1 byte)] [SYS (1 byte)] [COMP (1 byte)] [MSG_ID (3 bytes)] -// [PAYLOAD (LEN bytes)] [CRC (2 bytes)] [SIGNATURE (13 bytes, optional)] -// -// STX: Start of frame (0xFD) -// LEN: Payload length (0-255) -// INCOMPAT: Incompatibility flags (must understand to parse) -// COMPAT: Compatibility flags (can ignore if unknown) -// SEQ: Sequence number (0-255) -// SYS: System ID (1-255) -// COMP: Component ID (1-255) -// MSG_ID: 24-bit message ID (0-16777215) -// PAYLOAD: Message data -// CRC: CRC-16 checksum -// SIGNATURE: Optional 13-byte message signature for authentication -// -// Incompatibility Flags: -// 0x01 - MAVLINK_IFLAG_SIGNED - Message is signed -// -// Use Cases: -// - Modern drone/UAV communication -// - Extended message ID space (16.7M messages) -// - Authenticated communication -// - High-security applications -// -// Header Length: 10 bytes (STX + LEN + INCOMPAT + COMPAT + SEQ + SYS + COMP + MSG_ID) -// Footer Length: 2 bytes CRC + optional 13 bytes signature -// Overhead: 12-25 bytes total -// Max Payload: 255 bytes - +// MAVLINK V2 FRAME - Modern drone protocol with extended message IDs +// Format: [STX=0xFD] [LEN] [INCOMPAT] [COMPAT] [SEQ] [SYS] [COMP] [MSG_ID x3] [PAYLOAD] [CRC] [SIG?] +// Overhead: 12-25 bytes message MavlinkV2Frame { - option msgid = 22; - - // Start of frame marker (always 0xFD) - uint8 stx = 1; - - // Payload length (0-255 bytes) + uint8 stx = 1 [(hex) = 0xFD]; uint8 length = 2; - - // Incompatibility flags (must be understood to parse message) - // Bit 0 (0x01): MAVLINK_IFLAG_SIGNED - message is signed uint8 incompat_flags = 3; - - // Compatibility flags (can be ignored if unknown) uint8 compat_flags = 4; - - // Packet sequence number (0-255, wrapping counter) uint8 sequence = 5; - - // System ID (identifies the vehicle/GCS, 1-255) uint8 system_id = 6; - - // Component ID (identifies component on system, 1-255) uint8 component_id = 7; - - // 24-bit message ID, byte 0 (low byte) uint8 msg_id_0 = 8; - - // 24-bit message ID, byte 1 (middle byte) uint8 msg_id_1 = 9; - - // 24-bit message ID, byte 2 (high byte) uint8 msg_id_2 = 10; - - // CRC-16 checksum low byte uint8 crc_lo = 11; - - // CRC-16 checksum high byte uint8 crc_hi = 12; } -// MAVLink v2 signature for authenticated messages -// Appended after CRC when MAVLINK_IFLAG_SIGNED is set +// MAVLINK V2 SIGNATURE - Optional authentication (13 bytes) message MavlinkV2Signature { - option msgid = 23; - - // Link ID (identifies the communication link) uint8 link_id = 1; - - // Timestamp (48-bit Unix epoch in 10us units, bytes 0-5) uint8 timestamp_0 = 2; uint8 timestamp_1 = 3; uint8 timestamp_2 = 4; uint8 timestamp_3 = 5; uint8 timestamp_4 = 6; uint8 timestamp_5 = 7; - - // SHA-256 signature (first 6 bytes) uint8 signature_0 = 8; uint8 signature_1 = 9; uint8 signature_2 = 10; @@ -821,26 +289,14 @@ message MavlinkV2Signature { } // ============================================================================ -// FRAME FORMAT CONFIGURATION +// CONFIGURATION // ============================================================================ -// -// Configuration message to select and configure frame format at runtime +// Runtime frame format configuration message FrameFormatConfig { - option msgid = 24; - - // Selected frame format type FrameFormatType format_type = 1; - - // Start byte(s) for formats that use them (0x90 default) - uint8 start_byte = 2; - - // Secondary start byte for UBX and similar (0x62 default for UBX) - uint8 start_byte_2 = 3; - - // Enable CRC checking (for formats that support optional CRC) + uint8 start_byte = 2 [(hex) = 0x90]; + uint8 start_byte_2 = 3 [(hex) = 0x62]; bool crc_enabled = 4; - - // Enable message signing (MAVLink v2 only) bool signing_enabled = 5; } From eef9e6041afa12c86b66b88d3064241be83e6fa1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Nov 2025 19:15:43 +0000 Subject: [PATCH 5/7] Fix third-party protocols to use native message ID fields Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com> --- examples/frame_formats.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/frame_formats.proto b/examples/frame_formats.proto index dc306f9f..529208e8 100644 --- a/examples/frame_formats.proto +++ b/examples/frame_formats.proto @@ -232,7 +232,7 @@ message UbxFrame { uint8 sync1 = 1 [(hex) = 0xB5]; uint8 sync2 = 2 [(hex) = 0x62]; uint8 msg_class = 3; - BasicMessage payload = 4; + uint8 msg_id = 4; uint8 length_lo = 5; uint8 length_hi = 6; uint8 ck_a = 7; @@ -248,7 +248,7 @@ message MavlinkV1Frame { uint8 sequence = 3; uint8 system_id = 4; uint8 component_id = 5; - BasicMessage payload = 6; + uint8 msg_id = 6; uint8 crc_lo = 7; uint8 crc_hi = 8; } From cd3371e40b4197eff58f366eee336a2d6b0b33b1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Nov 2025 21:48:04 +0000 Subject: [PATCH 6/7] Address review: restructure tables, rename BasicFrameLen8 to BasicFrameWithLen Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com> --- docs/framing.md | 70 ++++++++++++++++++------------------ examples/frame_formats.proto | 6 ++-- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/docs/framing.md b/docs/framing.md index 1430f9e9..9839686e 100644 --- a/docs/framing.md +++ b/docs/framing.md @@ -12,35 +12,37 @@ All supported frame formats are defined in [`examples/frame_formats.proto`](../e ## Recommended Frame Formats -| Format | Preamble | Header | CRC | Length | Total Overhead | Use Case | -|--------|----------|--------|-----|--------|----------------|----------| -| NoFormat | 0 | 0 | 0 | None | 0 | Trusted links, nested protocols | -| BasicFrame | 1 | 2 | 2 | None | 4 | Standard reliable communication | -| BasicFrameLen8 | 1 | 3 | 2 | 8-bit | 5 | Variable length messages | - -## All Frame Formats - -| Format | Preamble | Header | CRC | Length | Total Overhead | Use Case | -|--------|----------|--------|-----|--------|----------------|----------| -| NoFormat | 0 | 0 | 0 | None | 0 | Trusted links, nested protocols | -| MsgIdFrame | 0 | 1 | 2 | None | 3 | Minimal framing with CRC | -| MsgIdFrameNoCrc | 0 | 1 | 0 | None | 1 | Minimal framing, trusted link | -| MsgIdFrameLen8 | 0 | 2 | 2 | 8-bit | 4 | Variable length, minimal | -| MsgIdFrameLen8NoCrc | 0 | 2 | 0 | 8-bit | 2 | Variable length, no CRC | -| MsgIdFrameLen16 | 0 | 3 | 2 | 16-bit | 5 | Large payloads, minimal | -| MsgIdFrameLen16NoCrc | 0 | 3 | 0 | 16-bit | 3 | Large payloads, no CRC | -| BasicFrame | 1 | 2 | 2 | None | 4 | Standard reliable communication | -| BasicFrameNoCrc | 1 | 2 | 0 | None | 2 | Sync recovery, no CRC | -| BasicFrameLen8 | 1 | 3 | 2 | 8-bit | 5 | Variable length messages | -| BasicFrameLen8NoCrc | 1 | 3 | 0 | 8-bit | 3 | Variable length, no CRC | -| BasicFrameLen16 | 1 | 4 | 2 | 16-bit | 6 | Large payload messages | -| BasicFrameLen16NoCrc | 1 | 4 | 0 | 16-bit | 4 | Large payloads, no CRC | -| TinyFrame | 1 | 2 | 2 | None | 4 | Constrained environments | -| TinyFrameNoCrc | 1 | 2 | 0 | None | 2 | Minimal overhead | -| TinyFrameLen8 | 1 | 3 | 2 | 8-bit | 5 | Variable length, constrained | -| TinyFrameLen8NoCrc | 1 | 3 | 0 | 8-bit | 3 | Variable, minimal overhead | -| TinyFrameLen16 | 1 | 4 | 2 | 16-bit | 6 | Large payloads, constrained | -| TinyFrameLen16NoCrc | 1 | 4 | 0 | 16-bit | 4 | Large, minimal overhead | +| Format | Start Bytes | Length | CRC | Total Overhead | Use Case | +|--------|-------------|--------|-----|----------------|----------| +| BasicFrame | 1 (0x90) | 0 | 2 | 4 | When all messages are known to both systems | +| BasicFrameWithLen | 1 (0x90) | 1 | 2 | 5 | When systems may not have matching message definitions. Recommended if unknown messages may be sent. | + +## Extended Frame Formats + +| Format | Start Bytes | Length | CRC | Total Overhead | Use Case | +|--------|-------------|--------|-----|----------------|----------| +| BasicFrameNoCrc | 1 (0x90) | 0 | 0 | 2 | Sync recovery, no CRC | +| BasicFrameLen16 | 1 (0x90) | 2 | 2 | 6 | Large payload messages | +| BasicFrameLen16NoCrc | 1 (0x90) | 2 | 0 | 4 | Large payloads, no CRC | +| BasicFrameLen8NoCrc | 1 (0x90) | 1 | 0 | 3 | Variable length, no CRC | + +## Parametric Frame Formats + +| Format | Start Bytes | Length | CRC | Total Overhead | Use Case | +|--------|-------------|--------|-----|----------------|----------| +| NoFormat | 0 | 0 | 0 | 0 | Trusted links, nested protocols | +| MsgIdFrame | 0 | 0 | 2 | 3 | Minimal framing with CRC | +| MsgIdFrameNoCrc | 0 | 0 | 0 | 1 | Minimal framing, trusted link | +| MsgIdFrameLen8 | 0 | 1 | 2 | 4 | Variable length, minimal | +| MsgIdFrameLen8NoCrc | 0 | 1 | 0 | 2 | Variable length, no CRC | +| MsgIdFrameLen16 | 0 | 2 | 2 | 5 | Large payloads, minimal | +| MsgIdFrameLen16NoCrc | 0 | 2 | 0 | 3 | Large payloads, no CRC | +| TinyFrame | 1 | 0 | 2 | 4 | Constrained environments | +| TinyFrameNoCrc | 1 | 0 | 0 | 2 | Minimal overhead | +| TinyFrameLen8 | 1 | 1 | 2 | 5 | Variable length, constrained | +| TinyFrameLen8NoCrc | 1 | 1 | 0 | 3 | Variable, minimal overhead | +| TinyFrameLen16 | 1 | 2 | 2 | 6 | Large payloads, constrained | +| TinyFrameLen16NoCrc | 1 | 2 | 0 | 4 | Large, minimal overhead | ## No Frame Format @@ -192,11 +194,11 @@ checksum = [sum1, sum2] ## Third Party Protocols -| Format | Preamble | Header | CRC | Length | Total Overhead | Use Case | -|--------|----------|--------|-----|--------|----------------|----------| -| UBX | 2 | 6 | 2 | 16-bit | 8 | u-blox GPS compatibility | -| MavlinkV1 | 1 | 6 | 2 | 8-bit | 8 | Legacy drone communication | -| MavlinkV2 | 1 | 10 | 2-15 | 8-bit | 12-25 | Modern drone communication | +| Format | Start Bytes | Length | CRC | Total Overhead | Use Case | +|--------|-------------|--------|-----|----------------|----------| +| UBX | 2 (0xB5, 0x62) | 2 | 2 | 8 | u-blox GPS compatibility | +| MavlinkV1 | 1 (0xFE) | 1 | 2 | 8 | Legacy drone communication | +| MavlinkV2 | 1 (0xFD) | 1 | 2-15 | 12-25 | Modern drone communication | ### UBX Format diff --git a/examples/frame_formats.proto b/examples/frame_formats.proto index 529208e8..8c2a4a48 100644 --- a/examples/frame_formats.proto +++ b/examples/frame_formats.proto @@ -16,7 +16,7 @@ enum FrameFormatType { MSG_ID_FRAME_LEN8_NO_CRC = 8; MSG_ID_FRAME_LEN16 = 9; MSG_ID_FRAME_LEN16_NO_CRC = 10; - BASIC_FRAME_LEN8 = 11; + BASIC_FRAME_WITH_LEN = 11; BASIC_FRAME_LEN8_NO_CRC = 12; BASIC_FRAME_LEN16 = 13; BASIC_FRAME_LEN16_NO_CRC = 14; @@ -119,10 +119,10 @@ message MsgIdFrameLen8NoCrc { uint8 length = 2; } -// BASIC FRAME LEN8 (Recommended for variable length) +// BASIC FRAME WITH LEN (Recommended for variable length) // Format: [START=0x90] [MSG_ID] [LEN] [MSG] [CRC1] [CRC2] // Overhead: 5 bytes -message BasicFrameLen8 { +message BasicFrameWithLen { uint8 start_byte = 1 [(hex) = 0x90]; BasicMessage payload = 2; uint8 length = 3; From d85f467a34ab58fbb939b5a4cb228ee554512586 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Nov 2025 22:07:28 +0000 Subject: [PATCH 7/7] Restructure frames: BasicFrame 2 start bytes, TinyFrame 1 start byte, add SysComp variant Co-authored-by: rijesha <7819200+rijesha@users.noreply.github.com> --- docs/framing.md | 91 ++++++++------- examples/frame_formats.proto | 212 +++++++++++++++++++---------------- 2 files changed, 169 insertions(+), 134 deletions(-) diff --git a/docs/framing.md b/docs/framing.md index 9839686e..9cb5a587 100644 --- a/docs/framing.md +++ b/docs/framing.md @@ -14,35 +14,36 @@ All supported frame formats are defined in [`examples/frame_formats.proto`](../e | Format | Start Bytes | Length | CRC | Total Overhead | Use Case | |--------|-------------|--------|-----|----------------|----------| -| BasicFrame | 1 (0x90) | 0 | 2 | 4 | When all messages are known to both systems | -| BasicFrameWithLen | 1 (0x90) | 1 | 2 | 5 | When systems may not have matching message definitions. Recommended if unknown messages may be sent. | +| BasicFrame | 2 (0x90, 0x91) | 0 | 2 | 5 | When all messages are known to both systems | +| TinyFrame | 1 (0x70) | 0 | 2 | 4 | Constrained environments with known messages | +| BasicFrameWithLen | 2 (0x90, 0x92) | 1 | 2 | 6 | When systems may not have matching message definitions | +| TinyFrameWithLen | 1 (0x71) | 1 | 2 | 5 | Constrained environments with variable messages | +| BasicFrameWithLen16 | 2 (0x90, 0x93) | 2 | 2 | 7 | Large payloads up to 64KB | +| BasicFrameWithSysComp | 2 (0x90, 0x94) | 0 | 2 | 7 | Multi-system networks with system and component IDs | ## Extended Frame Formats | Format | Start Bytes | Length | CRC | Total Overhead | Use Case | |--------|-------------|--------|-----|----------------|----------| -| BasicFrameNoCrc | 1 (0x90) | 0 | 0 | 2 | Sync recovery, no CRC | -| BasicFrameLen16 | 1 (0x90) | 2 | 2 | 6 | Large payload messages | -| BasicFrameLen16NoCrc | 1 (0x90) | 2 | 0 | 4 | Large payloads, no CRC | -| BasicFrameLen8NoCrc | 1 (0x90) | 1 | 0 | 3 | Variable length, no CRC | +| NoFormat | 0 | 0 | 0 | 0 | Trusted links, nested protocols | +| MinimalFrame | 0 | 0 | 2 | 3 | Minimal framing with CRC | +| MinimalFrameNoCrc | 0 | 0 | 0 | 1 | Minimal framing, trusted link | +| MinimalFrameWithLen | 0 | 1 | 2 | 4 | Variable length, minimal | ## Parametric Frame Formats | Format | Start Bytes | Length | CRC | Total Overhead | Use Case | |--------|-------------|--------|-----|----------------|----------| -| NoFormat | 0 | 0 | 0 | 0 | Trusted links, nested protocols | -| MsgIdFrame | 0 | 0 | 2 | 3 | Minimal framing with CRC | -| MsgIdFrameNoCrc | 0 | 0 | 0 | 1 | Minimal framing, trusted link | -| MsgIdFrameLen8 | 0 | 1 | 2 | 4 | Variable length, minimal | -| MsgIdFrameLen8NoCrc | 0 | 1 | 0 | 2 | Variable length, no CRC | -| MsgIdFrameLen16 | 0 | 2 | 2 | 5 | Large payloads, minimal | -| MsgIdFrameLen16NoCrc | 0 | 2 | 0 | 3 | Large payloads, no CRC | -| TinyFrame | 1 | 0 | 2 | 4 | Constrained environments | -| TinyFrameNoCrc | 1 | 0 | 0 | 2 | Minimal overhead | -| TinyFrameLen8 | 1 | 1 | 2 | 5 | Variable length, constrained | -| TinyFrameLen8NoCrc | 1 | 1 | 0 | 3 | Variable, minimal overhead | -| TinyFrameLen16 | 1 | 2 | 2 | 6 | Large payloads, constrained | -| TinyFrameLen16NoCrc | 1 | 2 | 0 | 4 | Large, minimal overhead | +| BasicFrameNoCrc | 2 (0x90, 0x95) | 0 | 0 | 3 | Sync recovery, no CRC | +| BasicFrameWithLenNoCrc | 2 (0x90, 0x96) | 1 | 0 | 4 | Variable length, no CRC | +| BasicFrameWithLen16NoCrc | 2 (0x90, 0x97) | 2 | 0 | 5 | Large payloads, no CRC | +| TinyFrameNoCrc | 1 (0x72) | 0 | 0 | 2 | Minimal overhead | +| TinyFrameWithLenNoCrc | 1 (0x73) | 1 | 0 | 3 | Variable, minimal overhead | +| TinyFrameWithLen16 | 1 (0x74) | 2 | 2 | 6 | Large payloads, constrained | +| TinyFrameWithLen16NoCrc | 1 (0x75) | 2 | 0 | 4 | Large, minimal overhead | +| MinimalFrameWithLenNoCrc | 0 | 1 | 0 | 2 | Variable length, no CRC | +| MinimalFrameWithLen16 | 0 | 2 | 2 | 5 | Large payloads, minimal | +| MinimalFrameWithLen16NoCrc | 0 | 2 | 0 | 3 | Large payloads, no CRC | ## No Frame Format @@ -63,16 +64,16 @@ Limitations: The default frame format used by Struct Frame: ``` -[Start Byte] [Message ID] [Payload Data...] [Checksum 1] [Checksum 2] - 0x90 1 byte Variable Length 1 byte 1 byte +[Start Byte 1] [Start Byte 2] [Message ID] [Payload Data...] [Checksum 1] [Checksum 2] + 0x90 0x91 1 byte Variable Length 1 byte 1 byte ``` ### Components -**Start Byte (0x90)** -- Fixed marker to identify frame boundaries -- Parser scans for this byte to synchronize -- Allows recovery after corruption +**Start Bytes (0x90, 0x91)** +- Two-byte marker to identify frame boundaries +- Parser scans for this sequence to synchronize +- Second byte varies by frame type (0x91=Basic, 0x92=WithLen, etc.) **Message ID (1 byte)** - Maps to specific message type defined in proto @@ -94,37 +95,37 @@ The default frame format used by Struct Frame: Message: VehicleHeartbeat (ID=42) with payload [0x01, 0x02, 0x03, 0x04] ``` -Frame: [0x90] [0x2A] [0x01, 0x02, 0x03, 0x04] [0x7F] [0x8A] - Start ID Payload Checksum +Frame: [0x90] [0x91] [0x2A] [0x01, 0x02, 0x03, 0x04] [0x7F] [0x8A] + Start1 Start2 ID Payload Checksum ``` ### Frame Size -Total bytes = 2 (header) + payload size + 2 (checksum) +Total bytes = 3 (header) + payload size + 2 (checksum) -For a message with 5 bytes of data: 2 + 5 + 2 = 9 bytes total +For a message with 5 bytes of data: 3 + 5 + 2 = 10 bytes total -## MSG ID Frame Variants +## Minimal Frame Variants -Minimal framing with just message ID and optional CRC: +Minimal framing with just message ID and optional CRC (0 start bytes): -**MsgIdFrame**: `[MSG_ID (1)] [PAYLOAD] [CRC (2)]` +**MinimalFrame**: `[MSG_ID (1)] [PAYLOAD] [CRC (2)]` - 3 bytes overhead - For synchronized links with error detection -**MsgIdFrameNoCrc**: `[MSG_ID (1)] [PAYLOAD]` +**MinimalFrameNoCrc**: `[MSG_ID (1)] [PAYLOAD]` - 1 byte overhead - For trusted, synchronized links ## Tiny Frame Variants -Low overhead framing for constrained environments: +Low overhead framing for constrained environments (1 start byte): -**TinyFrame**: `[START (1)] [MSG_ID (1)] [PAYLOAD] [CRC (2)]` +**TinyFrame**: `[START (0x70)] [MSG_ID (1)] [PAYLOAD] [CRC (2)]` - 4 bytes overhead - Battery-powered devices, high message rates -**TinyFrameNoCrc**: `[START (1)] [MSG_ID (1)] [PAYLOAD]` +**TinyFrameNoCrc**: `[START (0x72)] [MSG_ID (1)] [PAYLOAD]` - 2 bytes overhead - Minimal overhead with sync recovery @@ -132,18 +133,28 @@ Low overhead framing for constrained environments: All frame formats have variants with explicit length fields: -**8-bit length (Len8)**: Supports payloads up to 255 bytes +**1-byte length (WithLen)**: Supports payloads up to 255 bytes - Adds 1 byte to header - Use for variable-length messages -**16-bit length (Len16)**: Supports payloads up to 65,535 bytes +**2-byte length (WithLen16)**: Supports payloads up to 65,535 bytes - Adds 2 bytes to header (little-endian) - Use for large data transfers, firmware updates -Example: `BasicFrameLen16` +Example: `BasicFrameWithLen16` +``` +[START1 (0x90)] [START2 (0x93)] [MSG_ID (1)] [LEN_LO (1)] [LEN_HI (1)] [PAYLOAD] [CRC (2)] +``` + +## System/Component ID Variant + +**BasicFrameWithSysComp**: For multi-system networks ``` -[START (1)] [MSG_ID (1)] [LEN_LO (1)] [LEN_HI (1)] [PAYLOAD] [CRC (2)] +[START1 (0x90)] [START2 (0x94)] [SYS_ID (1)] [COMP_ID (1)] [MSG_ID (1)] [PAYLOAD] [CRC (2)] ``` +- 7 bytes overhead +- System ID identifies the vehicle/ground station +- Component ID identifies the component (autopilot, camera, etc.) ## Parser State Machine diff --git a/examples/frame_formats.proto b/examples/frame_formats.proto index 8c2a4a48..89ffe90b 100644 --- a/examples/frame_formats.proto +++ b/examples/frame_formats.proto @@ -6,27 +6,28 @@ package frame_formats; // Frame format type enumeration enum FrameFormatType { NO_FORMAT = 0; - MSG_ID_FRAME = 1; - MSG_ID_FRAME_NO_CRC = 2; + MINIMAL_FRAME = 1; + MINIMAL_FRAME_NO_CRC = 2; BASIC_FRAME = 3; BASIC_FRAME_NO_CRC = 4; TINY_FRAME = 5; TINY_FRAME_NO_CRC = 6; - MSG_ID_FRAME_LEN8 = 7; - MSG_ID_FRAME_LEN8_NO_CRC = 8; - MSG_ID_FRAME_LEN16 = 9; - MSG_ID_FRAME_LEN16_NO_CRC = 10; + MINIMAL_FRAME_WITH_LEN = 7; + MINIMAL_FRAME_WITH_LEN_NO_CRC = 8; + MINIMAL_FRAME_WITH_LEN16 = 9; + MINIMAL_FRAME_WITH_LEN16_NO_CRC = 10; BASIC_FRAME_WITH_LEN = 11; - BASIC_FRAME_LEN8_NO_CRC = 12; - BASIC_FRAME_LEN16 = 13; - BASIC_FRAME_LEN16_NO_CRC = 14; - TINY_FRAME_LEN8 = 15; - TINY_FRAME_LEN8_NO_CRC = 16; - TINY_FRAME_LEN16 = 17; - TINY_FRAME_LEN16_NO_CRC = 18; - UBX = 19; - MAVLINK_V1 = 20; - MAVLINK_V2 = 21; + BASIC_FRAME_WITH_LEN_NO_CRC = 12; + BASIC_FRAME_WITH_LEN16 = 13; + BASIC_FRAME_WITH_LEN16_NO_CRC = 14; + TINY_FRAME_WITH_LEN = 15; + TINY_FRAME_WITH_LEN_NO_CRC = 16; + TINY_FRAME_WITH_LEN16 = 17; + TINY_FRAME_WITH_LEN16_NO_CRC = 18; + BASIC_FRAME_WITH_SYS_COMP = 19; + UBX = 20; + MAVLINK_V1 = 21; + MAVLINK_V2 = 22; } // Basic message payload included in all frame formats @@ -43,184 +44,207 @@ message NoFormat { } // ============================================================================ -// MSG ID FRAME - Minimal framing with CRC +// MINIMAL FRAME - No start bytes, just MSG_ID with CRC // Format: [MSG_ID] [MSG] [CRC1] [CRC2] // Overhead: 3 bytes -message MsgIdFrame { +message MinimalFrame { BasicMessage payload = 1; uint8 crc_byte1 = 2; uint8 crc_byte2 = 3; } -// MSG ID FRAME NO CRC +// MINIMAL FRAME NO CRC // Format: [MSG_ID] [MSG] // Overhead: 1 byte -message MsgIdFrameNoCrc { +message MinimalFrameNoCrc { BasicMessage payload = 1; } // ============================================================================ -// BASIC FRAME - Standard framing with sync and CRC (Recommended) -// Format: [START=0x90] [MSG_ID] [MSG] [CRC1] [CRC2] -// Overhead: 4 bytes +// BASIC FRAME - 2 start bytes with CRC (Recommended) +// Format: [START1=0x90] [START2=0x91] [MSG_ID] [MSG] [CRC1] [CRC2] +// Overhead: 5 bytes message BasicFrame { - uint8 start_byte = 1 [(hex) = 0x90]; - BasicMessage payload = 2; - uint8 crc_byte1 = 3; - uint8 crc_byte2 = 4; + uint8 start_byte1 = 1 [(hex) = 0x90]; + uint8 start_byte2 = 2 [(hex) = 0x91]; + BasicMessage payload = 3; + uint8 crc_byte1 = 4; + uint8 crc_byte2 = 5; } // BASIC FRAME NO CRC -// Format: [START=0x90] [MSG_ID] [MSG] -// Overhead: 2 bytes +// Format: [START1=0x90] [START2=0x95] [MSG_ID] [MSG] +// Overhead: 3 bytes message BasicFrameNoCrc { - uint8 start_byte = 1 [(hex) = 0x90]; - BasicMessage payload = 2; + uint8 start_byte1 = 1 [(hex) = 0x90]; + uint8 start_byte2 = 2 [(hex) = 0x95]; + BasicMessage payload = 3; } // ============================================================================ -// TINY FRAME - Compact framing for constrained environments -// Format: [START] [MSG_ID] [MSG] [CRC1] [CRC2] +// TINY FRAME - 1 start byte with CRC (Recommended) +// Format: [START=0x70] [MSG_ID] [MSG] [CRC1] [CRC2] // Overhead: 4 bytes message TinyFrame { - uint8 start_byte = 1 [(hex) = 0x90]; + uint8 start_byte = 1 [(hex) = 0x70]; BasicMessage payload = 2; uint8 crc_byte1 = 3; uint8 crc_byte2 = 4; } // TINY FRAME NO CRC -// Format: [START] [MSG_ID] [MSG] +// Format: [START=0x72] [MSG_ID] [MSG] // Overhead: 2 bytes message TinyFrameNoCrc { - uint8 start_byte = 1 [(hex) = 0x90]; + uint8 start_byte = 1 [(hex) = 0x72]; BasicMessage payload = 2; } // ============================================================================ -// LENGTH-PREFIXED VARIANTS (8-bit length, up to 255 bytes) +// LENGTH-PREFIXED VARIANTS (1-byte length, up to 255 bytes) // ============================================================================ -// MSG ID FRAME LEN8 +// MINIMAL FRAME WITH LEN // Format: [MSG_ID] [LEN] [MSG] [CRC1] [CRC2] // Overhead: 4 bytes -message MsgIdFrameLen8 { +message MinimalFrameWithLen { BasicMessage payload = 1; uint8 length = 2; uint8 crc_byte1 = 3; uint8 crc_byte2 = 4; } -// MSG ID FRAME LEN8 NO CRC +// MINIMAL FRAME WITH LEN NO CRC // Format: [MSG_ID] [LEN] [MSG] // Overhead: 2 bytes -message MsgIdFrameLen8NoCrc { +message MinimalFrameWithLenNoCrc { BasicMessage payload = 1; uint8 length = 2; } // BASIC FRAME WITH LEN (Recommended for variable length) -// Format: [START=0x90] [MSG_ID] [LEN] [MSG] [CRC1] [CRC2] -// Overhead: 5 bytes +// Format: [START1=0x90] [START2=0x92] [MSG_ID] [LEN] [MSG] [CRC1] [CRC2] +// Overhead: 6 bytes message BasicFrameWithLen { - uint8 start_byte = 1 [(hex) = 0x90]; - BasicMessage payload = 2; - uint8 length = 3; - uint8 crc_byte1 = 4; - uint8 crc_byte2 = 5; + uint8 start_byte1 = 1 [(hex) = 0x90]; + uint8 start_byte2 = 2 [(hex) = 0x92]; + BasicMessage payload = 3; + uint8 length = 4; + uint8 crc_byte1 = 5; + uint8 crc_byte2 = 6; } -// BASIC FRAME LEN8 NO CRC -// Format: [START=0x90] [MSG_ID] [LEN] [MSG] -// Overhead: 3 bytes -message BasicFrameLen8NoCrc { - uint8 start_byte = 1 [(hex) = 0x90]; - BasicMessage payload = 2; - uint8 length = 3; +// BASIC FRAME WITH LEN NO CRC +// Format: [START1=0x90] [START2=0x96] [MSG_ID] [LEN] [MSG] +// Overhead: 4 bytes +message BasicFrameWithLenNoCrc { + uint8 start_byte1 = 1 [(hex) = 0x90]; + uint8 start_byte2 = 2 [(hex) = 0x96]; + BasicMessage payload = 3; + uint8 length = 4; } -// TINY FRAME LEN8 -// Format: [START] [MSG_ID] [LEN] [MSG] [CRC1] [CRC2] +// TINY FRAME WITH LEN (Recommended) +// Format: [START=0x71] [MSG_ID] [LEN] [MSG] [CRC1] [CRC2] // Overhead: 5 bytes -message TinyFrameLen8 { - uint8 start_byte = 1 [(hex) = 0x90]; +message TinyFrameWithLen { + uint8 start_byte = 1 [(hex) = 0x71]; BasicMessage payload = 2; uint8 length = 3; uint8 crc_byte1 = 4; uint8 crc_byte2 = 5; } -// TINY FRAME LEN8 NO CRC -// Format: [START] [MSG_ID] [LEN] [MSG] +// TINY FRAME WITH LEN NO CRC +// Format: [START=0x73] [MSG_ID] [LEN] [MSG] // Overhead: 3 bytes -message TinyFrameLen8NoCrc { - uint8 start_byte = 1 [(hex) = 0x90]; +message TinyFrameWithLenNoCrc { + uint8 start_byte = 1 [(hex) = 0x73]; BasicMessage payload = 2; uint8 length = 3; } // ============================================================================ -// LENGTH-PREFIXED VARIANTS (16-bit length, up to 65535 bytes) +// LENGTH-PREFIXED VARIANTS (2-byte length, up to 65535 bytes) // ============================================================================ -// MSG ID FRAME LEN16 +// MINIMAL FRAME WITH LEN16 // Format: [MSG_ID] [LEN_LO] [LEN_HI] [MSG] [CRC1] [CRC2] // Overhead: 5 bytes -message MsgIdFrameLen16 { +message MinimalFrameWithLen16 { BasicMessage payload = 1; uint16 length = 2; uint8 crc_byte1 = 3; uint8 crc_byte2 = 4; } -// MSG ID FRAME LEN16 NO CRC +// MINIMAL FRAME WITH LEN16 NO CRC // Format: [MSG_ID] [LEN_LO] [LEN_HI] [MSG] // Overhead: 3 bytes -message MsgIdFrameLen16NoCrc { +message MinimalFrameWithLen16NoCrc { BasicMessage payload = 1; uint16 length = 2; } -// BASIC FRAME LEN16 -// Format: [START=0x90] [MSG_ID] [LEN_LO] [LEN_HI] [MSG] [CRC1] [CRC2] -// Overhead: 6 bytes -message BasicFrameLen16 { - uint8 start_byte = 1 [(hex) = 0x90]; - BasicMessage payload = 2; - uint16 length = 3; - uint8 crc_byte1 = 4; - uint8 crc_byte2 = 5; +// BASIC FRAME WITH LEN16 (Recommended for large payloads) +// Format: [START1=0x90] [START2=0x93] [MSG_ID] [LEN_LO] [LEN_HI] [MSG] [CRC1] [CRC2] +// Overhead: 7 bytes +message BasicFrameWithLen16 { + uint8 start_byte1 = 1 [(hex) = 0x90]; + uint8 start_byte2 = 2 [(hex) = 0x93]; + BasicMessage payload = 3; + uint16 length = 4; + uint8 crc_byte1 = 5; + uint8 crc_byte2 = 6; } -// BASIC FRAME LEN16 NO CRC -// Format: [START=0x90] [MSG_ID] [LEN_LO] [LEN_HI] [MSG] -// Overhead: 4 bytes -message BasicFrameLen16NoCrc { - uint8 start_byte = 1 [(hex) = 0x90]; - BasicMessage payload = 2; - uint16 length = 3; +// BASIC FRAME WITH LEN16 NO CRC +// Format: [START1=0x90] [START2=0x97] [MSG_ID] [LEN_LO] [LEN_HI] [MSG] +// Overhead: 5 bytes +message BasicFrameWithLen16NoCrc { + uint8 start_byte1 = 1 [(hex) = 0x90]; + uint8 start_byte2 = 2 [(hex) = 0x97]; + BasicMessage payload = 3; + uint16 length = 4; } -// TINY FRAME LEN16 -// Format: [START] [MSG_ID] [LEN_LO] [LEN_HI] [MSG] [CRC1] [CRC2] +// TINY FRAME WITH LEN16 +// Format: [START=0x74] [MSG_ID] [LEN_LO] [LEN_HI] [MSG] [CRC1] [CRC2] // Overhead: 6 bytes -message TinyFrameLen16 { - uint8 start_byte = 1 [(hex) = 0x90]; +message TinyFrameWithLen16 { + uint8 start_byte = 1 [(hex) = 0x74]; BasicMessage payload = 2; uint16 length = 3; uint8 crc_byte1 = 4; uint8 crc_byte2 = 5; } -// TINY FRAME LEN16 NO CRC -// Format: [START] [MSG_ID] [LEN_LO] [LEN_HI] [MSG] +// TINY FRAME WITH LEN16 NO CRC +// Format: [START=0x75] [MSG_ID] [LEN_LO] [LEN_HI] [MSG] // Overhead: 4 bytes -message TinyFrameLen16NoCrc { - uint8 start_byte = 1 [(hex) = 0x90]; +message TinyFrameWithLen16NoCrc { + uint8 start_byte = 1 [(hex) = 0x75]; BasicMessage payload = 2; uint16 length = 3; } +// ============================================================================ +// SYSTEM/COMPONENT ID VARIANT (Recommended for multi-system networks) +// ============================================================================ + +// BASIC FRAME WITH SYS COMP +// Format: [START1=0x90] [START2=0x94] [SYS_ID] [COMP_ID] [MSG_ID] [MSG] [CRC1] [CRC2] +// Overhead: 7 bytes +message BasicFrameWithSysComp { + uint8 start_byte1 = 1 [(hex) = 0x90]; + uint8 start_byte2 = 2 [(hex) = 0x94]; + uint8 system_id = 3; + uint8 component_id = 4; + BasicMessage payload = 5; + uint8 crc_byte1 = 6; + uint8 crc_byte2 = 7; +} + // ============================================================================ // THIRD PARTY PROTOCOLS // ============================================================================ @@ -295,8 +319,8 @@ message MavlinkV2Signature { // Runtime frame format configuration message FrameFormatConfig { FrameFormatType format_type = 1; - uint8 start_byte = 2 [(hex) = 0x90]; - uint8 start_byte_2 = 3 [(hex) = 0x62]; + uint8 start_byte1 = 2 [(hex) = 0x90]; + uint8 start_byte2 = 3 [(hex) = 0x91]; bool crc_enabled = 4; bool signing_enabled = 5; }