294 lines
9.2 KiB
C
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
|