#include #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; } }