Decode/emit emergency/priority status

This commit is contained in:
Oliver Jowett 2018-01-09 14:43:58 +00:00
parent 079061df3c
commit ea1e9c336b
5 changed files with 60 additions and 2 deletions

View file

@ -215,6 +215,18 @@ typedef enum {
NAV_MODE_TCAS = 32
} nav_modes_t;
// Matches encoding of the ES type 28/1 emergency/priority status subfield
typedef enum {
EMERGENCY_NONE = 0,
EMERGENCY_GENERAL = 1,
EMERGENCY_LIFEGUARD = 2,
EMERGENCY_MINFUEL = 3,
EMERGENCY_NORDO = 4,
EMERGENCY_UNLAWFUL = 5,
EMERGENCY_DOWNED = 6,
EMERGENCY_RESERVED = 7
} emergency_t;
#define MODES_NON_ICAO_ADDRESS (1<<24) // Set on addresses to indicate they are not ICAO addresses
#define MODES_DEBUG_DEMOD (1<<0)
@ -450,6 +462,7 @@ struct modesMessage {
unsigned spi : 1;
unsigned alert_valid : 1;
unsigned alert : 1;
unsigned emergency_valid : 1;
unsigned metype; // DF17/18 ME type
unsigned mesub; // DF17/18 ME subtype
@ -486,6 +499,7 @@ struct modesMessage {
unsigned squawk; // 13 bits identity (Squawk), encoded as 4 hex digits
char callsign[9]; // 8 chars flight number, NUL-terminated
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)

View file

@ -986,7 +986,10 @@ static void decodeESAircraftStatus(struct modesMessage *mm, int check_imf)
mm->mesub = getbits(me, 6, 8);
if (mm->mesub == 1) { // Emergency status squawk field
int ID13Field = getbits(me, 12, 24);
mm->emergency_valid = 1;
mm->emergency = (emergency_t) getbits(me, 9, 11);
unsigned ID13Field = getbits(me, 12, 24);
if (ID13Field) {
mm->squawk_valid = 1;
mm->squawk = decodeID13Field(ID13Field);
@ -1130,7 +1133,9 @@ static void decodeESTargetStatus(struct modesMessage *mm, int check_imf)
}
// 54-56: emergency/priority (ignored)
// 54-56: emergency/priority
mm->emergency_valid = 1;
mm->emergency = (emergency_t) getbits(me, 54, 56);
} else if (mm->mesub == 1) { // Target state and status, V2
// 8: SIL
unsigned is_fms = getbit(me, 9);
@ -1590,6 +1595,20 @@ static const char *sil_type_to_string(sil_type_t type)
}
}
static const char *emergency_to_string(emergency_t emergency)
{
switch (emergency) {
case EMERGENCY_NONE: return "no emergency";
case EMERGENCY_GENERAL: return "general emergency (7700)";
case EMERGENCY_LIFEGUARD: return "lifeguard / medical emergency";
case EMERGENCY_MINFUEL: return "minimum fuel";
case EMERGENCY_NORDO: return "no communications (7600)";
case EMERGENCY_UNLAWFUL: return "unlawful interference (7500)";
case EMERGENCY_DOWNED: return "downed aircraft";
default: return "reserved";
}
}
static void print_hex_bytes(unsigned char *data, size_t len) {
size_t i;
for (i = 0; i < len; ++i) {
@ -2050,6 +2069,9 @@ void displayModesMessage(struct modesMessage *mm) {
printf(" Nav modes: %s\n", nav_modes_to_string(mm->nav.modes));
}
if (mm->emergency_valid) {
printf(" Emergency/priority: %s\n", emergency_to_string(mm->emergency));
}
printf("\n");
fflush(stdout);

View file

@ -1977,6 +1977,20 @@ static const char *airground_string(airground_t ag)
}
}
static const char *emergency_enum_string(emergency_t emergency)
{
switch (emergency) {
case EMERGENCY_NONE: return "none";
case EMERGENCY_GENERAL: return "general";
case EMERGENCY_LIFEGUARD: return "lifeguard";
case EMERGENCY_MINFUEL: return "minfuel";
case EMERGENCY_NORDO: return "nordo";
case EMERGENCY_UNLAWFUL: return "unlawful";
case EMERGENCY_DOWNED: return "downed";
default: return "reserved";
}
}
static void writeFATSVBanner()
{
char *p = prepareWrite(&Modes.fatsv_out, TSV_MAX_PACKET_SIZE);
@ -2152,6 +2166,7 @@ static void writeFATSV()
p = appendFATSVMeta(p, end, "nav_heading", a, &a->nav_heading_valid, "%.1f", a->nav_heading);
p = appendFATSVMeta(p, end, "nav_modes", a, &a->nav_modes_valid, "{%s}", nav_modes_string(a->nav_modes));
p = appendFATSVMeta(p, end, "nav_qnh", a, &a->nav_qnh_valid, "%.1f", a->nav_qnh);
p = appendFATSVMeta(p, end, "emergency", a, &a->emergency_valid, "%s", emergency_enum_string(a->emergency));
// if we didn't get anything interesting, bail out.
// We don't need to do anything special to unwind prepareWrite().

View file

@ -876,6 +876,10 @@ struct aircraft *trackUpdateFromMessage(struct modesMessage *mm)
a->squawk = mm->squawk;
}
if (mm->emergency_valid && accept_data(&a->emergency_valid, mm->source)) {
a->emergency = mm->emergency;
}
if (mm->altitude_geom_valid && accept_data(&a->altitude_geom_valid, mm->source)) {
a->altitude_geom = altitude_to_feet(mm->altitude_geom, mm->altitude_geom_unit);
}

View file

@ -140,6 +140,9 @@ struct aircraft {
data_validity squawk_valid;
unsigned squawk; // Squawk
data_validity emergency_valid;
emergency_t emergency; // Emergency/priority status
unsigned category; // Aircraft category A0 - D7 encoded as a single hex byte
data_validity airground_valid;