Add some oneoff tools for comm-b decoding testing
This commit is contained in:
parent
d33b1160f2
commit
564f033087
3
Makefile
3
Makefile
|
@ -70,3 +70,6 @@ benchmarks: convert_benchmark
|
||||||
|
|
||||||
oneoff/convert_benchmark: oneoff/convert_benchmark.o convert.o util.o
|
oneoff/convert_benchmark: oneoff/convert_benchmark.o convert.o util.o
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -g -o $@ $^ -lm
|
$(CC) $(CPPFLAGS) $(CFLAGS) -g -o $@ $^ -lm
|
||||||
|
|
||||||
|
oneoff/decode_comm_b: oneoff/decode_comm_b.o comm_b.o ais_charset.o
|
||||||
|
$(CC) $(CPPFLAGS) $(CFLAGS) -g -o $@ $^ -lm
|
||||||
|
|
172
oneoff/decode_comm_b.c
Normal file
172
oneoff/decode_comm_b.c
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../dump1090.h"
|
||||||
|
#include "../comm_b.h"
|
||||||
|
|
||||||
|
char last_callsign[8];
|
||||||
|
double last_callsign_ts = 0;
|
||||||
|
double last_track = -1;
|
||||||
|
double last_track_ts = 0;
|
||||||
|
double last_magnetic = -1;
|
||||||
|
double last_magnetic_ts = 0;
|
||||||
|
double last_gs = -1;
|
||||||
|
double last_gs_ts = 0;
|
||||||
|
double last_ias = -1;
|
||||||
|
double last_ias_ts = 0;
|
||||||
|
double last_tas = -1;
|
||||||
|
double last_tas_ts = 0;
|
||||||
|
double last_mach = -1;
|
||||||
|
double last_mach_ts = 0;
|
||||||
|
|
||||||
|
double angle_difference(double h1, double h2)
|
||||||
|
{
|
||||||
|
float delta = fabs(h1 - h2);
|
||||||
|
if (delta > 180.0)
|
||||||
|
delta = 360.0 - delta;
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
void process(double timestamp, const char *line, struct modesMessage *mm)
|
||||||
|
{
|
||||||
|
decodeCommB(mm);
|
||||||
|
|
||||||
|
printf("line\t%s\tformat\t", line);
|
||||||
|
|
||||||
|
switch (mm->commb_format) {
|
||||||
|
#define EMIT(x) case COMMB_ ## x: printf("%s", #x); break
|
||||||
|
EMIT(UNKNOWN);
|
||||||
|
EMIT(AMBIGUOUS);
|
||||||
|
EMIT(EMPTY_RESPONSE);
|
||||||
|
EMIT(DATALINK_CAPS);
|
||||||
|
EMIT(GICB_CAPS);
|
||||||
|
EMIT(AIRCRAFT_IDENT);
|
||||||
|
EMIT(ACAS_RA);
|
||||||
|
EMIT(VERTICAL_INTENT);
|
||||||
|
EMIT(TRACK_TURN);
|
||||||
|
EMIT(HEADING_SPEED);
|
||||||
|
#undef EMIT
|
||||||
|
default:
|
||||||
|
printf("%s", "UNHANDLED"); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int suspicious = 0;
|
||||||
|
|
||||||
|
if (mm->callsign_valid) {
|
||||||
|
printf("\tcallsign\t%s", mm->callsign);
|
||||||
|
if ((timestamp - last_callsign_ts) < 30.0 && strcmp(last_callsign, mm->callsign)) {
|
||||||
|
suspicious = 1;
|
||||||
|
}
|
||||||
|
memcpy(last_callsign, mm->callsign, sizeof(last_callsign));
|
||||||
|
last_callsign_ts = timestamp;
|
||||||
|
}
|
||||||
|
if (mm->heading_valid && mm->heading_type == HEADING_GROUND_TRACK) {
|
||||||
|
printf("\ttrack\t%.1f", mm->heading);
|
||||||
|
if ((timestamp - last_track_ts) < 10.0 && angle_difference(last_track, mm->heading) > 45) {
|
||||||
|
suspicious = 1;
|
||||||
|
}
|
||||||
|
if ((timestamp - last_magnetic_ts) < 10.0 && angle_difference(last_magnetic, mm->heading) > 45) {
|
||||||
|
suspicious = 1;
|
||||||
|
}
|
||||||
|
last_track = mm->heading;
|
||||||
|
last_track_ts = timestamp;
|
||||||
|
}
|
||||||
|
if (mm->heading_valid && mm->heading_type == HEADING_MAGNETIC) {
|
||||||
|
printf("\tmagnetic\t%.1f", mm->heading);
|
||||||
|
if ((timestamp - last_magnetic_ts) < 10.0 && angle_difference(last_magnetic, mm->heading) > 45) {
|
||||||
|
suspicious = 1;
|
||||||
|
}
|
||||||
|
if ((timestamp - last_track_ts) < 10.0 && angle_difference(last_track, mm->heading) > 45) {
|
||||||
|
suspicious = 1;
|
||||||
|
}
|
||||||
|
last_magnetic = mm->heading;
|
||||||
|
last_magnetic_ts = timestamp;
|
||||||
|
}
|
||||||
|
if (mm->track_rate_valid) {
|
||||||
|
printf("\ttrack_rate\t%.2f", mm->track_rate);
|
||||||
|
}
|
||||||
|
if (mm->roll_valid) {
|
||||||
|
printf("\troll\t%.1f", mm->roll);
|
||||||
|
}
|
||||||
|
if (mm->gs_valid) {
|
||||||
|
printf("\tgs\t%.1f", mm->gs.selected);
|
||||||
|
if ((timestamp - last_gs_ts) < 10.0 && fabs(last_gs - mm->gs.selected) > 50) {
|
||||||
|
suspicious = 1;
|
||||||
|
}
|
||||||
|
last_gs = mm->gs.selected;
|
||||||
|
last_gs_ts = timestamp;
|
||||||
|
}
|
||||||
|
if (mm->ias_valid) {
|
||||||
|
printf("\tias\t%d", mm->ias);
|
||||||
|
if ((timestamp - last_ias_ts) < 10.0 && abs(last_ias - mm->ias) > 50) {
|
||||||
|
suspicious = 1;
|
||||||
|
}
|
||||||
|
last_ias = mm->ias;
|
||||||
|
last_ias_ts = timestamp;
|
||||||
|
}
|
||||||
|
if (mm->tas_valid) {
|
||||||
|
printf("\ttas\t%d", mm->tas);
|
||||||
|
if ((timestamp - last_tas_ts) < 10.0 && abs(last_tas - mm->tas) > 50) {
|
||||||
|
suspicious = 1;
|
||||||
|
}
|
||||||
|
last_tas = mm->tas;
|
||||||
|
last_tas_ts = timestamp;
|
||||||
|
}
|
||||||
|
if (mm->mach_valid) {
|
||||||
|
printf("\tmach\t%.3f", mm->mach);
|
||||||
|
if ((timestamp - last_mach_ts) < 10.0 && abs(last_mach - mm->mach) > 0.1) {
|
||||||
|
suspicious = 1;
|
||||||
|
}
|
||||||
|
last_mach = mm->mach;
|
||||||
|
last_mach_ts = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (suspicious) {
|
||||||
|
printf("\tsuspicious\tyes!");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
/* unused */ (void)argc;
|
||||||
|
/* unused */ (void)argv;
|
||||||
|
|
||||||
|
char line[1024];
|
||||||
|
|
||||||
|
while (fgets(line, sizeof(line), stdin)) {
|
||||||
|
if (line[strlen(line)-1] == '\n') {
|
||||||
|
line[strlen(line)-1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
double timestamp = 0;
|
||||||
|
int index = 0;
|
||||||
|
if (sscanf(line, "%lf %n", ×tamp, &index) < 1) {
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *hex = line + index;
|
||||||
|
|
||||||
|
static struct modesMessage mmZero;
|
||||||
|
struct modesMessage mm = mmZero;
|
||||||
|
for (unsigned i = 0; i < sizeof(mm.MB); ++i) {
|
||||||
|
if (!isxdigit(hex[i*2]) || !isxdigit(hex[i*2 + 1])) {
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned xvalue = 0;
|
||||||
|
if (sscanf(hex + i*2, "%2x", &xvalue) < 1) {
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
mm.MB[i] = xvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
process(timestamp, line, &mm);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
fprintf(stderr, "failed to scan line: %s", line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
17
oneoff/extract-comm-b.py
Executable file
17
oneoff/extract-comm-b.py
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Run me like this:
|
||||||
|
# view1090 --no-interactive | ./extract-comm-b.py
|
||||||
|
|
||||||
|
import re, sys, time
|
||||||
|
from contextlib import closing
|
||||||
|
|
||||||
|
commb_match = re.compile(r'^DF:\d+ addr:([a-zA-Z0-9]{6}) FS:\d+ DR:\d+ UM:\d+ (?:ID|AC):\d+ MB:([a-zA-Z0-9]{14})$')
|
||||||
|
|
||||||
|
for line in sys.stdin:
|
||||||
|
match = commb_match.match(line)
|
||||||
|
if match:
|
||||||
|
addr, mb = match.groups()
|
||||||
|
|
||||||
|
with closing(open('commb/' + addr.upper() + '.txt', 'a')) as f:
|
||||||
|
print('%.3f %s' % (time.time(), mb), file=f)
|
Loading…
Reference in a new issue