Documentation
¶
Overview ¶
Package adsb decodes Mode S downlink frames captured at 1090 MHz — both short-form (56-bit) surveillance replies and long-form (112-bit) extended squitter / ADS-B frames.
Wrap-vs-native judgement ¶
Native. The Mode S frame format and the ADS-B Extended Squitter sub-message family are fully published (ICAO Annex 10 Vol IV + RTCA DO-260 + EUROCAE ED-102). The CRC-24 generator (G(x) = 0x1FFF409) is a textbook bit-walking polynomial division. Type-code dispatch is a static switch over a 5-bit field. Pasting a hex blob captured by dump1090 / readsb / a Flipper-adjacent SDR feed is enough — no vendor SDK, no protocol negotiation, no hardware path.
What this package covers ¶
- Frame envelope: Downlink Format (DF, 5 bits) detection with a documented name table covering all 32 DF slots (DF0 / DF4 / DF5 / DF11 / DF16 / DF17 / DF18 / DF19 / DF20 / DF21 / DF24+ Comm-D extended length).
- Frame length validation: short (56 bits = 7 bytes) for DF0/4/5/11; long (112 bits = 14 bytes) for DF16-22 and DF24+.
- ICAO 24-bit aircraft address extraction for DF11/17/18 (where the AA field is in the clear; for other DFs the address is XOR-overlaid with the parity field — left to callers to recover via re-interrogation).
- Mode S CRC-24 validation (polynomial 0xFFF409, init 0, no reflection) — computes the expected parity field over the data portion and compares to the transmitted parity. Surfaces both the captured PI and the computed value for diffing.
- DF17 (ADS-B) Type Code dispatch covering the operationally important sub-types: TC 1-4 (Aircraft Identification with 8-character callsign decoded from the 6-bit AIS / IA-5 alphabet and emitter category lookup), TC 5-8 (Surface Position with movement decode, ground track, and raw CPR), TC 9-18 / 20-22 (Airborne Position with altitude decode from the 12-bit Q-bit field, raw CPR latitude/longitude, and odd/even frame flag), TC 19 (Airborne Velocity: subtype 1/2 ground speed and heading, subtype 3/4 airspeed and magnetic heading, vertical rate with source flag), TC 28 (Aircraft Status: emergency code / squawk), TC 29 (Target State and Status), TC 31 (Aircraft Operation Status).
What this package does NOT cover (deliberately out of scope) ¶
- CPR (Compact Position Reporting) lat/lon resolution: global resolution requires pairing an even-frame and an odd-frame from the same aircraft within ~10 seconds; this decoder exposes the raw 17-bit CPR values + the odd/even flag so a higher-level workflow / Spec can do the pairing. Local-CPR resolution (against a reference position) is intentionally deferred until the receiving side has somewhere to put the reference; otherwise the output would be misleading.
- DF1/2/3/6-10/12-15/22/23 reserved slot bodies — the DF name is reported but no body decode is attempted because no civil aviation traffic uses these slots in practice (and the bodies have no published civilian spec).
- Comm-B BDS register decoding for DF20/21 — the MB field is decoded register-by-register with validity-gated inference (BDS 2,0 / 4,0 / 5,0 / 6,0 / 1,7, with BDS 1,0 inferred); see commb.go. The surveillance AC13 altitude (DF0/4/16/20) and ID13 squawk (DF5/21) header fields — including Gillham (Mode C) gray-coded altitude and emergency-squawk flagging — are decoded in altid.go. Meteorological BDS 4,4 / 4,5 registers remain deferred.
- TIS-B (DF18) imitation-of-other-format payload variants: DF18 is decoded as if it were DF17, which is correct for the most common CF=0/CF=1 case. CF=2..7 sub-formats (ADS-R, fine TIS-B) are out of scope.
- Live demodulation from raw I/Q samples — frames must be pre-decoded to hex by an upstream demodulator (dump1090 --raw output, for instance).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ADSB ¶
type ADSB struct {
TC int `json:"tc"`
TCName string `json:"tc_name"`
Identification *Identification `json:"identification,omitempty"`
AirbornePosition *AirbornePosition `json:"airborne_position,omitempty"`
AirborneVelocity *AirborneVelocity `json:"airborne_velocity,omitempty"`
SurfacePosition *SurfacePosition `json:"surface_position,omitempty"`
}
ADSB carries the decoded Extended Squitter ME field (DF17 / DF18). Only one of the sub-pointers is set per frame — the one that matches the Type Code.
type AirbornePosition ¶
type AirbornePosition struct {
SurveillanceStatus int `json:"surveillance_status"`
AltitudeSource string `json:"altitude_source"`
AltitudeFt int `json:"altitude_ft,omitempty"`
AltitudeValid bool `json:"altitude_valid"`
CPRFormat int `json:"cpr_format"`
CPRLatRaw int `json:"cpr_lat_raw"`
CPRLonRaw int `json:"cpr_lon_raw"`
}
AirbornePosition is the decoded TC 9-18 / 20-22 Airborne Position message. Latitude/longitude are not resolved here — the caller pairs an even + odd frame for a global CPR solve. Altitude is decoded from the 12-bit field with the Q-bit (25-ft vs 100-ft resolution).
type AirborneVelocity ¶
type AirborneVelocity struct {
Subtype int `json:"subtype"`
SubtypeName string `json:"subtype_name"`
GroundSpeedKts *int `json:"ground_speed_kts,omitempty"`
GroundTrackDeg *float64 `json:"ground_track_deg,omitempty"`
AirspeedKts *int `json:"airspeed_kts,omitempty"`
AirspeedIsIAS bool `json:"airspeed_is_ias,omitempty"`
MagneticHeadingDeg *float64 `json:"magnetic_heading_deg,omitempty"`
VerticalRateFPM int `json:"vertical_rate_fpm"`
VerticalRateSource string `json:"vertical_rate_source"`
}
AirborneVelocity is the decoded TC 19 Airborne Velocity message. Subtypes 1/2 carry ground speed + ground track; subtypes 3/4 carry airspeed + magnetic heading.
type AltID ¶ added in v0.530.0
type AltID struct {
AltitudeFt *int `json:"altitude_ft,omitempty"`
AltitudeEncoding string `json:"altitude_encoding,omitempty"` // 25ft / Gillham 100ft / metric
AltitudeNote string `json:"altitude_note,omitempty"`
Squawk string `json:"squawk,omitempty"`
SquawkEmergency string `json:"squawk_emergency,omitempty"`
}
AltID is the decoded AC13 altitude or ID13 squawk header of a surveillance frame.
type BDS17Capability ¶ added in v0.529.0
type BDS17Capability struct {
SupportedRegisters []string `json:"supported_registers"`
}
BDS17Capability is the BDS 1,7 GICB capability report.
type BDS20Identification ¶ added in v0.529.0
type BDS20Identification struct {
Callsign string `json:"callsign"`
}
BDS20Identification is the BDS 2,0 callsign.
type BDS40VerticalIntention ¶ added in v0.529.0
type BDS40VerticalIntention struct {
MCPSelectedAltitudeFt *int `json:"mcp_selected_altitude_ft,omitempty"`
FMSSelectedAltitudeFt *int `json:"fms_selected_altitude_ft,omitempty"`
BarometricPressureMB *float64 `json:"barometric_pressure_mb,omitempty"`
}
BDS40VerticalIntention is the BDS 4,0 selected-vertical-intention report.
type BDS50TrackTurn ¶ added in v0.529.0
type BDS50TrackTurn struct {
RollAngleDeg *float64 `json:"roll_angle_deg,omitempty"`
TrueTrackDeg *float64 `json:"true_track_angle_deg,omitempty"`
GroundSpeedKts *int `json:"ground_speed_kts,omitempty"`
TrackAngleRate *float64 `json:"track_angle_rate_deg_s,omitempty"`
TrueAirspeedKts *int `json:"true_airspeed_kts,omitempty"`
}
BDS50TrackTurn is the BDS 5,0 track-and-turn report.
type BDS60HeadingSpeed ¶ added in v0.529.0
type BDS60HeadingSpeed struct {
MagneticHeadingDeg *float64 `json:"magnetic_heading_deg,omitempty"`
IndicatedAirspeed *int `json:"indicated_airspeed_kts,omitempty"`
Mach *float64 `json:"mach,omitempty"`
VerticalRateBaroFPM *int `json:"vertical_rate_barometric_fpm,omitempty"`
VerticalRateInsFPM *int `json:"vertical_rate_inertial_fpm,omitempty"`
}
BDS60HeadingSpeed is the BDS 6,0 heading-and-speed report.
type CommB ¶ added in v0.529.0
type CommB struct {
MBHex string `json:"mb_hex"`
// InferredRegisters lists every BDS code whose validity gate passes.
// Exactly one is the normal case; an empty list means no known
// register fit (the MB may be a register this decoder does not cover);
// more than one is surfaced with an ambiguity note.
InferredRegisters []string `json:"inferred_registers"`
BDS20 *BDS20Identification `json:"bds20_identification,omitempty"`
BDS40 *BDS40VerticalIntention `json:"bds40_selected_vertical_intention,omitempty"`
BDS50 *BDS50TrackTurn `json:"bds50_track_turn_report,omitempty"`
BDS60 *BDS60HeadingSpeed `json:"bds60_heading_speed_report,omitempty"`
BDS17 *BDS17Capability `json:"bds17_gicb_capability,omitempty"`
Notes []string `json:"notes,omitempty"`
}
CommB is the decoded Comm-B (DF20/21) MB field.
type Frame ¶
type Frame struct {
HexInput string `json:"hex_input"`
BitCount int `json:"bit_count"`
DF int `json:"df"`
DFName string `json:"df_name"`
CA *int `json:"ca,omitempty"`
CAName string `json:"ca_name,omitempty"`
ICAOAddress string `json:"icao_address,omitempty"`
CRC string `json:"crc"`
CRCExpected string `json:"crc_expected"`
CRCValid bool `json:"crc_valid"`
ADSB *ADSB `json:"adsb,omitempty"`
CommB *CommB `json:"comm_b,omitempty"`
// Surveillance carries the AC13 pressure altitude (DF0/4/16/20) or
// the ID13 Mode-A squawk (DF5/21) from the 13-bit field at bits 20-32.
Surveillance *AltID `json:"surveillance,omitempty"`
}
Frame is the decoded view of a single Mode S downlink frame.
func Decode ¶
Decode parses a hex-encoded Mode S frame into a structured Frame view. Accepts ':', '-', '_', whitespace as separators and a leading '0x' prefix.
func DecodeBytes ¶
DecodeBytes parses a 7-byte (short) or 14-byte (long) Mode S frame into a Frame.
type Identification ¶
type Identification struct {
Category int `json:"category"`
CategoryName string `json:"category_name"`
Callsign string `json:"callsign"`
}
Identification is the decoded TC 1-4 Aircraft Identification message: 8-character callsign + emitter category.
type SurfacePosition ¶
type SurfacePosition struct {
Movement int `json:"movement"`
GroundSpeedKts *float64 `json:"ground_speed_kts,omitempty"`
GroundTrackDeg *float64 `json:"ground_track_deg,omitempty"`
GroundTrackValid bool `json:"ground_track_valid"`
CPRFormat int `json:"cpr_format"`
CPRLatRaw int `json:"cpr_lat_raw"`
CPRLonRaw int `json:"cpr_lon_raw"`
}
SurfacePosition is the decoded TC 5-8 Surface Position message — for aircraft on the ground.