#ads-b #binrw #transponders #uavionix

gdl90

GDL90 message encoder/decoder

1 stable release

1.0.0 Oct 8, 2024

#12 in #ads-b

Download history 142/week @ 2024-10-05 25/week @ 2024-10-12 2/week @ 2024-10-19

169 downloads per month

MIT license

56KB
986 lines

Note: Work in progress, feel free to contribute.

gdl90

GDL90 Parser on crates.io GDL90 Parser on docs.rs GitHub last commit

This crate provides types and structures for handling GDL90 messages.

It uses Rust crates such as binrw and modular-bitfield to efficiently represent and manipulate these message types.

What is GDL90?

GDL 90 is designed to transmit, receive and decode Automatic Dependent Surveillance-Broadcast (ADS-B) messages via onboard datalink. It broadcasts your aircraft's position, velocity, projected track, altitude and flight identification to other equipped aircraft in your vicinity, as well as to ground-based transceivers maintained by the FAA.

Many ADS-B transponders (such as uAvionix ping20Si) use this protocol for their I/O interfaces. With this crate, you can easily integrate one of those in your rusty system.

You can find the full specification here.

Usage

[dependencies]
gdl90 = "0.1.0"
use std::io::Cursor;
use gdl90::datalink::Gdl90DatalinkMessage;
use gdl90::Gdl90Message;

// hardcoded, but you should read this from transponder
let parsed = gdl90::read_raw(&[0x7E, 0x00, 0x81, 0x41, 0xDB, 0xD0, 0x08, 0x02, 0xB3, 0x8B, 0x7E]).unwrap();
dbg!(&parsed);

match parsed.message_data {
    Gdl90DatalinkMessage::Heartbeat { status_byte_1, status_byte_2, uat_timestamp, message_counts } => { } ,
    Gdl90DatalinkMessage::Initialization { configuration_byte_1, configuration_byte_2 } => { },
    Gdl90DatalinkMessage::UplinkData { time_of_reception, payload } => { },
    Gdl90DatalinkMessage::HeightAboveTerrain { hat } => { },
    Gdl90DatalinkMessage::OwnshipReport { report } => { },
    Gdl90DatalinkMessage::TrafficReport { report } => { },
    Gdl90DatalinkMessage::OwnshipGeoometricAltitude { ownship_geo_altitude, vertical_metrics } => { },
    Gdl90DatalinkMessage::BasicReport() => { },
    Gdl90DatalinkMessage::LongReport() => { },
    Gdl90DatalinkMessage::Unknown => { },
}

Result:

&parsed = Gdl90Message {
    message_data: Heartbeat {
        status_byte_1: HeartbeatStatusByte1 {
            uat_initialized: true,
            ratcs: false,
            gps_batt_low: false,
            addr_type: false,
            ident: false,
            maint_reqd: false,
            gps_pos_valid: true,
        },
        status_byte_2: HeartbeatStatusByte2 {
            utc_ok: true,
            csa_not_available: false,
            csa_requested: true,
            timestamp_msb: false,
        },
        uat_timestamp: 53467,
        message_counts: 520,
    },
    frame_check_seq: 35763,
}

TODO:

  • Add more strong typying structures, no raw bits like B4, ...
  • Add and test remaining messages.
  • Try removing bitfields as maximum as possible, replacing it with custom types, using binrw directives and magic macros.

References

Dependencies

~2MB
~45K SLoC