Add skeletal BDS0,5 decoding.
These messages duplicate ADS-B messages so it's not clear why they are being interrogated for, and we don't really trust them enough to do anything with the position information. But recognizing/decoding them where possible does let us exclude other Comm-B message types, avoiding some false positives.
This commit is contained in:
parent
c148fdca84
commit
825f959e4d
52
comm_b.c
52
comm_b.c
|
|
@ -32,6 +32,7 @@ static int decodeBDS40(struct modesMessage *mm, bool store);
|
|||
static int decodeBDS44(struct modesMessage *mm, bool store);
|
||||
static int decodeBDS50(struct modesMessage *mm, bool store);
|
||||
static int decodeBDS60(struct modesMessage *mm, bool store);
|
||||
static int decodeBDS05(struct modesMessage *mm, bool store);
|
||||
|
||||
static CommBDecoderFn comm_b_decoders[] = {
|
||||
&decodeEmptyResponse,
|
||||
|
|
@ -42,7 +43,8 @@ static CommBDecoderFn comm_b_decoders[] = {
|
|||
&decodeBDS40,
|
||||
&decodeBDS50,
|
||||
&decodeBDS60,
|
||||
&decodeBDS44
|
||||
&decodeBDS44,
|
||||
&decodeBDS05
|
||||
};
|
||||
|
||||
void decodeCommB(struct modesMessage *mm)
|
||||
|
|
@ -908,3 +910,51 @@ static int decodeBDS44(struct modesMessage *mm, bool store)
|
|||
|
||||
return score;
|
||||
}
|
||||
|
||||
// BDS0,5 extended squitter airborne position
|
||||
// (apparently this gets queried via comm-b sometimes??)
|
||||
// We don't try to _use_ this as a position, but we can
|
||||
// at least try to recognize it, to exclude other
|
||||
// comm-b types (in particular they can be mistaken for MRAR)
|
||||
static int decodeBDS05(struct modesMessage *mm, bool store)
|
||||
{
|
||||
// We recognize these by matching the position altitude against
|
||||
// the altitude in the surrounding message, so we need a
|
||||
// DF20 not a DF21
|
||||
if (mm->msgtype != 20)
|
||||
return 0;
|
||||
|
||||
unsigned char *msg = mm->MB;
|
||||
|
||||
unsigned typecode = getbits(msg, 1, 5);
|
||||
if (typecode < 9 || typecode > 18)
|
||||
return 0; // only consider typecodes that could be an airborne position with baro altitude
|
||||
|
||||
unsigned t_bit = getbit(msg, 21);
|
||||
if (t_bit) // unlikely
|
||||
return 0;
|
||||
|
||||
unsigned ac12 = getbits(msg, 9, 20);
|
||||
if (!ac12)
|
||||
return 0;
|
||||
|
||||
// Insert M=0 to make an AC13 value, match against the
|
||||
// AC13 value in the surrounding message
|
||||
unsigned ac13 = ((ac12 & 0x0FC0) << 1) | (ac12 & 0x003F);
|
||||
if (mm->AC != ac13)
|
||||
return 0; // no altitude match
|
||||
|
||||
unsigned lat = getbits(msg, 23, 39);
|
||||
unsigned lon = getbits(msg, 40, 56);
|
||||
if (lat == 0 || lon == 0) // unlikely position
|
||||
return 0;
|
||||
|
||||
if (store) {
|
||||
mm->commb_format = COMMB_AIRBORNE_POSITION;
|
||||
// No further decoding done, we don't really trust this
|
||||
// enough to use as real input to CPR
|
||||
}
|
||||
|
||||
// Score this high enough to override everything else
|
||||
return 100;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,7 +211,8 @@ typedef enum {
|
|||
COMMB_VERTICAL_INTENT,
|
||||
COMMB_TRACK_TURN,
|
||||
COMMB_HEADING_SPEED,
|
||||
COMMB_MRAR
|
||||
COMMB_MRAR,
|
||||
COMMB_AIRBORNE_POSITION
|
||||
} commb_format_t;
|
||||
|
||||
typedef enum {
|
||||
|
|
|
|||
2
mode_s.c
2
mode_s.c
|
|
@ -1699,6 +1699,8 @@ static const char *commb_format_to_string(commb_format_t format) {
|
|||
return "BDS6,0 Heading and speed report";
|
||||
case COMMB_MRAR:
|
||||
return "BDS4,4 Meterological routine air report";
|
||||
case COMMB_AIRBORNE_POSITION:
|
||||
return "BDS0,5 Extended squitter airborne position";
|
||||
default:
|
||||
return "unknown format";
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue