Files
SSR/readsb/comm_b.h
T
2026-06-16 11:04:03 +08:00

294 lines
9.2 KiB
C

// Part of readsb, a Mode-S/ADSB/TIS message decoder.
//
// comm_b.h: Comm-B message decoding (header)
//
// Copyright (c) 2019 Michael Wolf <michael@mictronics.de>
//
// This code is based on a detached fork of dump1090-fa.
//
// Copyright (c) 2017 FlightAware, LLC
// Copyright (c) 2017 Oliver Jowett <oliver@mutability.co.uk>
//
// This file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This file is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef COMM_B_H
#define COMM_B_H
struct modesMessage
{
// Generic fields
unsigned char msg[MODES_LONG_MSG_BYTES]; // Binary message.
unsigned char verbatim[MODES_LONG_MSG_BYTES]; // Binary message, as originally received before correction
double signalLevel; // RSSI, in the range [0..1], as a fraction of full-scale power
struct client *client; // network client this message came from, NULL otherwise
struct aircraft *aircraft; // tracked aircraft associated with this message or NULL
struct messageBuffer *messageBuffer;
int64_t timestamp; // Timestamp of the message (12MHz clock)
int64_t sysTimestamp; // Timestamp of the message (system time)
uint64_t receiverId; // zero if not transmitted
int msgtype; // Downlink format #
int msgbits; // Number of bits in message
int score; // Scoring from scoreModesMessage, if used
int receiverCountMlat; // number of receivers for MLAT messages
int mlatEPU; // estimated position uncertainty
int correctedbits; // No. of bits corrected
int decodeResult;
uint32_t crc; // Message CRC
uint32_t addr; // Address Announced
uint32_t maybe_addr; // probably the address, good chance to be wrong
addrtype_t addrtype; // address format / source
int8_t remote; // If set this message is from a remote station
int8_t sbs_in; // Signifies this message is coming from basestation input
int8_t address_reliable;
int8_t sbsMsgType; // SBS message type
int8_t reduce_forward; // forward this message for reduced beast output
int8_t garbage; // from garbage receiver
int8_t duplicate; // associated position is a duplicate
int8_t duplicate_checked; // duplicate check done
int8_t pos_bad; // speed_check failed
int8_t pos_ignore; // associated position is old / delayed / misc error
int8_t pos_old; // associated position is old / delayed / misc error
int8_t pos_receiver_range_exceeded;
int8_t trackUnreliable;
int8_t speedUnreliable;
int8_t in_disc_cache;
int8_t jsonPositionOutputEmit;
datasource_t source; // Characterizes the overall message source
// Raw data, just extracted directly from the message
// The names reflect the field names in Annex 4
unsigned IID; // extracted from CRC of DF11s
unsigned AA;
unsigned AC;
unsigned CA;
unsigned CC;
unsigned CF;
unsigned DR;
unsigned FS;
unsigned ID;
unsigned KE;
unsigned ND;
unsigned RI;
unsigned SL;
unsigned UM;
unsigned VS;
unsigned metype; // DF17/18 ME type
unsigned mesub; // DF17/18 ME subtype
unsigned char MB[7];
unsigned char MD[10];
unsigned char ME[7];
unsigned char MV[7];
// Decoded data
bool baro_alt_valid;
bool geom_alt_valid;
bool track_valid;
bool track_rate_valid;
bool heading_valid;
bool roll_valid;
bool gs_valid;
bool ias_valid;
bool tas_valid;
bool mach_valid;
bool baro_rate_valid;
bool geom_rate_valid;
bool squawk_valid;
bool callsign_valid;
bool cpr_valid;
bool cpr_odd;
bool cpr_decoded;
bool cpr_relative;
bool category_valid;
bool geom_delta_valid;
bool from_mlat;
bool from_tisb;
bool spi_valid;
bool spi;
bool alert_valid;
bool alert;
bool emergency_valid;
bool sbs_pos_valid;
bool alt_q_bit;
bool acas_ra_valid;
bool geom_alt_derived;
bool wind_valid;
bool oat_valid;
bool static_pressure_valid;
bool turbulence_valid;
bool humidity_valid;
bool met_source_valid;
bool squawk_emergency_valid;
bool squawk_emergency;
// valid if baro_alt_valid:
int baro_alt; // Altitude in either feet or meters
altitude_unit_t baro_alt_unit; // the unit used for altitude
// valid if geom_alt_valid:
int geom_alt; // Altitude in either feet or meters
altitude_unit_t geom_alt_unit; // the unit used for altitude
// following fields are valid if the corresponding _valid field is set:
int geom_delta; // Difference between geometric and baro alt
float heading; // ground track or heading, degrees (0-359). Reported directly or computed from from EW and NS velocity
heading_type_t heading_type; // how to interpret 'track_or_heading'
float track_rate; // Rate of change of track, degrees/second
float roll; // Roll, degrees, negative is left roll
struct
{
// Groundspeed, kts, reported directly or computed from from EW and NS velocity
// For surface movement, this has different interpretations for v0 and v2; both
// fields are populated. The tracking layer will update "gs.selected".
float v0;
float v2;
float selected;
} gs;
unsigned ias; // Indicated airspeed, kts
unsigned tas; // True airspeed, kts
double mach; // Mach number
int baro_rate; // Rate of change of barometric altitude, feet/minute
int geom_rate; // Rate of change of geometric (GNSS / INS) altitude, feet/minute
char callsign[16]; // 8 chars flight number, NUL-terminated
uint32_t squawkHex; // 13 bits identity (Squawk), encoded as 4 hex digits
uint32_t squawkDec; // Squawk as a decimal number
unsigned category; // A0 - D7 encoded as a single hex byte
emergency_t emergency; // emergency/priority status
// valid if cpr_valid
cpr_type_t cpr_type; // The encoding type used (surface, airborne, coarse TIS-B)
uint32_t cpr_lat; // Non decoded latitude.
uint32_t cpr_lon; // Non decoded longitude.
uint32_t cpr_nucp; // NUCp/NIC value implied by message type
airground_t airground; // air/ground state
// valid if cpr_decoded:
double decoded_lat;
double decoded_lon;
unsigned decoded_nic;
unsigned decoded_rc;
double distance_traveled; // set in speed_check, zero is invalid
double receiver_distance; // distance to receiver
float calculated_track; // set in speed_check, -1 is invalid
// meteorological
int wind_speed;
float wind_direction;
float oat;
int static_pressure;
int turbulence;
float humidity;
int met_source;
commb_format_t commb_format; // Inferred format of a comm-b message
// various integrity/accuracy things
struct
{
bool nic_a_valid;
bool nic_b_valid;
bool nic_c_valid;
bool nic_baro_valid;
bool nac_p_valid;
bool nac_v_valid;
bool gva_valid;
bool sda_valid;
bool nic_a; // if nic_a_valid
bool nic_b; // if nic_b_valid
bool nic_c; // if nic_c_valid
bool nic_baro; // if nic_baro_valid
unsigned nac_p; // if nac_p_valid
unsigned nac_v; // if nac_v_valid
unsigned sil; // if sil_type != SIL_INVALID
unsigned gva; // if gva_valid
unsigned sda; // if sda_valid
sil_type_t sil_type;
} accuracy;
// Operational Status
struct
{
sil_type_t sil_type;
heading_type_t tah;
heading_type_t hrd;
enum
{
ANGLE_HEADING, ANGLE_TRACK
} track_angle;
unsigned cc_lw;
unsigned cc_antenna_offset;
unsigned valid : 1;
unsigned version : 3;
unsigned om_acas_ra : 1;
unsigned om_ident : 1;
unsigned om_atc : 1;
unsigned om_saf : 1;
unsigned cc_acas : 1;
unsigned cc_cdti : 1;
unsigned cc_1090_in : 1;
unsigned cc_arv : 1;
unsigned cc_ts : 1;
unsigned cc_tc : 2;
unsigned cc_uat_in : 1;
unsigned cc_poa : 1;
unsigned cc_b2_low : 1;
unsigned cc_lw_valid : 1;
} opstatus;
// combined:
// Target State & Status (ADS-B V2 only)
// Comm-B BDS4,0 Vertical Intent
struct
{
unsigned fms_altitude; // FMS selected altitude
unsigned mcp_altitude; // MCP/FCU selected altitude
float qnh; // altimeter setting (QFE or QNH/QNE), millibars
float heading; // heading, degrees (0-359) (could be magnetic or true heading; magnetic recommended)
bool heading_valid;
bool fms_altitude_valid;
bool mcp_altitude_valid;
bool qnh_valid;
bool modes_valid;
heading_type_t heading_type;
nav_altitude_source_t altitude_source;
nav_modes_t modes;
} nav;
};
void decodeCommB (struct modesMessage *mm);
int checkAcasRaValid(unsigned char *MV, struct modesMessage *mm, int debug);
#endif